Как вызвать процедуру формирования дерева из модуля формы на сервере и оптимизировать получение иерархических данных в 1С

Программист 1С v8.3 (Управляемые формы) Управленческий учет Промышленность, строительство и АПК
← На главную

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

Причина проблемы и ограничения платформы 1С

В управляемом приложении платформы 1С:Предприятие 8.3 модуль формы существует исключительно в контексте работы текущего сеанса пользователя на клиенте. Экспортные процедуры модуля формы предназначены для обслуживания клиентской логики конкретного экземпляра формы.

Попытка обратиться к процедурам модуля формы из контекста печатной формы, фонового задания или модуля объекта без открытого экземпляра формы на клиенте не поддерживается платформой. Кроме того, передача объекта ДеревоЗначений между клиентом и сервером напрямую невозможна — на тонком клиенте используется элемент ДанныеФормыДерево.

Способ 1. Рефакторинг и вынос логики в общий модуль или модуль менеджера

Наиболее правильным и соответствующим стандартам разработки 1С решением является вынос бизнес-логики формирования дерева из модуля формы в серверный контекст.

Рассмотрим пошагово, как выполнить данный рефакторинг:

  1. Перенос процедуры: Переместим функцию формирования дерева значений из модуля формы в модуль менеджера соответствующего справочника (или в серверный общий модуль с установленным флагом «Сервер»).
  2. Отказ от контекста формы: Исключим из вынесенной процедуры любые обращения к элементам формы (Элементы, ЭтаФорма, клиентские переменные). Входными параметрами процедуры должны выступать ссылки на объекты (например, СсылкаНаНоменклатуру или ВариантИсполнения).
  3. Вызов из формы и печатной формы: В модуле формы вызовем эту серверную функцию и загрузим полученное ДеревоЗначений в реквизит формы с помощью метода ЗначениеВРеквизитФормы(). Из модуля печатной формы обратимся напрямую к экспортной функции модуля менеджера.

Посмотрим на пример вызова экспортной функции модуля менеджера из печатной формы:


// В модуле менеджера справочника ВариантыИсполнения
Функция ПолучитьДеревоСостава(СсылкаНаВариант) Экспорт
    Дерево = Новый ДеревоЗначений;
    // Логика заполнения дерева значений на сервере
    Возвратить Дерево;
КонецФункции

// В модуле печатной формы или внешней обработки
Процедура СформироватьПечатнуюФорму(МассивОбъектов)
    Для Каждого Заказ Из МассивОбъектов Цикл
        ДеревоСостава = Справочники.ВариантыИсполнения.ПолучитьДеревоСостава(Заказ.ВариантИсполнения);
        // Вывод данных в табличный документ
    КонецЦикла;
КонецПроцедуры

Способ 2. Оптимизация получения иерархических данных через запросы

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

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

  1. Фильтрация по отсутствию родителя: Для получения верхнего уровня иерархии выберем элементы справочника или табличной части, у которых реквизит Родитель равен пустой ссылке (Значение(Справочник.ИмяСправочника.ПустаяСсылка)).
  2. Использование иерархических итогов: Построим запрос с использованием конструкции ИТОГИ ПО ... ИЕРАРХИЯ. Это позволит СУБД самостоятельно сгруппировать ветви, что работает существенно быстрее выполнения рекурсивных циклов на встроенном языке 1С.

Дополнительно: Причины аномального роста базы данных при доработках

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

  1. Неоптимальное хранение бинарных данных: Использование реквизитов с типом ХранилищеЗначения для сохранения чертежей, файлов или сериализованных деревьев без использования объекта СжатиеДанных приводит к быстрому разрастанию таблиц СУБД.
  2. Включенное версионирование объектов: Если для доработанного справочника в подсистеме версионирования объектов включена запись версий при каждом сохранении, то при активной работе пользователей регистр сведений ВерсииОбъектов увеличивает объем базы на гигабайты за короткий период.
← На главную