Область «ПрограммныйИнтерфейс» в модулях 1С 8.3: правила, контексты, доступ и отладка

· 10 мин

Содержание

Программный интерфейс в 1С — это набор экспортных процедур и функций модуля, которые разработчик разрешил вызывать из другого кода. В типовых конфигурациях их собирают в область #Область ПрограммныйИнтерфейс. Всё, что лежит в этой области, поставщик обещает сохранять от релиза к релизу: имя, параметры и смысл возвращаемого значения.

На практике это ответ на вопрос «что из чужого модуля можно звать в своей доработке, чтобы она не сломалась после обновления». Возможности программного интерфейса ограничены тремя вещами: где выполняется код (клиент или сервер), какие права у пользователя и в каком режиме подключён код (расширение, внешняя обработка, безопасный режим). Тема общая для платформы 8.3 и всех конфигураций на Библиотеке стандартных подсистем (БСП): Бухгалтерии 3.0, ЗУП 3.1, УТ 11, ERP.

Что такое программный интерфейс модуля и чем он отличается от служебного

Платформа сама по себе знает только одно правило: процедура с ключевым словом Экспорт видна снаружи модуля, без него — нет. Области #Область … #КонецОбласти компилятор не учитывает. Это разметка для людей и инструментов проверки кода.

Смысл областям придают стандарты разработки 1С. Для общего модуля они задают такой порядок:

ОбластьКто может вызыватьЧто гарантирует поставщик
ПрограммныйИнтерфейслюбой код, в том числе ваши доработкиимя и параметры сохраняются, изменения объявляются заранее
СлужебныйПрограммныйИнтерфейстолько подсистемы самой конфигурации или библиотекиничего: метод могут переименовать в любом релизе
СлужебныеПроцедурыИФункциитолько код этого же модуляничего, методы не экспортные

Отсюда главный вывод. Экспортный метод из области «СлужебныйПрограммныйИнтерфейс» вызывать можно технически, но нельзя по смыслу: после очередного обновления доработка упадёт, и это будет не ошибка поставщика.

Как выглядит описание метода

Каждый метод программного интерфейса снабжают комментарием над заголовком. По нему Конфигуратор и EDT показывают подсказку при наборе кода.

#Область ПрограммныйИнтерфейс

// Возвращает долг покупателя по неоплаченным заказам.
//
// Параметры:
//  Контрагент - СправочникСсылка.Контрагенты - покупатель.
//  НаДату     - Дата - дата расчёта, по умолчанию текущая.
//
// Возвращаемое значение:
//  Число - сумма долга; 0, если долга нет.
//
Функция ДолгПокупателя(Контрагент, НаДату = Неопределено) Экспорт

	Если НаДату = Неопределено Тогда
		НаДату = ТекущаяДатаСеанса();
	КонецЕсли;

	Возврат РассчитатьДолг(Контрагент, НаДату);

КонецФункции

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

Функция РассчитатьДолг(Контрагент, НаДату)
	// Запрос к регистру расчётов вашей конфигурации.
	Возврат 0;
КонецФункции

#КонецОбласти

Внешний код видит только ДолгПокупателя. Алгоритм РассчитатьДолг можно переписывать сколько угодно — вызывающие модули об этом не узнают.

💡 Новый параметр в метод программного интерфейса добавляют только в конец и только со значением по умолчанию. Так старые вызовы продолжают работать.

Области модулей: где применяется программный интерфейс

Набор областей зависит от вида модуля. Ниже — что встречается в типовых конфигурациях чаще всего.

  • 📦 Общий модуль — ПрограммныйИнтерфейс, СлужебныйПрограммныйИнтерфейс, СлужебныеПроцедурыИФункции. Основное место, где живёт публичный API библиотеки.
  • 🗂 Модуль менеджера справочника или документа — те же области плюс ОбработчикиСобытий. Здесь обычно лежат функции вида «получить настройки печати», «заполнить по умолчанию».
  • 🧾 Модуль объекта — дополнительно ОписаниеПеременных, ОбработчикиСобытий и Инициализация. Экспортные методы объекта вызывают через сам объект: ДокументОбъект.ЗаполнитьТовары().
  • 🖥 Модуль формы — области обработчиков событий формы, элементов и команд. Области ПрограммныйИнтерфейс в нём обычно нет: форма не библиотека, её методы вызывают только из неё самой.

