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

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

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

Почему форма документа открывается с задержкой

Проанализируем механику работы управляемого приложения. Задержка в 2–3 секунды при 300 реквизитах шапки обусловлена не алгоритмами в модуле формы, а внутренними процессами платформы:

  1. Сериализация контекста формы: при вызове формы сервер формирует структуру данных (ДанныеФормыСтруктура), сериализует значения всех 300 реквизитов шапки и их мета-свойства, после чего отправляет пакет клиенту. Чем массивнее структура, тем выше накладные расходы на сериализацию и сетевой трафик.
  2. Отрисовка и Data Binding на клиенте: тонкий клиент вынужден создать в памяти более 300 визуальных контролов и связать каждый элемент с соответствующим путем к данным. В отличие от таблиц, для полей ввода не предусмотрена виртуализация: платформа строит дерево элементов целиком, даже если поля разнесены по разным вкладкам.
  3. Ограничения СУБД: хранение сотен полей в одной таблице базы данных приводит к превышению лимитов размера строки данных (в частности, 8060 байт в MS SQL Server), что порождает вынос данных за пределы страницы (row-overflow data), фрагментацию и замедление дискового чтения даже при простом чтении объекта.
  4. Тяжелый контекстный трафик в процессе работы: любой обработчик события с директивой &НаСервере привязывает к вызову весь контекст формы, передавая 300 реквизитов туда и обратно при каждом изменении значения.

Идея выгрузки данных во внешнюю обработку и возврата итогов не решает проблему, а лишь усложняет архитектуру, создавая риски конкурентного доступа и блокировок. Рассмотрим правильные варианты оптимизации.

Решение 1. Переход на модель EAV через табличную часть

Вместо расширения шапки документа сотнями статических полей используем табличную часть. В полиграфии и производстве параметры расчета (тип бумаги, расход краски, приладка, лакирование) отлично укладываются в модель пар «Параметр — Значение».

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

  1. Параметр (тип: ПланВидовХарактеристикСсылка... или СправочникСсылка...);
  2. Значение (составной тип данных, определяемый характеристиками);
  3. Формула или Коэффициент (числовой реквизит для ручной корректировки технологами).

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

Решение 2. Разделение данных шапки и истории расчета (ХранилищеЗначения)

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

Оставим в метаданных шапки только результирующие показатели, а детальный протокол расчета свернем в служебный реквизит типа ХранилищеЗначения:


&НаСервере
Процедура СохранитьДетализациюРасчета(ДокументОбъект, СтруктураПараметров)
    ДокументОбъект.ДетализацияРасчета = Новый ХранилищеЗначения(СтруктураПараметров, Новый СжатиеДанных(9));
КонецПроцедуры

&НаСервере
Функция ПрочитатьДетализациюРасчета(СсылкаНаДокумент)
    Возврат СсылкаНаДокумент.ДетализацияРасчета.Получить();
КонецФункции

В результате таблица документа в СУБД становится компактной, а форма открывается мгновенно, считывая тяжелый расчетный блок только при необходимости.

Решение 3. Интерфейс на основе поля табличного документа

Если пользователи привыкли к табличным редакторам (например, Excel) и требуют видеть расчетное полотно целиком с промежуточными итогами, заменим 300 полей ввода одним элементом ПолеТабличногоДокумента.

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


&НаСервере
Процедура СформироватьСеткуРасчета()
    ТабДок = Элементы.РасчетноеПолотно;
    Макет = Документы.КалькуляцияПечати.ПолучитьМакет("МакетРасчета");
    
    Область = Макет.ПолучитьОбласть("ПараметрыПечати");
    // Снимаем защиту с ячеек для ввода коэффициентов
    Область.Параметры.КоэффициентКраски = Объект.РасходКраски;
    
    ТабДок.Вывести(Область);
    ТабДок.Защита = Истина; // Защищаем заголовки, оставляя открытыми только нужные ячейки
КонецПроцедуры

Этот метод полностью устраняет проблему тяжелой формы: вместо 300 тяжелых контролов операционной системы платформа управляет единой координатной сеткой ячеек.

Решение 4. Разделение форм документа

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

  1. Основная форма документа: содержит минимальный состав реквизитов (контрагент, сумма, статус, тираж). Открывается мгновенно менеджерами и бухгалтерами.
  2. Форма технолога: вызывается по гиперссылке или отдельной команде «Открыть подробный расчет» только теми специалистами, кому действительно требуется корректировка технологической цепочки.

Решение 5. Оптимизация серверных вызовов при расчетах

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


&НаКлиенте
Процедура КоэффициентПриИзменении(Элемент)
    // Передаем только изменяемое значение и ключевой параметр, избегая контекста формы
    НоваяСумма = РассчитатьОперациюНаСервере(Объект.Тираж, Объект.КоэффициентСложности);
    Объект.ИтоговаяСумма = НоваяСумма;
КонецПроцедуры

&НаСервереБезКонтекста
Функция РассчитатьОперациюНаСервере(Знач Тираж, Знач Коэффициент)
    Возврат Тираж * Коэффициент * 1.15;
КонецФункции

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

← На главную