Разработка внешних печатных форм — это одна из первых задач, с которой сталкивается начинающий программист 1С. Несмотря на кажущуюся простоту, этот процесс скрывает множество нюансов, связанных со стандартами разработки и особенностями платформы. Рассмотрим типичную ситуацию: вы создали внешнюю обработку, настроили макет, написали код, но при выводе на печать вместо номера и даты документа вы видите пустые поля или исходный текст макета. Разберем пошагово, почему это происходит и как правильно настроить заполнение данных.
Одной из самых распространенных ошибок является неправильное определение заголовка (сигнатуры) функции, которая отвечает за формирование печатной формы. В современных конфигурациях, построенных на базе Библиотеки стандартных подсистем (БСП), существует жесткий стандарт. Система ожидает, что функция будет принимать массив ссылок, а не одиночную ссылку на документ.
Проанализируем типичную ошибку. Часто разработчики пытаются упростить код и пишут так:
Функция СформироватьПечатнуюФорму(СсылкаНаОбъект, ОбъектыПечати) Экспорт
// Код формирования
КонецФункции
Такой подход может сработать при ручном вызове, но механизм «Дополнительные отчеты и обработки» передает в качестве первого параметра именно МассивОбъектов. Даже если вы печатаете всего один документ, система упаковывает его ссылку в массив. Если функция ожидает одиночную ссылку, происходит конфликт типов, и данные не могут быть получены корректно.
Рассмотрим правильный вариант реализации, соответствующий стандартам БСП:
Функция СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати) Экспорт
ТабличныйДокумент = Новый ТабличныйДокумент;
Макет = ПолучитьМакет("Макет");
Для Каждого Ссылка Из МассивОбъектов Цикл
// Здесь происходит основная работа с каждым документом
КонецЦикла;
Возврат ТабличныйДокумент;
КонецФункции
Использование цикла Для Каждого позволяет корректно обработать ситуацию, когда пользователь выделяет в списке несколько документов и нажимает кнопку «Печать».
Если программный код кажется верным, но параметры всё равно не заполняются, нам необходимо проверить сам макет (табличный документ). Выясним, как 1С понимает, что в конкретную ячейку нужно подставить данные из базы.
У каждой ячейки макета есть важное свойство — «Заполнение». Оно может принимать три значения:
[Номер], пользователь увидит именно это слово со скобками.Область.Параметры.Номер = "001". В макете при этом пишется просто Номер.Счет № [Номер] от [Дата]. Все, что в квадратных скобках, система попытается заменить данными.Посмотрим на частую ошибку: разработчик прописывает в коде заполнение параметра, но в макете у ячейки по ошибке оставлен тип «Текст». В этом случае 1С просто проигнорирует ваши программные команды. Всегда проверяйте через палитру свойств, что для ячеек с датой и номером установлен тип Параметр.
Также важно помнить про регистр имен. Хотя язык 1С в целом нечувствителен к регистру, хорошей практикой считается полное совпадение имен в коде и макете. Если в макете параметр назван ДатаДокумента, то и в коде обращайтесь к нему именно так: Область.Параметры.ДатаДокумента.
Разберем ситуацию, когда мы получили область макета, но параметры в ней пустые. Рассмотрим, как опытные разработчики автоматизируют процесс заполнения, чтобы не писать по одной строчке для каждого реквизита.
Вместо длинного списка присваиваний:
ОбластьШапка.Параметры.Номер = Ссылка.Номер;
ОбластьШапка.Параметры.Дата = Ссылка.Дата;
ОбластьШапка.Параметры.Организация = Ссылка.Организация;
Мы можем использовать встроенную функцию ЗаполнитьЗначенияСвойств. Это значительно ускоряет разработку, если имена параметров в вашем макете совпадают с именами реквизитов документа в базе данных.
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
// Заполняем сразу все параметры области данными из ссылки
ЗаполнитьЗначенияСвойств(ОбластьШапка.Параметры, Ссылка);
ТабличныйДокумент.Вывести(ОбластьШапка);
Важное замечание по производительности: Обращение к данным через точку (Ссылка.Номер, Ссылка.Дата) внутри цикла по массиву объектов — это «плохой тон» в программировании 1С. Каждое такое обращение заставляет систему выполнять отдельный запрос к серверу базы данных. Если вы печатаете 100 документов, нагрузка возрастет многократно. Проанализируем, как сделать правильно: лучше один раз получить данные всех документов одним запросом, а затем использовать их при формировании областей.
Если данные все равно не выводятся, нам нужно выяснить, что именно содержит переменная Ссылка (или МассивОбъектов) в момент выполнения кода. Для этого используется отладка.
Поскольку внешнюю обработку сложно «поймать» отладчиком в обычном режиме (когда она запускается из справочника «Дополнительные отчеты и обработки»), воспользуемся следующими приемами:
Печать или СформироватьПечатнуюФорму. Чтобы она сработала, откройте обработку через меню «Файл -> Открыть» (если в ней предусмотрен тестовый запуск) или используйте специальные расширения для отладки внешних форм.Ссылка, нажмите Shift+F9 и убедитесь, что это не Неопределено или ПустаяСсылка.Сообщить("Тип ссылки: " + ТипЗнч(Ссылка) + ", Значение: " + Ссылка);. Это позволит увидеть состояние данных непосредственно в окне сообщений при запуске печати.Бывают случаи, когда параметры заполнены идеально, но печатная форма все равно пуста. Выясним причину. После того как вы получили область макета и заполнили её параметры, эту область нужно физически добавить в результирующий табличный документ.
Проверьте наличие команды Вывести():
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
ОбластьШапка.Параметры.Дата = ТекущаяДата();
// Без следующей строки область не появится в печатной форме!
ТабличныйДокумент.Вывести(ОбластьШапка);
Если вы сначала заполнили параметры, а потом забыли вызвать Вывести() или Присоединить(), ваши усилия по заполнению данных останутся только в оперативной памяти, не попав на экран пользователя.
Подведем итог: для корректного заполнения параметров даты и номера необходимо обеспечить правильную сигнатуру функции (прием МассивОбъектов), проверить тип заполнения ячеек в макете (Параметр), убедиться в корректности получения ссылки на объект и не забыть вывести подготовленную область в итоговый табличный документ.