При формировании отчетов или печатных форм в 1С разработчики часто сталкиваются с необходимостью визуально выделить определенные данные — например, покрасить фон ячейки с суммой или статусом в зависимости от условий. Однако при попытке программно изменить цвет фона ячеек в выводимой области макет может повести себя непредсказуемо: строки начинают «разъезжаться», таблица визуально ломается, а раскрашенные ячейки смещаются вниз и выводятся отдельной строкой.
В этой статье мы подробно разберем, почему возникает эта проблема, как устроена адресация внутри областей макета, и рассмотрим три надежных способа программной раскраски ячеек без деформации итогового табличного документа.
Давайте проанализируем типичную ситуацию. Разработчик получает область макета с помощью метода ПолучитьОбласть("Таблица"). В исходном макете эта секция расположена, к примеру, на 11-й и 12-й строках. Логично предположить, что для раскраски двух ячеек во второй колонке нужно обратиться к ним по адресу: ОбластьТаблица.Область("R11C2:R12C2"). Но именно здесь кроется главная ошибка.
Когда мы вызываем метод ПолучитьОбласть(), платформа 1С копирует указанную секцию и создает на ее основе изолированный, самостоятельный табличный документ. Координаты внутри этой новой локальной области всегда сбрасываются и начинаются с R1C1 (строка 1, колонка 1), независимо от того, на каких строках эта область находилась в исходном шаблоне конфигуратора.
Если реальная высота полученной области составляет всего 2 строки, а в коде выполняется обращение к 11-й строке через Область("R11C2:R12C2"), платформа 1С автоматически «растягивает» эту локальную область до 12 строк, заполняя пустые строки значениями по умолчанию. При последующем вызове метода Вывести() в итоговый документ попадает не компактная строка, а огромный пустой блок из 12 строк с раскрашенным низом. Это и приводит к визуальному разрыву таблицы.
Самый простой и быстрый способ исправить ошибку — скорректировать адресацию ячеек, учитывая локальные координаты полученной области. Если целевые ячейки занимают первую и вторую строки внутри выделенной области Таблица, то и обращаться к ним нужно как к первой и второй строке:
ОбластьТаблица.Область("R1C2:R2C2").ЦветФона = WebЦвета.Зеленый;
Однако при использовании этого метода в цикле нас подстерегает еще одна проблема — проблема «грязного» шаблона. Если мы получаем область макета один раз вне цикла (что абсолютно верно с точки зрения производительности), любые изменения свойств ее ячеек будут сохраняться в памяти.
Если в цикле обхода данных мы покрасим ячейку в зеленый цвет при выполнении какого-то условия, то все последующие строки, выводимые следом, также останутся зелеными, даже если они не соответствуют условию. Чтобы избежать этого эффекта, нам придется принудительно возвращать стандартный цвет в ветке Иначе:
Пока ВыборкаДетЗаписи.Следующий() Цикл
ОбластьТаблица.Параметры.Заполнить(ВыборкаДетЗаписи);
Если ВыборкаДетЗаписи.ВажноеУсловие Тогда
ОбластьТаблица.Область("R1C2:R2C2").ЦветФона = WebЦвета.Зеленый;
Иначе
// Возвращаем авто-цвет (сбрасываем оформление)
ОбластьТаблица.Область("R1C2:R2C2").ЦветФона = Новый Цвет;
КонецЕсли;
ТабличныйДокумент.Вывести(ОбластьТаблица);
КонецЦикла;
Существует гораздо более элегантный, профессиональный и производительный способ раскраски, который избавляет от необходимости следить за «чистотой» макета и высчитывать локальные координаты.
Метод ТабличныйДокумент.Вывести() возвращает специальный объект типа ОбластьЯчеекТабличногоДокумента. Эта возвращаемая область содержит абсолютные координаты только что выведенного блока строк уже непосредственно в результирующем документе. У этого объекта есть свойства Верх, Низ, Лево и Право.
Давайте посмотрим на пример реализации этого подхода:
// Получаем область один раз вне цикла, макет остается чистым
ОбластьТаблица = Макет.ПолучитьОбласть("Таблица");
Пока ВыборкаДетЗаписи.Следующий() Цикл
// Заполняем параметры области данными из выборки
ОбластьТаблица.Параметры.Заполнить(ВыборкаДетЗаписи);
// Выводим область и сразу получаем её абсолютные координаты в результирующем документе
ОбластьОформления = ТабличныйДокумент.Вывести(ОбластьТаблица);
// Раскрашиваем ячейки непосредственно в итоговом документе
Если ВыборкаДетЗаписи.ВажноеУсловие Тогда
// Красим только что выведенные строки (с Верх по Низ) во 2-й колонке
ТабличныйДокумент.Область(ОбластьОформления.Верх, 2, ОбластьОформления.Низ, 2).ЦветФона = WebЦвета.Зеленый;
КонецЕсли;
КонецЦикла;
Преимущества этого метода очевидны:
ОбластьТаблица всегда остается чистым. Нам не нужно писать ветку Иначе для сброса цвета фона.Использование строковых литералов формата "R1C2:R2C2" считается плохим стилем разработки по ряду причин. Если в будущем аналитик или дизайнер изменит структуру макета (например, добавит новую колонку слева), целевая колонка сместится с индекса 2 на индекс 3. Код продолжит красить вторую колонку, выводя неверное оформление и заставляя разработчика вручную переписывать программный код.
Чтобы сделать код гибким и устойчивым к изменениям, воспользуемся альтернативными подходами:
А. Использование именованных областей внутри секции
В самом макете конфигуратора выделите целевые ячейки внутри области Таблица и задайте им уникальное имя в свойствах (например, ЯчейкаСтатуса). Тогда в коде вы сможете обращаться к ним напрямую по имени:
ОбластьТаблица.Область("ЯчейкаСтатуса").ЦветФона = WebЦвета.Зеленый;
Платформа 1С самостоятельно определит, где именно внутри выведенной строки находится именованная ячейка, даже если вы добавите новые колонки в макет.
Б. Использование числовых параметров области
Вместо текстового формата адресации "R1C2" лучше использовать обращение через числовые индексы метода Область(НачСтрока, НачКолонка, КонСтрока, КонКолонка), где номера колонок вынесены в понятные константы или переменные в начале процедуры:
КолонкаСуммы = 2; // Номер колонки легко поменять в одном месте кода
// В цикле при выводе:
ТабличныйДокумент.Область(ОбластьОформления.Верх, КолонкаСуммы, ОбластьОформления.Низ, КолонкаСуммы).ЦветФона = WebЦвета.Зеленый;
Применение этих простых и надежных правил позволит вам создавать красивые, динамически раскрашиваемые отчеты, которые не «разъезжаются» при выводе и легко поддаются дальнейшей поддержке и доработке.