Решение задач 1С:Предприятие 8 на примерах

БСП 1С: Библиотека стандартных подсистем для разработчика

БСП 2.3Опубликовано

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

Задача: не писать заново то, что уже есть в типовой библиотеке

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

Что такое БСП и что в неё входит

Библиотека стандартных подсистем — это набор подсистем, который 1С разрабатывает как основу для типовых решений («Бухгалтерия», «Зарплата и управление персоналом», «Управление торговлей» и других). Они обеспечивают то, что нужно почти любому прикладному решению:

  • базовая функциональность: общие модули ОбщегоНазначения, ОбщегоНазначенияКлиент, ОбщегоНазначенияКлиентСервер, СтроковыеФункцииКлиентСервер;
  • пользователи, группы доступа, права и ограничения на уровне записей;
  • печать, работа с файлами, контактная информация, свойства и категории;
  • версионирование объектов, журнал регистрации, обновление версии информационной базы;
  • длительные операции и фоновые задания, расширения конфигурации, дополнительные отчёты и обработки.

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

Как узнать версию БСП

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

&НаСервере
Функция ВерсияБСП()

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

    Возврат Вычислить("СтандартныеПодсистемыСервер.ВерсияБиблиотеки()");

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

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

ОбщегоНазначения: значения реквизитов объекта

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

&НаСервере
Процедура ПроверитьКонтрагента(Контрагент)

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

    // Несколько реквизитов: возвращается структура
    Реквизиты = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(Контрагент, "ИНН, КПП, Наименование");
    Сообщить(Реквизиты.Наименование + ": " + Реквизиты.ИНН + "/" + Реквизиты.КПП);

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

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

Для пустой ссылки не рассчитывайте на осмысленный результат — проверяйте ЗначениеЗаполнено(Контрагент) заранее. Модуль ОбщегоНазначения серверный, поэтому на клиенте напрямую его не вызвать: сделайте серверную процедуру формы или используйте клиент-серверные обёртки библиотеки.

Если реквизиты нужны сразу для многих объектов, используйте ОбщегоНазначения.ЗначенияРеквизитовОбъектов(): она принимает массив ссылок и возвращает соответствие «ссылка — структура реквизитов». Один запрос на весь массив работает заметно быстрее, чем вызов функции для каждой ссылки в цикле, особенно когда обрабатываются сотни документов или элементов справочника.

Сообщения пользователю

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

// В модуле формы: сообщение привязывается к полю формы
ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Заполните ИНН контрагента.", , "ИНН", "Объект");

// В модуле объекта: ключ данных — сам объект, параметр Отказ получает значение Истина
ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Заполните ИНН контрагента.", ЭтотОбъект, "ИНН", , Отказ);

Преимущество перед обычным Сообщить() — привязка к полю и единый интерфейс: тот же вызов годится для проверки заполнения на клиенте, на сервере и в обработчике записи.

Таблица значений в массив и значение в массиве

Функция ОбщегоНазначения.ТаблицаЗначенийВМассив() превращает таблицу значений в массив структур. Результат удобно отправлять на клиент или в сериализацию, потому что таблица значений на клиент не передаётся в виде самостоятельного объекта. Подробнее о таблице значений — в статье про таблицу значений.

МассивСтрок = ОбщегоНазначения.ТаблицаЗначенийВМассив(ТаблицаТоваров);

Для Каждого Строка Из МассивСтрок Цикл
    Сообщить(Строка.Номенклатура + ": " + Строка.Количество);
КонецЦикла;

// Одно значение в виде массива — например, для параметра запроса В (&Контрагенты)
Запрос.УстановитьПараметр("Контрагенты", ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(Контрагент));

Колонки таблицы становятся свойствами структур, поэтому имена колонок должны быть допустимыми идентификаторами.

Подстановка параметров в строку

В 3.x есть функция СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(): в строке отмечаются места подстановки %1…%9, а далее идут значения.

Текст = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
    "Документ %1 от %2 не проведён.", Номер, Формат(Дата, "ДЛФ=D"));

В новых версиях БСП эту функцию рекомендуют заменять встроенным СтрШаблон("Документ %1 от %2 не проведён.", Номер, Формат(Дата, "ДЛФ=D")): результат тот же, а зависимости от библиотеки нет.

