При формировании печатных форм и отчетов нередко возникает задача условного форматирования: в зависимости от данных строки требуется объединить определенные ячейки, изменить границы или применить заливку. Если заголовок или шапка отчета состоят из множества строк, жестко прописывать номера в коде крайне нежелательно. Любое редактирование макета (например, добавление новой строки в шапку) сломает ручной расчет координат, и форматирование сместится.
Проанализируем специфику работы с координатами табличного документа в платформе 1С:Предприятие и разберем наиболее надежные способы решения этой задачи.
Выясним, как платформа 1С определяет текущие размеры документа:
ВысотаТаблицы всегда отражает фактическое количество строк, выведенных в табличный документ на данный момент. Номер последней выведенной строки равен значению ТабДок.ВысотаТаблицы.ШиринаТаблицы возвращает максимальную ширину документа среди всех сформированных строк. Если в шапке документа было выведено 15 колонок, то значение свойства всегда будет равно 15, даже если текущая строка состоит всего из 3 колонок. Поэтому определять позицию столбца через ширину таблицы нельзя.Разберем самый чистый и удобный способ. Вместо того чтобы искать строку в готовом документе и рассчитывать смещение шапки, выполним объединение ячеек в самой области макета до момента ее отправки на печать. Внутри полученной области строки нумерация строк всегда начинается с единицы, независимо от того, какой по счету эта строка станет в итоговом отчете.
Посмотрим на пример кода:
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
Для Каждого СтрДанных Из ТаблицаДанных Цикл
ОбластьСтрока.Параметры.Заполнить(СтрДанных);
Если СтрДанных.ТребуетсяОбъединение Тогда
// Внутри локальной области первая строка всегда имеет индекс 1
// Объединяем, например, со 2-й по 4-ю колонку
ОбластьСтрока.Область("R1C2:R1C4").Объединить();
КонецЕсли;
ТабДок.Вывести(ОбластьСтрока);
КонецЦикла;
Важный нюанс: метод Макет.ПолучитьОбласть() каждый раз создает новый объект в памяти, поэтому модификация ячеек не испортит исходный макет конфигурации.
Если объединение ячеек необходимо выполнить именно в результирующем табличном документе (например, при постобработке), зафиксируем вертикальные координаты через свойство ВысотаТаблицы. Сделаем замер до вывода области и после него.
Рассмотрим реализацию данного алгоритма:
НомерСтрокиДо = ТабДок.ВысотаТаблицы;
ТабДок.Вывести(ОбластьСтрока);
НомерСтрокиПосле = ТабДок.ВысотаТаблицы;
// Диапазон добавленных строк: от (НомерСтрокиДо + 1) до НомерСтрокиПосле
Если УсловиеОбъединения Тогда
// Обращаемся к добавленной строке по абсолютному номеру
ТабДок.Область(НомерСтрокиПосле, 2, НомерСтрокиПосле, 4).Объединить();
КонецЕсли;
Этот способ гарантирует, что мы обратимся именно к выведенной строке, сколько бы строк ни содержала шапка или заголовок отчета.
Разберем подход, который позволяет полностью отказаться от манипуляций с координатами ячеек в программном коде. В самом макете создаются две версии одной и той же строки:
СтрокаОбычная — с разделенными колонками;СтрокаОбъединенная — с заранее объединенными ячейками и настроенными границами.Посмотрим на пример вызова областей:
Для Каждого СтрДанных Из ТаблицаДанных Цикл
Если СтрДанных.СпециальныйРежим Тогда
ОбластьВывода = Макет.ПолучитьОбласть("СтрокаОбъединенная");
Иначе
ОбластьВывода = Макет.ПолучитьОбласть("СтрокаОбычная");
КонецЕсли;
ОбластьВывода.Параметры.Заполнить(СтрДанных);
ТабДок.Вывести(ОбластьВывода);
КонецЦикла;
Такой вариант упрощает сопровождение: оформление и объединение настраиваются визуально в табличном редакторе, а в коде остается только выбор нужной ветки условия.
Если при изменении макета могут сдвинуться не только строки, но и колонки, избегайте жесткого указания номеров колонок (например, индексов 2 и 4). Определим границы колонок динамически, используя свойства именованных областей макета: Лево и Право.
Рассмотрим пример определения координат колонок:
// В макете заранее выделены и названы именованные колонки или ячейки
КолонкаНачало = Макет.ПолучитьОбласть("КолонкаНоменклатура").Лево;
КолонкаКонец = Макет.ПолучитьОбласть("КолонкаХарактеристика").Право;
НомерСтроки = ТабДок.ВысотаТаблицы;
// Объединяем ячейки без жесткой привязки к номерам столбцов
ТабДок.Область(НомерСтроки, КолонкаНачало, НомерСтроки, КолонкаКонец).Объединить();
Если к выведенным строкам потребуется обращаться многократно на разных этапах формирования отчета, сохраним их границы в коллекции именованных областей целевого документа с помощью метода Вставить() коллекции Области.
Посмотрим, как зарегистрировать именованную область программно:
НомерСтроки = ТабДок.ВысотаТаблицы;
// Получаем нужный диапазон ячеек
НужнаяОбласть = ТабДок.Область(НомерСтроки, 1, НомерСтроки, ТабДок.ШиринаТаблицы);
// Регистрируем область с уникальным именем в готовом документе
ТабДок.Области.Вставить("СтрокаИтога_" + Формат(НомерСтроки, "ЧГ="), НужнаяОбласть);
// В дальнейшем к ней можно обращаться по имени напрямую
ТабДок.ПолучитьОбласть("СтрокаИтога_" + Формат(НомерСтроки, "ЧГ=")).ЦветФона = WebЦвета.СветлоСерый;
Таким образом, для безопасной работы со структурой строк наиболее практично объединять ячейки в локальной области до вызова ТабДок.Вывести() либо отслеживать позицию через ТабДок.ВысотаТаблицы в сочетании со свойствами Лево и Право именованных колонок макета.