При разработке на управляемых формах в 1С часто возникает задача: получить на клиенте значение одного или нескольких реквизитов объекта, имея только ссылку на него. Прямое обращение к реквизиту через точку, например МояСсылка.Наименование, кажется простым, но таит в себе подводные камни, связанные с производительностью. Такой вызов приводит к неявному обращению к серверу и загрузке всего объекта, что может быть очень ресурсозатратно. Разберемся, как делать это правильно и эффективно с помощью механизмов Библиотеки стандартных подсистем (БСП), а ускорить разработку поможет Консоль кода с ИИ-помощником (поможет интеллектуальная консоль кода с ИИ-помощником для 1С).
Проанализируем основную причину, по которой для получения данных требуется специальный подход. Платформа "1С:Предприятие 8" в режиме управляемого приложения работает по клиент-серверной архитектуре (разобраться в зависимостях которой поможет Analyzer 1C). Это означает, что:
Таким образом, любая операция по чтению или записи данных должна быть выполнена на сервере. Чтобы получить значение реквизита, клиент должен отправить запрос на сервер. Использование специализированных функций позволяет сделать этот запрос максимально "легким" и быстрым.
Для решения этой задачи в БСП существуют специальные серверные функции в общем модуле ОбщегоНазначения. Они выполняют легковесный запрос к базе данных, получая только то, что нужно, и не загружая весь объект в память сервера.
ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Ссылка, ИмяРеквизита) — идеально подходит для получения значения одного реквизита.ОбщегоНазначения.ЗначенияРеквизитовОбъекта(Ссылка, "ИмяРеквизита1,ИмяРеквизита2") — предпочтительный вариант, если нужно получить несколько реквизитов одного объекта. Функция возвращает структуру, где ключами выступают имена реквизитов. Это позволяет сократить количество серверных вызовов до одного (схожие приемы используются при постобработке печатных форм на основе БСП).Однако, как было верно замечено, модуль ОбщегоНазначения — серверный, и его нельзя вызвать с клиента напрямую. Для этого существуют специальные модули-шлюзы, а для удобной навигации по ним пригодится MCP сервер для работы с экспортными функциями — см. MCP-сервер контекста метаданных для ИИ-разработки в 1С.
В типовых конфигурациях для контролируемого доступа к серверным функциям с клиента существуют общие модули с установленным флагом "Вызов сервера". Их названия, как правило, заканчиваются на ...ВызовСервера. Они выступают в роли безопасной "прослойки".
В разных конфигурациях эти модули могут называться по-разному. Рассмотрим примеры, найденные в ходе обсуждения:
ОбщегоНазначенияУТВызовСервераОбщегоНазначенияДокументооборотВызовСервераЭлектронныйДокументооборотСКонтролирующимиОрганамиВызовСервера или ИнтеграцияС1СДокументооборотВызовСервераПосмотрим на пример. Допустим, на форме есть реквизит Организация (тип СправочникСсылка.Организации), и нам нужно получить его ИНН на клиенте.
// &НаКлиенте
Процедура ПолучитьИННОрганизации()
СсылкаНаОрганизацию = Объект.Организация;
Если ЗначениеЗаполнено(СсылкаНаОрганизацию) Тогда
// Вызываем серверную функцию через специальный модуль
ИНН_Организации = ЭлектронныйДокументооборотСКонтролирующимиОрганамиВызовСервера.ЗначениеРеквизитаОбъекта(СсылкаНаОрганизацию, "ИНН");
Сообщить("ИНН полученной организации: " + ИНН_Организации);
КонецЕсли;
КонецПроцедуры
Этот способ является самым простым и быстрым при работе с неизмененной типовой конфигурацией. Вам просто нужно найти подходящий модуль с флагом "Вызов сервера", который предоставляет доступ к нужной вам функции.
Что делать, если конфигурация сильно доработана или вы хотите сделать свой код независимым от возможных изменений в типовых модулях при обновлениях? Лучшей практикой в этом случае является создание собственного общего модуля-шлюза.
Это дает полный контроль над серверными вызовами и гарантирует, что ваш функционал не "сломается" после очередного обновления.
Разберем по шагам, как это сделать:
Создайте новый общий модуль. Назовем его, например, МойМодульВызовСервера. Важно придерживаться соглашения об именовании, чтобы было понятно его назначение.
Установите правильные флаги. В свойствах модуля установите галочки:
СерверВызов сервераНапишите функцию-обертку. Внутри этого модуля создайте экспортную функцию, которая будет принимать параметры от клиента и передавать их в стандартную функцию БСП на сервере.
// Общий модуль МойМодульВызовСервера
&НаСервереБезКонтекста
Функция ЗначениеРеквизитаОбъекта(Ссылка, ИмяРеквизита, ВыбратьРазрешенные = Ложь) Экспорт
// Внутри этой серверной функции мы вызываем стандартную функцию БСП
Результат = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Ссылка, ИмяРеквизита, ВыбратьРазрешенные);
Возврат Результат;
КонецФункции
Вызовите новую функцию с клиента. Теперь в клиентском коде вы можете обращаться к своей собственной, полностью контролируемой функции.
// &НаКлиенте
Процедура МояКомандаНаКлиенте()
// Вызываем нашу собственную функцию-обертку
НужныйРеквизит = МойМодульВызовСервера.ЗначениеРеквизитаОбъекта(ЭтаФорма.Организация, "ИНН");
Сообщить("Значение реквизита: " + НужныйРеквизит);
КонецПроцедуры
Этот подход не только более надежен, но и позволяет в будущем расширять функциональность, добавляя в свой модуль другие необходимые серверные вызовы, не затрагивая типовые объекты конфигурации.