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

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Сравнение двух подходов к заполнению параметров

Рассмотрим два распространенных варианта кода, выполняющих одну и ту же задачу — заполнение шапки с данными контрагента.

Вариант 1. Заполнение через структуру и метод Заполнить():


ОбластьМакета = Макет.ПолучитьОбласть("Поставщик");
СтруктураДанныхПоставщик = Новый Структура;
ПредставлениеПоставщика = ФормированиеПечатныхФорм.ОписаниеОрганизации(ФормированиеПечатныхФорм.СведенияОЮрФизЛице(ДанныеПечати.Организация, ДанныеПечати.Дата), "ПолноеНаименование");
СтруктураДанныхПоставщик.Вставить("ПредставлениеПоставщика", ПредставлениеПоставщика);
СтруктураДанныхПоставщик.Вставить("Поставщик", ДанныеПечати.Организация);
ОбластьМакета.Параметры.Заполнить(СтруктураДанныхПоставщик);
ТабличныйДокумент.Вывести(ОбластьМакета);

Вариант 2. Прямое присвоение значений параметрам области:


ОбластьМакета = Макет.ПолучитьОбласть("Поставщик");
ОбластьМакета.Параметры.ПредставлениеПоставщика = ФормированиеПечатныхФорм.ОписаниеОрганизации(ФормированиеПечатныхФорм.СведенияОЮрФизЛице(ДанныеПечати.Организация, ДанныеПечати.Дата), "ПолноеНаименование");
ОбластьМакета.Параметры.Поставщик = ДанныеПечати.Организация;
ТабличныйДокумент.Вывести(ОбластьМакета);

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

Почему в типовых конфигурациях и БСП используется метод Заполнить()

В большинстве типовых решений фирмы «1С» (таких как 1C:ERP, Управление торговлей, Комплексная автоматизация) повсеместно применяется заполнение через структуры. Выясним основные причины такого подхода:

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

Посмотрим на пример прямой передачи выборки запроса в параметры области:


ВыборкаСтрок = РезультатЗапроса.Выбрать();
Пока ВыборкаСтрок.Следующий() Цикл
    ОбластьСтрока.Параметры.Заполнить(ВыборкаСтрок);
    ТабличныйДокумент.Вывести(ОбластьСтрока);
КонецЦикла;

Рекомендации по реальной оптимизации скорости формирования печатных форм

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

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

// Более быстрый и компактный вариант создания структуры:
СтруктураДанных = Новый Структура("Поставщик, ПредставлениеПоставщика", ДанныеПечати.Организация, ПредставлениеПоставщика);
ОбластьМакета.Параметры.Заполнить(СтруктураДанных);

Таким образом, с точки зрения скорости варианты равнозначны, однако по соображениям отказоустойчивости и стандартов разработки БСП следует использовать метод Заполнить().

← На главную