БСП 1С (Библиотека стандартных подсистем) — это набор готовых подсистем фирмы «1С», на котором построены все современные типовые конфигурации: пользователи и права, управление доступом, печать, варианты отчётов, рассылки, дополнительные обработки, длительные операции и десятки других. Правильно использовать БСП в разработке — значит вызывать только её программный интерфейс и подключать свои объекты к подсистемам через переопределяемые модули, определяемые типы и подписки на события, не правя код самой библиотеки. Тогда доработка переживает обновление.

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

Почему стоит опираться на БСП, а не писать своё

Сама по себе БСП — конфигурация-библиотека: учёт в ней не ведут, она поставляется для встраивания. Аргументы за неё простые:

  • код уже написан, протестирован и соответствует стандартам разработки;
  • его поддерживает и обновляет вендор платформы, а не подрядчик, которого через год может не стать;
  • пользователи типовых конфигураций уже знают её интерфейсы — формы печати, настройки отчётов, рассылки;
  • есть документация и подробные комментарии к методам.

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

Области видимости: что можно вызывать

Модули БСП размечены областями, и от этого зависит, можно ли вызывать метод снаружи:

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

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

1С
ИдентификаторОтчета = ОбщегоНазначения.ИдентификаторОбъектаМетаданных(Метаданные.Отчеты.ВаловаяПрибыль);
БСП 1С: публичный программный интерфейс и закрытые служебные области
БСП 1С: публичный программный интерфейс и закрытые служебные области

Внутри программного интерфейса бывает ещё подраздел «Для вызова из других подсистем» — это методы для конкретных потребителей, описанные в документации. Их вызывают только оттуда, где это предусмотрено.

Где искать программный интерфейс

Программный интерфейс БСП живёт в общих модулях. Искать нужную функцию в модулях объектов, форм и менеджеров — ошибка: там в основном служебный код.

Порядок поиска, которым пользуюсь сам:

  1. Определить подсистему: в дереве метаданных «Стандартные подсистемы» → нужная подсистема → отбор по её объектам.
  2. Среди её общих модулей выбрать модуль под контекст вызова.
  3. Открыть область ПрограммныйИнтерфейс и прочитать комментарии.

Суффиксы общих модулей подсказывают контекст:

СуффиксГде вызывать
без суффиксаНа сервере
КлиентНа клиенте
КлиентСерверИ на клиенте, и на сервере
ВызовСервераС клиента, когда нужен серверный вызов
ПовтИспКэшируемые значения на время сеанса
ПереопределяемыйСюда вы пишете свой код — это точки подключения

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

Методы, которые я использую чаще всего

1С
// Значения реквизитов без получения объекта целиком
Реквизиты = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(Договор, "Организация, Контрагент, ВалютаВзаиморасчетов");
Организация = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Договор, "Организация");

// Сообщение пользователю с привязкой к полю формы
ОбщегоНазначения.СообщитьПользователю(НСтр("ru = 'Не заполнен договор'"), , "Объект.Договор");

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

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

Два вида подсистем: самостоятельные и интегрируемые

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

Интегрируемые подсистемы работают с вашими объектами, и объект нужно к ним подключить: печать, запрет редактирования реквизитов, управление доступом, дополнительные реквизиты, версионирование. Подключение — это своего рода контракт: вы сообщаете подсистеме, какие объекты участвуют, и выполняете её требования к модулям и формам.

Подключение своего объекта к подсистеме БСП через стандартные точки
Подключение своего объекта к подсистеме БСП через стандартные точки

Способ 1: переопределяемый модуль и вставки в объект

Разберу на подсистеме «Запрет редактирования реквизитов объектов». Задача: в справочнике КассыККМ после записи нельзя просто так менять организацию и склад.

Шаг 1. Регистрация объекта. В общем модуле ЗапретРедактированияРеквизитовОбъектовПереопределяемый есть процедура ПриОпределенииОбъектовСЗаблокированнымиРеквизитами. Её комментарий описывает формат — добавляем свой объект:

