В разработке на платформе 1С 8.2 или 8.3 при использовании Обычных форм программисты часто сталкиваются с задачей визуального выделения данных. Например, нужно подсветить строки с отрицательными остатками или выделить ячейки с определенным товаром по нажатию кнопки. В отличие от управляемых форм, где оформление можно задать через условное оформление в свойствах списка, в обычных формах процесс требует понимания механизмов отрисовки интерфейса.
Разберем подробно, почему нельзя просто «покрасить» ячейку внутри цикла перебора таблицы и как правильно реализовать эту задачу, чтобы интерфейс работал быстро и без ошибок.
Главная техническая сложность заключается в том, что объект ОформлениеСтроки, который отвечает за цвета, шрифты и видимость ячеек, не является частью данных самой таблицы (будь то ТаблицаЗначений или ТабличнаяЧасть). Этот объект существует динамически только в момент, когда платформа «рисует» таблицу на экране монитора.
Проанализируем ситуацию: когда мы нажимаем на кнопку и перебираем строки таблицы в цикле, мы работаем с данными. Но у объекта строки данных нет свойства ЦветФона. Цвет «живет» в объекте ОформлениеСтроки, к которому можно обратиться только в специализированных процедурах-событиях табличного поля. Поэтому реализация задачи всегда делится на два этапа: подготовка данных и визуальное отображение.
Чтобы при нажатии на кнопку система «узнала», какие именно ячейки нужно покрасить, нам необходимо создать некий признак в самой таблице. Рассмотрим наиболее надежный способ — использование служебной колонки.
СостояниеЦвета (тип Число или Булево).Рассмотрим пример кода для обработчика кнопки:
Процедура КнопкаВыделитьЦветомНажатие(Элемент)
// Перебираем строки нашей таблицы (например, ТчНоменклатура)
Для Каждого СтрокаТЗ Из Объект.ТчНоменклатура Цикл
// Условие, при котором нужно выделить ячейку
Если СтрокаТЗ.Количество < 0 Тогда
СтрокаТЗ.СостояниеЦвета = 1; // Устанавливаем флаг для покраски
Иначе
СтрокаТЗ.СостояниеЦвета = 0; // Сбрасываем флаг
КонецЕсли;
КонецЦикла;
// ВАЖНО: Принудительно заставляем форму перерисовать таблицу,
// чтобы сработало событие оформления
ЭлементыФормы.ТчНоменклатура.Обновить();
КонецПроцедуры
Теперь, когда данные подготовлены и метод Обновить() вызван, платформа начнет отрисовывать каждую строку заново. В этот момент для каждой видимой строки будет вызываться предопределенное событие ПриВыводеСтроки. Именно здесь мы и «покрасим» ячейки.
Выясним, как правильно написать код внутри этого события:
Процедура ТчНоменклатураПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
// Проверяем наш служебный флаг, который мы установили по кнопке
Если ДанныеСтроки.СостояниеЦвета = 1 Тогда
// Вариант 1: Красим всю строку целиком
// ОформлениеСтроки.ЦветФона = Новый Цвет(255, 200, 200); // Светло-красный
// Вариант 2: Красим только конкретную ячейку (например, "Количество")
ОформлениеСтроки.Ячейки.Количество.ЦветФона = Новый Цвет(255, 150, 150);
// Можно также изменить шрифт на жирный
ОформлениеСтроки.Ячейки.Количество.Шрифт = Новый Шрифт(,,Истина);
Иначе
// Обязательно сбрасываем оформление к стандартному,
// иначе при прокрутке цвета могут "залипнуть"
ОформлениеСтроки.Ячейки.Количество.ЦветФона = ЦветаСтиля.ЦветФонаПоля;
ОформлениеСтроки.Ячейки.Количество.Шрифт = Новый Шрифт(,,Ложь);
КонецЕсли;
КонецПроцедуры
Если в вашей таблице сотни или тысячи строк, использование ПриВыводеСтроки может привести к «подтормаживанию» интерфейса при скроллинге. Это происходит потому, что процедура вызывается для каждой строки отдельно. Для оптимизации в 1С предусмотрено более мощное событие — ПриПолученииДанных.
Проанализируем ситуацию: это событие срабатывает один раз для целой группы строк, которые в данный момент отображаются на экране. Это позволяет нам:
Пример реализации оптимизированной раскраски:
Процедура ТчНоменклатураПриПолученииДанных(Элемент, ОформленияСтрок)
// ОформленияСтрок - это коллекция объектов ОформлениеСтроки
Для Каждого Оформление Из ОформленияСтрок Цикл
// Получаем данные текущей строки через свойство ДанныеСтроки
ТекДанные = Оформление.ДанныеСтроки;
Если ТекДанные.СостояниеЦвета = 1 Тогда
Оформление.Ячейки.Количество.ЦветФона = Новый Цвет(255, 230, 230);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Многие разработчики замечают, что точка останова в процедуре ПриВыводеСтроки срабатывает гораздо чаще, чем количество строк в таблице. Выясним причину этого поведения платформы. В «Обычных формах» отрисовка — это непрерывный процесс. Событие вызывается не только при открытии формы, но и:
Критически важно: Никогда не пишите внутри этих событий «тяжелый» код. Не делайте запросы к базе данных (Новый Запрос), не создавайте сложные объекты и не открывайте модальные окна. Это гарантированно приведет к критическому падению производительности программы.
При работе с цветами фона и текста рекомендуется придерживаться следующих правил:
255, 255, 255), используйте ЦветаСтиля.ЦветФонаПоля. Это позволит вашей обработке корректно выглядеть при смене цветовой схемы Windows или темы 1С.Иначе, которая возвращает стандартный цвет. В противном случае при кэшировании отрисовки вы можете увидеть «хвосты» цвета на строках, которые не должны быть раскрашены.ПриВыводеСтроки всегда полезно проверять, определены ли ДанныеСтроки, чтобы избежать ошибок при добавлении новых пустых строк.Таким образом, мы выяснили, что прямое управление цветом в процедуре кнопки невозможно, но связка «Служебная колонка + Обновить() + ПриВыводеСтроки» является стандартным и надежным решением для обычных форм 1С.