При формировании сложных печатных форм нередко возникает ситуация, когда часть информации в начале документа зависит от данных, которые рассчитываются только в самом конце формирования. Классический пример — указание в шапке или в первой строке спецификации общего количества листов или страниц всего документа.
Проанализируем, почему стандартный подход с заполнением параметров макета не срабатывает «задним числом», и подробно разберем рабочие способы изменения текста в уже сформированном табличном документе.
Метод ТабличныйДокумент.Вывести() является процедурой: он не возвращает ссылку на выведенную область. При выводе секции макета в результирующий табличный документ переносятся только статические свойства ячеек (текст, оформление, расшифровка). Коллекция Параметры существует исключительно в исходной области макета. После того как секция выведена в ТабДокумент, связь с параметрами макета утрачивается, а ячейки становятся обычными областями результирующего документа.
Попытка повторно изменить значение в объекте ОбластьСпецификация.Параметры никак не повлияет на уже добавленные в документ строки.
Разберем популярный и простой способ подстановки: вывод временной строки-метки (маркера) с последующим поиском и заменой текста после завершения формирования документа.
#КоличествоСтраниц#).НайтиТекст() и заменим её текст на актуальное значение.Посмотрим на пример реализации данного алгоритма:
// 1. Формируем шапку с маркером-заполнителем
ОбластьСпецификация = Макет.ПолучитьОбласть("Спецификация");
ОбластьСпецификация.Параметры.ТоварНаименование = "Товар согласно приложения на #КоличествоСтраниц#";
ТабДокумент.Вывести(ОбластьСпецификация);
// 2. Выводим остальные разделы и строки документа
ОбластьСтрока = Макет.ПолучитьОбласть("СтрокаТаблицы");
Для Каждого Стр Из ТаблицаТоваров Цикл
ЗаполнитьЗначенияСвойств(ОбластьСтрока.Параметры, Стр);
ТабДокумент.Вывести(ОбластьСтрока);
КонецЦикла;
// 3. Вычисляем общее количество страниц
ВсегоСтраниц = ТабДокумент.КоличествоСтраниц();
ТекстСтраниц = Строка(ВсегоСтраниц) + " листах";
// 4. Находим маркер и выполняем замену текста
НайденнаяОбласть = ТабДокумент.НайтиТекст("#КоличествоСтраниц#");
Если НайденнаяОбласть <> Неопределено Тогда
НайденнаяОбласть.Текст = СтрЗаменить(НайденнаяОбласть.Текст, "#КоличествоСтраниц#", ТекстСтраниц);
КонецЕсли;
Если в документе выводится большой объем данных, сканирование всего документа через НайтиТекст() может занимать дополнительное время. Более производительный и надежный способ — зафиксировать номер строки в момент вывода целевой секции.
Рассмотрим пошагово, как реализовать обращение к конкретной ячейке по координатам:
ВысотаТаблицы.Область(НомерСтроки, НомерКолонки).
// 1. Фиксируем начальную позицию строки
НомерСтроки = ТабДокумент.ВысотаТаблицы + 1;
НомерКолонки = 2; // Номер колонки, где выводится текст
ОбластьСпецификация = Макет.ПолучитьОбласть("Спецификация");
ТабДокумент.Вывести(ОбластьСпецификация);
// 2. Выводим оставшуюся часть документа
// ... вывод других секций ...
// 3. Получаем итоги и обновляем значение в известной ячейке
ВсегоСтраниц = ТабДокумент.КоличествоСтраниц();
ЯчейкаДляЗамены = ТабДокумент.Область(НомерСтроки, НомерКолонки);
ЯчейкаДляЗамены.Текст = "Товар согласно приложения на " + Строка(ВсегоСтраниц) + " листах";
При использовании метода КоличествоСтраниц() важно учитывать технические особенности платформы 1С:
КоличествоСтраниц() производит расчет на основе параметров страницы (ПолеСверху, ПолеСнизу, ОриентацияСтраницы, АвтоМасштаб). Если эти свойства настраиваются программно, их необходимо задать до вызова метода расчета.ЧислоПрописью() с параметрами предмета исчисления:
ФорматнаяСтрока = "L=ru_RU; ДП=Истина";
ПараметрыПредмета = "лист, листа, листов, м, , , , , 0";
Склонение = ЧислоПрописью(ВсегоСтраниц, ФорматнаяСтрока, ПараметрыПредмета);
// Результат для 2: "два листа", для 5: "пять листов"