БСП 1С: Библиотека стандартных подсистем для разработчика
Библиотека стандартных подсистем (БСП) встроена почти во все типовые конфигурации 1С, и разработчику постоянно приходится вызывать её функции: читать реквизиты по ссылке, выводить сообщения, запускать фоновые задания. В статье — что такое БСП, как определить её версию в конфигурации, какие общие модули и функции пригодятся чаще всего, как их вызывать, и коротко о том, как подключить БСП к собственной конфигурации.
Задача: не писать заново то, что уже есть в типовой библиотеке
В типовой конфигурации вы открываете общий модуль, а в нём — десятки готовых функций: получить реквизит по ссылке, показать сообщение, преобразовать таблицу значений, запустить расчёт в фоне. Если конфигурация построена на БСП, эти функции доступны без дополнительных усилий, а код получается единообразным и понятным остальным разработчикам. Ниже — самое нужное из библиотеки.
Что такое БСП и что в неё входит
Библиотека стандартных подсистем — это набор подсистем, который 1С разрабатывает как основу для типовых решений («Бухгалтерия», «Зарплата и управление персоналом», «Управление торговлей» и других). Они обеспечивают то, что нужно почти любому прикладному решению:
- базовая функциональность: общие модули
ОбщегоНазначения,ОбщегоНазначенияКлиент,ОбщегоНазначенияКлиентСервер,СтроковыеФункцииКлиентСервер; - пользователи, группы доступа, права и ограничения на уровне записей;
- печать, работа с файлами, контактная информация, свойства и категории;
- версионирование объектов, журнал регистрации, обновление версии информационной базы;
- длительные операции и фоновые задания, расширения конфигурации, дополнительные отчёты и обработки.
Подсистемы связаны между собой и с модулями приложения через «точки входа»: события старта работы, создание формы, запись объекта. Поэтому БСП нельзя просто скопировать по частям — её внедряют по документации. О доработке типовых решений без изменения кода — в статье про расширения конфигурации.
Как узнать версию БСП
Самый надёжный способ — открыть в конфигураторе общий модуль СтандартныеПодсистемыСервер и найти функцию ВерсияБиблиотеки(): она возвращает строку вида «3.1.х.х». То же можно сделать из кода:
&НаСервере
Функция ВерсияБСП()
Если Метаданные.ОбщиеМодули.Найти("СтандартныеПодсистемыСервер") = Неопределено Тогда
Возврат Неопределено; // в конфигурации нет БСП
КонецЕсли;
Возврат Вычислить("СтандартныеПодсистемыСервер.ВерсияБиблиотеки()");
КонецФункции
Здесь вызов выполнен через Вычислить(), чтобы код компилировался и в конфигурации без БСП — это нужно внешним обработкам, которые работают в разных базах. В самой конфигурации с библиотекой достаточно прямого вызова СтандартныеПодсистемыСервер.ВерсияБиблиотеки(). Версию информационной базы по библиотеке возвращает и ОбновлениеИнформационнойБазы.ВерсияИБ("СтандартныеПодсистемы"), но это уже версия установленных данных, а не кода.
ОбщегоНазначения: значения реквизитов объекта
Самые частые функции — чтение реквизитов по ссылке без загрузки объекта целиком. Читать реквизит через Контрагент.ИНН удобно, но библиотечные функции работают одним запросом, понимают реквизиты через точку и умеют работать с ограничениями доступа.
&НаСервере
Процедура ПроверитьКонтрагента(Контрагент)
// Один реквизит
ИНН = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Контрагент, "ИНН");
// Несколько реквизитов: возвращается структура
Реквизиты = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(Контрагент, "ИНН, КПП, Наименование");
Сообщить(Реквизиты.Наименование + ": " + Реквизиты.ИНН + "/" + Реквизиты.КПП);
// Реквизит связанного объекта через точку
Страна = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Контрагент, "СтранаРегистрации.Наименование");
КонецПроцедуры
Для пустой ссылки не рассчитывайте на осмысленный результат — проверяйте ЗначениеЗаполнено(Контрагент) заранее. Модуль ОбщегоНазначения серверный, поэтому на клиенте напрямую его не вызвать: сделайте серверную процедуру формы или используйте клиент-серверные обёртки библиотеки.
Если реквизиты нужны сразу для многих объектов, используйте ОбщегоНазначения.ЗначенияРеквизитовОбъектов(): она принимает массив ссылок и возвращает соответствие «ссылка — структура реквизитов». Один запрос на весь массив работает заметно быстрее, чем вызов функции для каждой ссылки в цикле, особенно когда обрабатываются сотни документов или элементов справочника.
Сообщения пользователю
Функция ОбщегоНазначенияКлиентСервер.СообщитьПользователю() работает и на клиенте, и на сервере. Она принимает текст сообщения, ключ данных, поле, путь к данным и флаг отказа. Если указать поле и путь к данным, сообщение подсветит нужное поле формы.
// В модуле формы: сообщение привязывается к полю формы
ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Заполните ИНН контрагента.", , "ИНН", "Объект");
// В модуле объекта: ключ данных — сам объект, параметр Отказ получает значение Истина
ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Заполните ИНН контрагента.", ЭтотОбъект, "ИНН", , Отказ);
Преимущество перед обычным Сообщить() — привязка к полю и единый интерфейс: тот же вызов годится для проверки заполнения на клиенте, на сервере и в обработчике записи.
Таблица значений в массив и значение в массиве
Функция ОбщегоНазначения.ТаблицаЗначенийВМассив() превращает таблицу значений в массив структур. Результат удобно отправлять на клиент или в сериализацию, потому что таблица значений на клиент не передаётся в виде самостоятельного объекта. Подробнее о таблице значений — в статье про таблицу значений.
МассивСтрок = ОбщегоНазначения.ТаблицаЗначенийВМассив(ТаблицаТоваров);
Для Каждого Строка Из МассивСтрок Цикл
Сообщить(Строка.Номенклатура + ": " + Строка.Количество);
КонецЦикла;
// Одно значение в виде массива — например, для параметра запроса В (&Контрагенты)
Запрос.УстановитьПараметр("Контрагенты", ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(Контрагент));
Колонки таблицы становятся свойствами структур, поэтому имена колонок должны быть допустимыми идентификаторами.
Подстановка параметров в строку
В 3.x есть функция СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(): в строке отмечаются места подстановки %1…%9, а далее идут значения.
Текст = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
"Документ %1 от %2 не проведён.", Номер, Формат(Дата, "ДЛФ=D"));
В новых версиях БСП эту функцию рекомендуют заменять встроенным СтрШаблон("Документ %1 от %2 не проведён.", Номер, Формат(Дата, "ДЛФ=D")): результат тот же, а зависимости от библиотеки нет.
Проверка подсистем и текущий пользователь
Код, который должен работать и в конфигурации без определённых подсистем, не обращается к их модулям напрямую. Сначала проверяют, есть ли подсистема, затем получают общий модуль по имени. Так устроены необязательные интеграции в самой библиотеке.
Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.Печать") Тогда
МодульУправлениеПечатью = ОбщегоНазначения.ОбщийМодуль("УправлениеПечатью");
// дальше вызываются методы через переменную модуля
КонецЕсли;
ТекущийПользователь = Пользователи.ТекущийПользователь();
Функция Пользователи.ТекущийПользователь() возвращает ссылку на элемент справочника «Пользователи», соответствующий пользователю информационной базы текущего сеанса. Её применяют вместо ручного поиска по имени.
Длительные операции
Подсистема «Длительные операции» запускает процедуру в фоновом задании и показывает пользователю индикатор ожидания. Серверная часть запускает процедуру общего модуля, клиентская дожидается результата.
&НаСервере
Функция ЗапуститьРасчётНаСервере()
ПараметрыПроцедуры = Новый Структура("Склад", Склад);
ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияВФоне(УникальныйИдентификатор);
ПараметрыВыполнения.НаименованиеФоновогоЗадания = "Расчёт остатков";
Возврат ДлительныеОперации.ВыполнитьВФоне("РасчетОстатков.Выполнить", ПараметрыПроцедуры, ПараметрыВыполнения);
КонецФункции
&НаКлиенте
Процедура Рассчитать(Команда)
Операция = ЗапуститьРасчётНаСервере();
ПараметрыОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(ЭтотОбъект);
Оповещение = Новый ОписаниеОповещения("ПослеРасчёта", ЭтотОбъект);
ДлительныеОперацииКлиент.ОжидатьЗавершение(Операция, Оповещение, ПараметрыОжидания);
КонецПроцедуры
&НаКлиенте
Процедура ПослеРасчёта(Результат, ДополнительныеПараметры) Экспорт
Если Результат = Неопределено Тогда
Возврат; // операция отменена
КонецЕсли;
Если Результат.Статус = "Выполнено" Тогда
Данные = ПолучитьИзВременногоХранилища(Результат.АдресРезультата);
ИначеЕсли Результат.Статус = "Ошибка" Тогда
ВызватьИсключение Результат.КраткоеПредставлениеОшибки;
КонецЕсли;
КонецПроцедуры
Процедура общего модуля, которую запускает функция, принимает параметры и адрес временного хранилища, куда кладёт результат. Названия параметров и точное поведение зависят от версии БСП, поэтому ориентируйтесь на комментарии к функциям ВыполнитьВФоне и ОжидатьЗавершение в вашей конфигурации.
Как внедрить БСП в свою конфигурацию
Если у вас пустая или собственная конфигурация, БСП переносят в неё по руководству по внедрению. В общих чертах порядок такой:
- Возьмите поставку библиотеки (конфигурация-образец или демонстрационная база).
- Через сравнение и объединение конфигураций перенесите подсистему базовой функциональности и нужные подсистемы (пользователи, печать, файлы и другие), включая их зависимости.
- Добавьте в модули приложения, сеанса и объектов вызовы точек входа БСП — их список приведён в документации.
- Заполните перечень обработчиков обновления и подключите начальное заполнение данных.
- Проверьте конфигурацию — синтаксический контроль и проверку конфигурации в конфигураторе — и убедитесь, что запускается пустая база.
Внедряйте только те подсистемы, которые нужны: у каждой есть зависимости, а лишний код усложняет обновления.
Типичные ошибки
- Вызов серверного модуля
ОбщегоНазначенияиз клиентского кода — ошибка компиляции или вызова; нужен серверный метод. - Использование функций БСП в конфигурации без библиотеки — модуля нет, код не компилируется.
- Расчёт на старых названиях функций: в разных версиях часть методов переименована или вынесена в другие модули.
- Чтение реквизита у пустой ссылки без проверки.
- Копирование части БСП вручную без зависимостей: подсистемы связаны между собой, и неполный перенос ломает запуск.
Что где искать
| Задача | Функция | Где вызывается |
|---|---|---|
| Один реквизит по ссылке | ОбщегоНазначения.ЗначениеРеквизитаОбъекта() | Сервер |
| Несколько реквизитов | ОбщегоНазначения.ЗначенияРеквизитовОбъекта() | Сервер |
| Сообщение пользователю | ОбщегоНазначенияКлиентСервер.СообщитьПользователю() | Клиент и сервер |
| Таблица значений в массив | ОбщегоНазначения.ТаблицаЗначенийВМассив() | Сервер |
| Значение в массив | ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве() | Клиент и сервер |
| Подстановка в строку | СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку() | Клиент и сервер |
| Фоновое задание | ДлительныеОперации.ВыполнитьВФоне() | Сервер; ожидание — ДлительныеОперацииКлиент |
Актуальность для новых версий
Примеры рассчитаны на БСП версий 3.0 и 3.1 и платформу 8.3. В новых релизах библиотеки часть функций помечена устаревшими, а вместо них рекомендованы стандартные средства платформы — например, СтрШаблон() вместо СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(). Состав параметров и расположение методов (например, переход функций в модули с суффиксом «Клиент» и «ВызовСервера») меняются от версии к версии, поэтому перед использованием откройте общий модуль в конфигураторе и прочитайте комментарий к функции — в нём указаны актуальные параметры и применимость.
Частые вопросы
Что такое БСП в 1С?
БСП — Библиотека стандартных подсистем, набор готовых подсистем и общих модулей фирмы 1С: пользователи, права доступа, печать, работа с файлами, длительные операции, обновление версии и другие. Она встроена в типовые конфигурации и может быть внедрена в собственную.
Как узнать версию БСП в конфигурации?
В конфигураторе откройте общий модуль СтандартныеПодсистемыСервер и найдите функцию ВерсияБиблиотеки(). Из кода версию получают вызовом СтандартныеПодсистемыСервер.ВерсияБиблиотеки() на сервере, если модуль есть в конфигурации.
Как получить реквизит объекта по ссылке без загрузки всего объекта?
Вызовите ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Ссылка, "ИмяРеквизита") для одного реквизита или ЗначенияРеквизитовОбъекта(Ссылка, "Реквизит1, Реквизит2") для нескольких. Функции работают на сервере и читают данные запросом.
Можно ли использовать функции БСП, если библиотеки в конфигурации нет?
Нет, обращение к несуществующему общему модулю вызовет ошибку компиляции. Либо внедрите нужные подсистемы БСП в конфигурацию, либо напишите собственные аналоги и используйте стандартные функции платформы.