При разработке печатных форм в среде 1С:Предприятие 8 программисты часто прибегают к услугам стандартного Конструктора печати. Он отлично справляется с рутинной работой: автоматически создает макет, регистрирует команду на форме документа и формирует шаблон процедуры печати в модуле менеджера. Однако автоматически сгенерированный код ориентирован на стандартное заполнение всех параметров по принципу "один к одному" из выборки запроса с помощью универсального метода Заполнить().
На практике стандартного поведения бывает недостаточно. Возникают задачи, когда необходимо применить сложную логику заполнения, переопределить вывод отдельных реквизитов вручную или полностью скрыть из печатной формы строки, в которых нет данных, чтобы документ выглядел профессионально и не содержал пустых областей. В рамках этой статьи мы детально разберем, как перейти от автоматического заполнения к ручному управлению параметрами, исправим типичные синтаксические ошибки начинающих разработчиков и рассмотрим эффективные алгоритмы сокрытия пустых полей.
Рассмотрим ситуацию, когда разработчик пытается уйти от автоматического заполнения параметров всей области:
Шапка.Параметры.Заполнить(Выборка);
ТабДок.Вывести(Шапка, Выборка.Уровень());
И заменяет этот код на ручное присвоение:
Шапка.ТранспортнийЗасіб = Выборка.ПротоколВідповідності.ТранспортнийЗасіб()
Этот код не будет работать и вызовет ошибку компиляции или выполнения. Проанализируем, почему это происходит и какие критические ошибки здесь допущены:
Параметры. Область макета (переменная Шапка, имеющая тип ОбластьТабличногоДокумента) не содержит свойств, совпадающих с именами параметров макета напрямую. Все параметры области сгруппированы в специальной коллекции. Обращаться к ним нужно исключительно через свойство Параметры. То есть правильное начало конструкции должно выглядеть как Шапка.Параметры.ИмяПараметра.Выборка.ПротоколВідповідності ошибочна. После того как запрос выполнен и его результат передан в объект выборки (переменная Выборка), иерархия таблиц базы данных "схлопывается". В выборке находятся плоские поля, имена которых соответствуют псевдонимам полей из секции ВЫБРАТЬ вашего запроса. Обращаться к ним нужно напрямую через точку от объекта выборки.ТранспортнийЗасіб() со скобками в конце означает попытку вызвать функцию. Однако реквизиты выборки — это обычные свойства, содержащие данные (ссылки, строки, числа, даты), а не методы или функции. Круглые скобки здесь избыточны и вызовут синтаксическую ошибку.Выяснив причины ошибок, сформулируем правильное обращение к свойствам выборки. Чтобы присвоить конкретному параметру макета значение из результата запроса, используем следующий синтаксис:
Шапка.Параметры.ТранспортнийЗасіб = Выборка.ТранспортнийЗасіб;
Если в вашей печатной форме очень много реквизитов и вам не хочется прописывать вручную каждую строчку кода, вы можете эффективно комбинировать автоматический и ручной подходы. Сначала заполним все параметры по умолчанию, а затем точечно переопределим нужные поля:
// Шаг 1. Заполняем все совпадающие параметры автоматически
Шапка.Параметры.Заполнить(Выборка);
// Шаг 2. Корректируем или дополняем параметры вручную
Шапка.Параметры.ТранспортнийЗасіб = Выборка.ТранспортнийЗасіб;
Шапка.Параметры.Дата = Формат(Выборка.Дата, "ДФ=dd.MM.yyyy");
Шапка.Параметры.ИсполнительФИО = ФизическиеЛица.ФамилияИнициалы(Выборка.Виконавець);
Такой подход экономит время разработки, сокращает объем кода и оставляет возможность гибкого вмешательства в логику вывода данных.
Вторая частая проблема при формировании печатных форм — наличие пустых полей. Если у документа много необязательных для заполнения реквизитов, то при выводе "монолитной" области шапки на листе бумаги будут красоваться пустые строки или незаполненные поля с двоеточиями. Мы разберем два основных метода борьбы с этим визуальным дефектом.
Это самый профессиональный и надежный метод. Вместо создания одной большой области Шапка в макете конфигуратора мы разбиваем ее на несколько независимых горизонтальных строк. Например:
Шапка_Заголовок — содержит номер и дату документа (выводится всегда).Шапка_Контрагент — содержит сведения о заказчике (выводится всегда).Шапка_Транспорт — содержит сведения о транспортном средстве (выводится только при наличии данных).Шапка_Дополнительно — содержит примечания (выводится только при наличии данных).В программном коде модуля менеджера мы прописываем условный вывод каждой секции, используя функцию ЗначениеЗаполнено(). Посмотрим на пример реализации такого алгоритма:
// Выводим обязательную заголовочную часть
ОбластьЗаголовок = Макет.ПолучитьОбласть("Шапка_Заголовок");
ОбластьЗаголовок.Параметры.Заполнить(Выборка);
ТабДок.Вывести(ОбластьЗаголовок);
// Проверяем заполнение транспортного средства перед выводом секции
Если ЗначениеЗаполнено(Выборка.ТранспортнийЗасіб) Тогда
ОбластьТранспорт = Макет.ПолучитьОбласть("Шапка_Транспорт");
ОбластьТранспорт.Параметры.ТранспортнийЗасіб = Выборка.ТранспортнийЗасіб;
ТабДок.Вывести(ОбластьТранспорт);
КонецЕсли;
// Проверяем заполнение исполнителя
Если ЗначениеЗаполнено(Выборка.Виконавець) Тогда
ОбластьИсполнитель = Макет.ПолучитьОбласть("Шапка_Исполнитель");
ОбластьИсполнитель.Параметры.Виконавець = Выборка.Виконавець;
ТабДок.Вывести(ОбластьИсполнитель);
КонецЕсли;
При таком подходе строки печатной формы будут динамически "схлопываться" по высоте, не оставляя лишних пустых пространств на листе бумаги.
Если макет печатной формы уже разработан, имеет сложную сетку колонок и переверстывать его на мелкие области нет возможности или времени, можно применить программный обход сформированного табличного документа перед его выводом на экран.
Важное правило: удаление строк в табличном документе всегда необходимо производить в цикле снизу вверх (в обратном порядке). Если обходить строки сверху вниз, то при удалении первой же пустой строки индексы всех последующих строк сместятся вверх, и ваш цикл начнет пропускать строки или вызовет ошибку выхода за границы коллекции.
Проанализируем пример кода, который удаляет полностью пустые строки из табличного документа:
// Запоминаем общее количество строк в готовом документе
ВсегоСтрок = ТабДок.ВысотаТаблицы;
// Запускаем цикл с последней строки до первой
Для НомерСтроки = -ВсегоСтрок По -1 Цикл
ТекущийИндекс = -НомерСтроки;
// Определяем, есть ли значимая информация в строке.
// Например, проверяем значение во 2-й и 3-й ключевых колонках.
ТекстКолонки2 = ТабДок.Область(ТекущийИндекс, 2).Текст;
ТекстКолонки3 = ТабДок.Область(ТекущийИндекс, 3).Текст;
Если ПустаяСтрока(СокрЛП(ТекстКолонки2)) И ПустаяСтрока(СокрЛП(ТекстКолонки3)) Тогда
// Строка признана пустой, удаляем ее с вертикальным сдвигом
ОбластьУдаления = ТабДок.Область(ТекущийИндекс, , ТекущийИндекс, );
ТабДок.УдалитьОбласть(ОбластьУдаления, ТипСдвигаТабличногоДокумента.ПоВертикали);
КонецЕсли;
КонецЦикла;
Этот метод более ресурсоемкий по сравнению с условным выводом областей, но он незаменим при работе с жестко заданными внешними печатными формами или сложными регламентированными отчетами.
Обратим внимание на то, что в исходном запросе присутствуют поля фотографий: Фото1 ... Фото7. Картинки — это особый тип данных. Если вы попытаетесь вывести их методом Шапка.Параметры.Заполнить(Выборка), на печати вместо изображений вы получите пустые поля либо текстовое представление типа объекта (например, "ХранилищеЗначения").
Рассмотрим правильную методику вывода графических объектов на печать. Для этого нам нужно преобразовать двоичные данные или хранилище значений из базы данных в объект типа Картинка.
Этот способ удобен, когда позиция картинки в макете строго фиксирована. Выполним следующие шаги:
ПараметрФото1.
// Извлекаем двоичные данные картинки из результата запроса
Если ЗначениеЗаполнено(Выборка.Фото1) Тогда
// Если данные хранятся в Хранилище Значения
ДвоичныеДанныеКартинки = Выборка.Фото1.Получить();
Если ДвоичныеДанныеКартинки <> Неопределено Тогда
// Создаем объект Картинка на основе двоичных данных
НоваяКартинка = Новый Картинка(ДвоичныеДанныеКартинки);
// Передаем созданный объект в параметр картинки области макета
Шапка.Параметры.ПараметрФото1 = НоваяКартинка;
КонецЕсли;
КонецЕсли;
Используя эти несложные, но крайне важные правила обращения к коллекции Параметры, механизмы условного вывода секций макета и особенности работы с графическими объектами, вы сможете создавать визуально чистые, динамические и безотказно работающие печатные формы любой сложности.