Контекст исполнения: свойства общего модуля

У общего модуля в палитре свойств есть флажки, которые определяют, откуда его можно вызвать. Это вторая половина «области применения».

СвойствоЧто даёт
Клиент (управляемое приложение)модуль компилируется на клиенте
Сервермодуль компилируется на сервере
Вызов сервераэкспортные методы серверного модуля можно вызывать с клиента
Внешнее соединениемодуль доступен через COM-соединение
Привилегированныйкод выполняется без проверки прав пользователя
Глобальныйметоды вызываются без имени модуля
Повторное использование возвращаемых значенийрезультат функций кэшируется на время вызова или сеанса

По суффиксу имени в БСП сразу видно контекст: ОбщегоНазначения — сервер, ОбщегоНазначенияКлиент — клиент, ОбщегоНазначенияКлиентСервер — оба, …ВызовСервера — серверный с флажком «Вызов сервера», …Повтисп — с кэшированием.

Внешние программные интерфейсы

Слово «программный интерфейс» относят и к способам достучаться до базы снаружи. Это другой уровень, но вопросы задают одни и те же люди:

  • 🌐 HTTP-сервисы — свой REST-API, который вы описываете в конфигурации и публикуете на веб-сервере.
  • 🔗 Стандартный интерфейс OData — доступ к справочникам, документам и регистрам без программирования, после публикации и выбора состава объектов.
  • 🧩 Веб-сервисы (SOAP) — для обмена с системами, которым нужен WSDL.
  • 🖇 COM-соединение V83.COMConnector — для скриптов и программ под Windows. Из такого соединения видны только общие модули с флажком «Внешнее соединение».

Почему метод программного интерфейса недоступен: контекст и права

Метод виден в Синтакс-помощнике, а вызвать его не получается. Причин немного, и каждая проверяется за пару минут.

Неверный контекст

Самая частая ситуация — серверная функция вызывается из клиентской процедуры формы. Если у общего модуля нет флажка Вызов сервера, клиент его не видит, и при проверке модуля (F7 в Конфигураторе) вы получите ошибку о неизвестном методе.

Обратная история — клиентский метод в серверном коде, например ОбщегоНазначенияКлиент внутри процедуры &НаСервере. Решение одно: найти серверного или клиент-серверного «близнеца» метода. В БСП он почти всегда есть.

Не хватает прав

Права проверяются на уровне данных, а не методов. Функция программного интерфейса выполнится, но внутри неё запрос к таблице, на которую у роли нет права «Чтение», завершится ошибкой Нарушение прав доступа!.

Проверить права из кода можно заранее:

Если Не ПравоДоступа("Изменение", Метаданные.Справочники.Номенклатура) Тогда
	ОбщегоНазначения.СообщитьПользователю("Недостаточно прав для изменения номенклатуры.");
	Возврат;
КонецЕсли;

Привилегированный модуль обходит проверку прав. Не переносите код в привилегированный модуль только ради того, чтобы «заработало»: так вы откроете данные всем пользователям, у которых есть доступ к вызывающей команде.

Безопасный режим

Внешние отчёты и обработки, а также расширения могут подключаться в безопасном режиме. В нём запрещены работа с файлами на сервере, COM-объекты, внешние компоненты и привилегированный режим. Метод из программного интерфейса, который внутри пишет файл, в таком коде упадёт, хотя у пользователя полные права.

Диагностика: выберите симптом

Примеры использования программного интерфейса БСП в доработках

Типовые конфигурации предлагают тысячи готовых методов. Перед тем как писать свой запрос или свою форму сообщения, стоит поискать готовое в модулях БСП.

