Разработка внешних печатных форм (ВПФ) — это одна из первых задач, с которой сталкивается начинающий программист 1С. Однако кажущаяся простота часто скрывает в себе архитектурные ловушки. Проанализируем типичную ситуацию: печатная форма работает, документ выводится на экран, но код написан неоптимально. Разберем по шагам, как превратить «код новичка» в профессиональное решение, соответствующее стандартам Библиотеки стандартных подсистем (БСП) и требованиям высокой производительности.
Самая распространенная ошибка — это выполнение запроса к базе данных внутри цикла обхода документов. Давайте представим ситуацию: пользователь выделяет в списке 50 «Маршрутных листов» и нажимает кнопку «Печать». Если код написан так, что для каждой ссылки из массива выполняется отдельный запрос, система совершит 50 обращений к серверу БД. Это создает избыточную нагрузку на сеть и сервер.
Правильный подход: необходимо собрать данные для всех документов одним запросом. Для этого мы передаем весь МассивОбъектов в параметры запроса и используем оператор ГДЕ Ссылка В (&МассивОбъектов). Проанализируем пример правильной структуры запроса:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| МаршрутныйЛист.Ссылка КАК Ссылка,
| МаршрутныйЛист.Номер КАК Номер,
| МаршрутныйЛист.Дата КАК Дата,
| МаршрутныйЛист.Заказы.(
| НомерСтроки КАК НомерСтроки,
| ЗаказПокупателя КАК ЗаказПокупателя,
| АдресДоставки КАК АдресДоставки
| ) КАК Заказы
|ИЗ
| Документ.МаршрутныйЛист КАК МаршрутныйЛист
|ГДЕ
| МаршрутныйЛист.Ссылка В(&МассивОбъектов)
|ИТОГИ ПО
| Ссылка";
Запрос.УстановитьПараметр("МассивОбъектов", МассивОбъектов);
ВыборкаПоДокументам = Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Обратите внимание на использование ИТОГИ ПО Ссылка. Это позволяет нам в дальнейшем эффективно обходить данные: сначала по самим документам (для формирования шапки), а затем по их табличным частям.
Профессионально написанная печатная форма обязана уметь обрабатывать произвольное количество документов. Если в коде зашито обращение к МассивОбъектов[0], то при выделении нескольких строк в списке напечатается только первый документ, что введет пользователя в заблуждение.
Рассмотрим алгоритм обхода выборки с учетом итогов, который обеспечит корректную массовую печать:
Пока ВыборкаПоДокументам.Следующий() Цикл
// Выводим область шапки для каждого нового документа
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
ОбластьШапка.Параметры.Заполнить(ВыборкаПоДокументам);
ТабДок.Вывести(ОбластьШапка);
// Переходим к детальным записям (табличной части)
ВыборкаСтрок = ВыборкаПоДокументам.Выбрать();
Пока ВыборкаСтрок.Следующий() Цикл
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
ОбластьСтрока.Параметры.Заполнить(ВыборкаСтрок);
ТабДок.Вывести(ОбластьСтрока);
КонецЦикла;
// Добавляем разделитель страниц, если это не последний документ
ТабДок.ВывестиГоризонтальныйРазделительСтраниц();
КонецЦикла;
Использование метода ТабДок.ВывестиГоризонтальныйРазделительСтраниц() гарантирует, что каждый «Маршрутный лист» начнется с новой страницы, что критично для работы логистов и водителей.
Многие начинающие разработчики используют метод Сообщить() для проверки значений переменных. Это неудобно, так как не позволяет видеть структуру объектов и типов данных. Выясним, как отлаживать ВПФ правильно.
Рекомендуется встраивать во внешнюю обработку вспомогательную форму. На этой форме размещается реквизит с типом нужного документа и кнопка «Печать». В коде кнопки вызывается экспортная процедура Печать из модуля объекта. Таким образом, вы можете открыть обработку через меню «Файл — Открыть», выбрать тестовый документ и поставить точку останова в конфигураторе. Процесс отладки станет в разы быстрее и прозрачнее.
Вопрос об объединении ячеек часто вызывает споры. Проанализируем ситуацию: если мы программно объединяем ячейки в цикле через Область.Объединить(), это может существенно замедлить формирование формы при большом количестве строк (от 500 и выше).
Совет: старайтесь максимально настроить объединение ячеек непосредственно в макете. Программное объединение следует использовать только в тех случаях, когда структура колонок динамически меняется в зависимости от данных. Также не забывайте устанавливать свойство ТабДок.АвтоМасштаб = Истина, чтобы печатная форма автоматически подгонялась под ширину листа при печати на разных принтерах.
В контексте конфигурации «Управление нашей фирмой», маршрутные листы часто требуют вывода весогабаритных характеристик (ВГХ). Если этих данных нет непосредственно в табличной части заказа, не стоит получать их через точку в цикле (например, Строка.Номенклатура.Вес), так как это порождает неявные запросы к базе.
Давайте выясним причину медленной работы таких форм: каждое обращение через точку к реквизиту ссылочного типа заставляет 1С считывать весь объект из базы. Чтобы избежать этого, добавьте левое соединение с соответствующими справочниками или регистрами сведений (например, ШтрихкодыНоменклатуры или ХарактеристикиНоменклатуры) прямо в основной запрос печатной формы.
Если «Маршрутный лист» содержит сотни заказов, в каждом из которых десятки позиций номенклатуры, сложность запроса растет. В этом случае эффективно использовать временные таблицы. Рассмотрим схему такого запроса:
МассивОбъектов во временную таблицу ВТ_Ссылки.ВТ_Ссылки с основной таблицей документов для получения шапки.ВТ_Ссылки с табличной частью для получения строк, сразу вычисляя итоги по весу и объему.Такой подход позволяет СУБД построить оптимальный план выполнения запроса, что значительно ускоряет получение данных по сравнению с простыми соединениями «в лоб».
Подведем итог. Качественная внешняя печатная форма — это не только корректный внешний вид, но и соблюдение стандартов разработки 1С. Основные правила: один запрос на все документы, использование механизмов БСП, отказ от запросов в циклах и грамотная работа с макетом. Придерживаясь этих принципов, вы создадите надежный инструмент, который будет работать быстро даже в условиях высокой нагрузки на базу данных.