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