Проверка подсистем и текущий пользователь

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

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

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

Функция Пользователи.ТекущийПользователь() возвращает ссылку на элемент справочника «Пользователи», соответствующий пользователю информационной базы текущего сеанса. Её применяют вместо ручного поиска по имени.

Длительные операции

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

&НаСервере
Функция ЗапуститьРасчётНаСервере()

    ПараметрыПроцедуры = Новый Структура("Склад", Склад);

    ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияВФоне(УникальныйИдентификатор);
    ПараметрыВыполнения.НаименованиеФоновогоЗадания = "Расчёт остатков";

    Возврат ДлительныеОперации.ВыполнитьВФоне("РасчетОстатков.Выполнить", ПараметрыПроцедуры, ПараметрыВыполнения);

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

&НаКлиенте
Процедура Рассчитать(Команда)

    Операция = ЗапуститьРасчётНаСервере();

    ПараметрыОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(ЭтотОбъект);
    Оповещение = Новый ОписаниеОповещения("ПослеРасчёта", ЭтотОбъект);
    ДлительныеОперацииКлиент.ОжидатьЗавершение(Операция, Оповещение, ПараметрыОжидания);

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

&НаКлиенте
Процедура ПослеРасчёта(Результат, ДополнительныеПараметры) Экспорт

    Если Результат = Неопределено Тогда
        Возврат; // операция отменена
    КонецЕсли;

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

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

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

Как внедрить БСП в свою конфигурацию

Если у вас пустая или собственная конфигурация, БСП переносят в неё по руководству по внедрению. В общих чертах порядок такой:

  1. Возьмите поставку библиотеки (конфигурация-образец или демонстрационная база).
  2. Через сравнение и объединение конфигураций перенесите подсистему базовой функциональности и нужные подсистемы (пользователи, печать, файлы и другие), включая их зависимости.
  3. Добавьте в модули приложения, сеанса и объектов вызовы точек входа БСП — их список приведён в документации.
  4. Заполните перечень обработчиков обновления и подключите начальное заполнение данных.
  5. Проверьте конфигурацию — синтаксический контроль и проверку конфигурации в конфигураторе — и убедитесь, что запускается пустая база.

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

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

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

Что где искать

ЗадачаФункцияГде вызывается
Один реквизит по ссылкеОбщегоНазначения.ЗначениеРеквизитаОбъекта()Сервер
Несколько реквизитовОбщегоНазначения.ЗначенияРеквизитовОбъекта()Сервер
Сообщение пользователюОбщегоНазначенияКлиентСервер.СообщитьПользователю()Клиент и сервер
Таблица значений в массивОбщегоНазначения.ТаблицаЗначенийВМассив()Сервер
Значение в массивОбщегоНазначенияКлиентСервер.ЗначениеВМассиве()Клиент и сервер
Подстановка в строкуСтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку()Клиент и сервер
Фоновое заданиеДлительныеОперации.ВыполнитьВФоне()Сервер; ожидание — ДлительныеОперацииКлиент

Актуальность для новых версий

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

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

Что такое БСП в 1С?

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

Как узнать версию БСП в конфигурации?

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

Как получить реквизит объекта по ссылке без загрузки всего объекта?

Вызовите ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Ссылка, "ИмяРеквизита") для одного реквизита или ЗначенияРеквизитовОбъекта(Ссылка, "Реквизит1, Реквизит2") для нескольких. Функции работают на сервере и читают данные запросом.

Можно ли использовать функции БСП, если библиотеки в конфигурации нет?

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

Как подключить контактную информацию к справочнику или документу в БСП

БСП 2.3

Пошаговое подключение подсистемы «Контактная информация» БСП к новому справочнику или документу: табличная часть, виды КИ, определяемый тип владельца и обработчики модуля формы.

Как подключить дополнительные сведения к справочнику или документу в БСП

БСП 2.3

Дополнительные сведения БСП подключаются к новому объекту без табличной части и кода формы. Разбираем три шага: предопределённый набор, тип в плане видов характеристик и включение набора.

Как подключить дополнительные реквизиты к справочнику или документу в БСП

БСП 2.3

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

Обмены в 1С: план обмена, регистрация и выгрузка изменений

Интеграция и веб-сервисы

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