1С
Процедура ПриОпределенииОбъектовСЗаблокированнымиРеквизитами(Объекты) Экспорт

	Объекты.Вставить(Метаданные.Справочники.КассыККМ.ПолноеИмя(), "");

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

Шаг 2. Список блокируемых реквизитов. В модуле менеджера справочника реализуем функцию, которую ждёт подсистема:

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

// Возвращает реквизиты, редактирование которых блокируется после записи.
Функция ПолучитьБлокируемыеРеквизитыОбъекта() Экспорт

	Результат = Новый Массив;
	Результат.Добавить("Организация");
	Результат.Добавить("Склад");
	Возврат Результат;

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

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

Шаг 3. Вставки в форму. Без изменения формы подсистема не может заблокировать её элементы, поэтому по документации добавляем вызовы:

1С
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	ЗапретРедактированияРеквизитовОбъектов.ЗаблокироватьРеквизиты(ЭтотОбъект);
КонецПроцедуры

&НаСервере
Процедура ПослеЗаписиНаСервере(ТекущийОбъект, ПараметрыЗаписи)
	ЗапретРедактированияРеквизитовОбъектов.ЗаблокироватьРеквизиты(ЭтотОбъект);
КонецПроцедуры

&НаКлиенте
Процедура РазрешитьРедактированиеРеквизитов(Команда)
	ЗапретРедактированияРеквизитовОбъектовКлиент.РазрешитьРедактированиеРеквизитовОбъекта(ЭтотОбъект);
КонецПроцедуры

Плюс команда формы «Разрешить редактирование реквизитов» с этим обработчиком. Точный состав вставок для вашей версии сверяйте с документацией подсистемы — в разных релизах он немного отличается.

Способ 2: определяемые типы и подписки на события

Для подсистем, которые хранят свои данные в регистрах с измерениями по вашим объектам, вставки в каждый регистр были бы неудобны. Поэтому используются определяемые типы: регистр подсистемы ссылается на определяемый тип, а вы просто добавляете в его состав свой объект.

На примере управления доступом:

  1. В определяемый тип ВладелецЗначенийКлючейДоступаДокумент (или аналогичный для справочников) добавляем свой документ — и регистры подсистемы автоматически начинают принимать ссылки на него.
  2. В состав подписок на события подсистемы (например, проверки доступа перед записью документа) добавляем наш тип в «Источник».
  3. В модуле менеджера описываем ограничение доступа и регистрируем объект в переопределяемом модуле подсистемы.

Логика внутри остаётся заботой разработчиков библиотеки, а вы отвечаете только за состав типов.

Типичные ошибки

  • Вызов служебных методов. Работает до первого обновления БСП. Ищите аналог в ПрограммныйИнтерфейс.
  • Правка кода самой библиотеки. Любая правка вне переопределяемых модулей — это конфликт при каждом обновлении. Если без неё никак, делайте это в расширении.
  • Забытые вставки в форму. Объект зарегистрирован, но подсистема «не работает», потому что в ПриСозданииНаСервере нет вызова.
  • Не тот модуль по контексту. Вызов серверного модуля с клиента не скомпилируется; для клиента нужен модуль с суффиксом Клиент.
  • Игнорирование документации. Комментарии к переопределяемым процедурам обычно содержат полный список шагов подключения.

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

Итог

  • БСП — библиотека готовых подсистем, встроенная во все современные типовые конфигурации.
  • Вызывайте только методы из области ПрограммныйИнтерфейс общих модулей; служебные области могут измениться без предупреждения.
  • Модуль выбирайте по контексту: без суффикса, Клиент, КлиентСервер.
  • Интегрируемые подсистемы подключаются через переопределяемые модули, вставки в формы, определяемые типы и подписки на события.
  • Не правьте код библиотеки напрямую — это главная причина болезненных обновлений.