При разработке в управляемых формах 1С разработчики часто сталкиваются с задачей считывания значений реквизитов для выбранного объекта — например, получения комментария, артикула или стандартной цены для выбранной номенклатуры. Простая разыменовка ссылки прямо на клиенте запрещена платформой, а при обращении через точку на сервере возникает проблема с производительностью.
Рассмотрим, почему прямые обращения к свойствам ссылки могут замедлять работу системы, и проанализируем наиболее правильные и быстры способы получения реквизитов.
Посмотрим, что происходит при написании следующего кода на сервере:
&НаСервереБезКонтекста
Функция ПолучитьРеквизит(Ссылка)
Возврат Ссылка.Комментарий;
КонецФункции
Или при обращении через квадратные скобки: Ссылка["Комментарий"]. В обоих случаях платформа 1С производит неявное считывание всего объекта из базы данных. Если справочник или документ содержит большое количество реквизитов и тяжелые табличные части, СУБД считывает полностью весь объект в оперативную память сервера приложений. Это создает ненужную нагрузку на базу данных и существенно замедляет выполнение кода, особенно при работе в циклах или многопользовательском режиме.
Если ваша конфигурация создана на базе БСП (например, «Управление торговлей», «ERP», «Бухгалтерия предприятия» и др.), рекомендуется использовать встроенные методы общих модулей. Они вызывают оптимизированные SQL-запросы, которые считывают исключительно необходимые поля, не загружая сам объект целиком.
Для чтения отдельного реквизита применим функцию ОбщегоНазначения.ЗначениеРеквизитаОбъекта.
// Вызов на сервере
Комментарий = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(СсылкаНаНоменклатуру, "Комментарий");
Если требуется вызвать получение значения с клиента без написания собственных серверных функций в модуле формы, используем модуль вызова сервера:
// Вызов на клиенте
Комментарий = ОбщегоНазначенияВызовСервера.ЗначениеРеквизитаОбъекта(СсылкаНаНоменклатуру, "Комментарий");
Если необходимо получить сразу несколько реквизитов одного объекта, эффективнее считать их за один серверный вызов и один запрос к базе данных. Для этого используем метод ОбщегоНазначения.ЗначенияРеквизитовОбъекта, который возвращает структуру значений.
// Передаем имена реквизитов через запятую
Реквизиты = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(СсылкаНаНоменклатуру, "Артикул, Комментарий, СтавкаНДС");
Артикул = Реквизиты.Артикул;
Комментарий = Реквизиты.Комментарий;
КонецФункции
Когда требуется собрать данные по нескольким объектам одновременно (например, для всех строк табличной части), используем метод ОбщегоНазначения.ЗначенияРеквизитовОбъектов. Это полностью исключает проблему массовых одиночных запросов к БД в цикле.
Разберем вариант, когда реквизит ссылочного типа (например, поле Номенклатура) выведен на управляемую форму, и рядом нужно просто отобразить значение его подчиненного реквизита (например, Комментарий или Артикул).
Для реализации этого сценария программный код не требуется вовсе:
Объект.Номенклатура) и раскрываем его список подчиненных реквизитов с помощью значка «+».Комментарий) в левое дерево элементов формы.В данном случае платформа 1С берет на себя всю работу: при изменении основного реквизита на клиенте подчиненное поле автоматически запрашивается и обновляется без выполнения лишнего кода на сервере.
Если конфигурация разрабатывается с нуля без использования БСП, наилучшим решением будет написание легкого запроса внутри серверной функции. При этом важно передавать вызов с клиента на сервер с директивой &НаСервереБезКонтекста, чтобы не передавать по сети тяжелый контекст всей формы.
&НаСервереБезКонтекста
Функция ПолучитьКомментарийНоменклатуры(СсылкаНаНоменклатуру)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Комментарий КАК Комментарий
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Ссылка = &Ссылка";
Запрос.УстановитьПараметр("Ссылка", СсылкаНаНоменклатуру);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
Возврат Выборка.Комментарий;
КонецЕсли;
Возврат "";
КонецФункции
Этот подход гарантирует точечную выборку нужных колонок из таблицы базы данных и обеспечивает минимальное время отклика интерфейса.