Прочитать реквизиты без загрузки объекта

ИНН = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Контрагент, "ИНН");

Реквизиты = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(Контрагент, "ИНН, КПП, Наименование");
Сообщение = СтрШаблон("%1: ИНН %2, КПП %3", Реквизиты.Наименование, Реквизиты.ИНН, Реквизиты.КПП);

Функции делают один запрос к нужным полям. Это быстрее, чем Контрагент.ПолучитьОбъект() или обращение через точку к нескольким реквизитам подряд.

Сообщить пользователю с привязкой к полю

ОбщегоНазначения.СообщитьПользователю(
	"Не заполнен ИНН контрагента.", Контрагент, "ИНН");

Сообщение появится в окне сообщений, а щелчок по нему откроет карточку контрагента на поле ИНН.

Вызвать подсистему, которой может не быть

Если доработка должна работать в разных конфигурациях, жёсткая ссылка на модуль сломает компиляцию там, где подсистемы нет. Для этого в БСП есть пара методов:

Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.Печать") Тогда
	МодульУправлениеПечатью = ОбщегоНазначения.ОбщийМодуль("УправлениеПечатью");
	// дальше вызываете методы через переменную МодульУправлениеПечатью
КонецЕсли;

Проверить роль и текущего пользователя

Если Пользователи.ЭтоПолноправныйПользователь() Тогда
	// действия только для администратора
КонецЕсли;

Автор = Пользователи.ТекущийПользователь();

💡 Чтобы найти подходящий метод, откройте общий модуль БСП, сверните области и разверните только ПрограммныйИнтерфейс. Комментарии над методами — по сути встроенная документация.

Как расширить стандартный программный интерфейс: расширения и внешние обработки

Типовую конфигурацию без снятия с поддержки дорабатывают тремя способами. Выбор зависит от задачи.

СпособКогда подходитОграничения
Расширение конфигурацииизменить поведение типовых объектов, добавить свои общие модули, роли, реквизитыможет слететь после обновления, если поменялся перехваченный метод
Переопределяемые модули БСПдонастроить поведение подсистемы, например добавить команду печатиизменение самих модулей …Переопределяемый — это правка конфигурации
Дополнительные отчёты и обработкипечатные формы, заполнение табличных частей, разовые обработки данныхподключаются в безопасном режиме, если не разрешено иное

Расширение: перехват методов

Расширения появились в платформе 8.3.6. Метод типового модуля перехватывают аннотациями:

  • &Перед("ИмяМетода") — ваш код выполняется до типового;
  • &После("ИмяМетода") — после типового;
  • &Вместо("ИмяМетода") — вместо типового; вызвать оригинал можно через ПродолжитьВызов();
  • &ИзменениеИКонтроль("ИмяМетода") — копия типового метода с вашими вставками; при изменении оригинала поставщиком платформа сообщит о несовпадении.
&После("ПередЗаписью")
Процедура Расш1_ПередЗаписьюПосле(Отказ, РежимЗаписи, РежимПроведения)

	Если Не ЗначениеЗаполнено(Комментарий) Тогда
		Комментарий = "Создан " + Формат(ТекущаяДатаСеанса(), "ДЛФ=D");
	КонецЕсли;

КонецПроцедуры

Перехватывайте методы из области ПрограммныйИнтерфейс и обработчики событий. Перехват служебных методов работает, но после обновления такое расширение придётся чинить первым.

Подключают расширение в Конфигураторе: Конфигурация → Расширения конфигурации. В пользовательском режиме список доступен через Все функции → Стандартные → Управление расширениями конфигурации. Загрузка файла .cfe и применение изменений — отдельные шаги: после загрузки перезапустите сеанс.

Внешняя обработка с регистрацией в БСП

Чтобы обработку можно было добавить в справочник дополнительных обработок, в её модуле объекта должна быть экспортная функция СведенияОВнешнейОбработке(). Она сообщает БСП вид обработки, версию, список команд и объекты, к которым она подключается. В Бухгалтерии 3.0 список ведётся в разделе Администрирование → Печатные формы, отчеты и обработки.

