При разработке и доработке печатных форм в системе 1С:Предприятие часто возникает задача динамического изменения выводимых данных в зависимости от документа-источника. Например, при формировании унифицированной формы ТОРГ-12 из документа поступления требуется скрыть или очистить определенные реквизиты, подписи или строки, сохранив при этом их отображение для документов реализации.
Разберем типичные ошибки, возникающие при попытке прямой модификации макета, выясним принципиальные отличия между объектами Макет и ТабличныйДокумент, а также подробно рассмотрим правильные архитектурные способы решения этой задачи.
Рассмотрим распространенную ошибку: попытку обратиться к исходному макету по абсолютным координатам и очистить свойство Текст:
Макет.Область("R59C2").Текст = "";
Макет.Область("R40C19:R60C19").Текст = "";
Проанализируем причины, по которым такой код не дает ожидаемого результата или приводит к ошибкам:
Макет представляет собой исходный неизменяемый шаблон (метаданные). Пользователь на экране или при отправке на принтер видит совершенно другой объект — результирующий ТабличныйДокумент (обычно именуемый ТабДок), который последовательно формируется методом ТабДок.Вывести(...).R59C2) крайне ненадежно. Если в табличной части документа содержится переменное количество строк, координаты подвала и итоговых секций смещаются вниз, и жестко прописанные индексы перестают указывать на нужные ячейки.Текст, Параметр или Шаблон. Если в ячейке указан Параметр, прямое присвоение свойства Текст = "" игнорируется при последующем выполнении метода Область.Параметры.Заполнить(...).СодержитЗначение = Истина, отображаемый текст генерируется платформой на основе свойств Значение и Формат. В этом случае очистка текста не приведет к результату.Наиболее корректный и универсальный подход заключается в очистке параметров конкретной секции макета непосредственно перед ее выводом в итоговый табличный документ. Посмотрим на пример реализации:
// Получаем нужную секцию макета
ОбластьПодвал = Макет.ПолучитьОбласть("Подвал");
// Проверяем контекст вызова
Если ЭтоПоступлениеТоваров Тогда
// Вариант А: Очистка конкретного параметра
ОбластьПодвал.Параметры.Отпустил = "";
// Вариант Б: Очистка именованной ячейки внутри секции
ОбластьПодвал.Область("ЯчейкаПодписи").Текст = "";
// Вариант В: Сброс типизированного значения
Если ОбластьПодвал.Область("ЯчейкаСуммы").СодержитЗначение Тогда
ОбластьПодвал.Область("ЯчейкаСуммы").Значение = Неопределено;
КонецЕсли;
КонецЕсли;
// Выводим уже подготовленную секцию в результирующий документ
ТабДок.Вывести(ОбластьПодвал);
В данном случае мы не зависим от количества строк в табличной части документа, так как обращение происходит к именованным областям и параметрам локальной секции.
Если требуется полностью скрыть строку или диапазон строк, стирать текст в каждой ячейке не требуется. Достаточно воспользоваться свойством Видимость области строк результирующего табличного документа.
Разберем пример программного скрытия строк:
// Скрытие диапазона строк в результирующем документе
ТабДок.Область("R40:R60").Видимость = Ложь;
// Скрытие конкретной строки по номеру
НомерСтрокиДляСкрытия = 59;
ТабДок.Область(НомерСтрокиДляСкрытия, , НомерСтрокиДляСкрытия, ).Видимость = Ложь;
Если логика формирования требует модификации ячеек уже после их вывода, но точный номер строки заранее неизвестен из-за динамической табличной части, используем свойство ВысотаТаблицы объекта ТабличныйДокумент.
Посмотрим, как отследить границы только что выведенной секции:
// Фиксируем номер строки до вывода секции
НомерНачала = ТабДок.ВысотаТаблицы + 1;
// Выводим секцию в отчет
ТабДок.Вывести(ОбластьСекции);
// Получаем конечный номер строки после вывода
НомерКонца = ТабДок.ВысотаТаблицы;
// Адресуем изменения строго в выведенном диапазоне
Если ЭтоПоступлениеТоваров Тогда
// Очищаем колонку 2 в пределах добавленной секции
ТабДок.Область(НомерНачала, 2, НомерКонца, 2).Текст = "";
КонецЕсли;
С точки зрения стандартов разработки 1С, наилучшим решением является разделение макета в конфигураторе на отдельные небольшие горизонтальные секции (например: ШапкаПодвала, ДанныеГрузополучателя, Подписи). Это позволяет управлять выводом секций через простое условие Если ... Тогда без необходимости очистки ячеек:
ТабДок.Вывести(Макет.ПолучитьОбласть("ШапкаПодвала"));
// Выводим блок грузополучателя только для документов отгрузки
Если Не ЭтоПоступлениеТоваров Тогда
ТабДок.Вывести(Макет.ПолучитьОбласть("ДанныеГрузополучателя"));
КонецЕсли;
ТабДок.Вывести(Макет.ПолучитьОбласть("Подписи"));
Такой подход делает программный код прозрачным, упрощает дальнейшую поддержку печатной формы и полностью исключает ошибки позиционирования ячеек при изменении состава макета.