Внутри внешней обработки вызывайте только методы из области ПрограммныйИнтерфейс. Обработку часто переносят между базами с разными релизами, и служебные методы там могут отличаться.

Отладка вызовов программного интерфейса

Когда метод возвращает не то, что ожидалось, быстрее всего пройти вызов отладчиком.

  1. Откройте базу в Конфигураторе и поставьте точку останова на строке вызова — F9.
  2. Запустите Отладка → Начать отладку (F5). Откроется сеанс 1С:Предприятия под отладчиком.
  3. Повторите действие пользователя. На точке останова войдите внутрь метода — F11, перешагните строку — F10.
  4. Значения переменных и параметров смотрите через вычисление выражения — Shift+F9.
  5. Если ошибка возникает «где-то внутри», включите Отладка → Остановка по ошибке: отладчик остановится в той строке, где возникло исключение.

Для клиент-серверной базы отладку серверного кода нужно разрешить на сервере: служба агента сервера 1С запускается с ключом -debug. ⚠️ Изменение параметров службы требует её перезапуска, а это оборвёт сеансы всех пользователей. Делайте это вне рабочего времени или на копии базы.

Ошибка воспроизводится только у одного пользователя

Почти всегда это права. Запустите отладочный сеанс под учётной записью этого пользователя: в Конфигураторе пользователь для запуска задаётся в параметрах запуска 1С:Предприятия (меню Сервис → Параметры). Если пароля вы не знаете, повторите сценарий на копии базы, где пароль можно сбросить.

Найти, кто вызывает метод

Перед изменением метода программного интерфейса посмотрите, где он используется. В Конфигураторе это глобальный поиск по имени метода (Ctrl+Shift+F) по всем модулям конфигурации и подключённых расширений.

Частые ошибки при работе с программным интерфейсом

  • ❌ Экспорт «на всякий случай». Каждый экспортный метод становится обязательством. Через год его вызывают из пяти мест, и поменять сигнатуру уже нельзя.
  • ❌ Серверный вызов в цикле. Вызов …ВызовСервера внутри клиентского цикла по 500 строкам — это 500 обращений к серверу. Передайте массив одним вызовом и обработайте его на сервере.
  • ❌ Передача объекта с клиента. На сервер передают ссылки, структуры, массивы и данные формы. Объект справочника или документа через границу клиент–сервер не передаётся.
  • ❌ Кэш с изменяемым результатом. Функция модуля с повторным использованием возвращает одно и то же значение всем вызывающим. Если вернуть обычную структуру, а снаружи её изменить, испортится кэш. Возвращайте ФиксированнаяСтруктура или ФиксированныйМассив.
  • ❌ Правка типового модуля вместо расширения. Конфигурация снимается с поддержки, и каждое обновление превращается в ручное сравнение.

Частые вопросы

Обязательно ли размечать свои модули областями?
Нет, платформа работает и без них. Но области помогают проверке кода (АПК, EDT) и коллегам сразу понять, какие методы можно вызывать.
Можно ли вызвать экспортный метод модуля формы из другого модуля?
Да, если у вас есть сама форма: Форма.ИмяМетода(). Обычно так делают только из обработчиков оповещения или из подчинённой формы.
Чем «Вызов сервера» отличается от директивы &НаСервере в форме?
Директива &НаСервере переносит процедуру формы на сервер вместе с данными формы. Вызов общего модуля с флажком «Вызов сервера» передаёт только параметры и обычно быстрее.
Где посмотреть программный интерфейс самой платформы?
В Синтакс-помощнике Конфигуратора: Справка → Синтакс-помощник. Там описаны глобальный контекст, встроенные объекты и доступность каждого метода на клиенте и сервере.
Попадает ли код расширения в программный интерфейс типовой конфигурации?
Нет. Свои общие модули расширения доступны коду расширения и формам, которые оно изменяет. Типовой код о них не знает, пока вы сами не вызовете их через перехват.