При разработке интерфейсов на управляемых формах часто возникает задача визуального выделения данных. Одной из популярных задач является раскраска ячеек в зависимости от состояния объекта — например, выделение цвета ссылки на документ в зависимости от того, проведен он, помечен на удаление или просто записан. В отличие от Динамического списка, где условное оформление работает практически "из коробки" на уровне запроса, работа с Таблицей Значений (ТЗ) требует более детального подхода.
В этой статье мы подробно разберем, как реализовать цветовую индикацию статуса документа в конкретной ячейке таблицы, рассмотрим способы оптимизации серверных вызовов и выясним, как поддерживать актуальность данных, если их изменил другой пользователь.
Разберем ситуацию: у нас есть Таблица Значений в реквизитах формы (например, Объект.Документы), где присутствуют колонки Документ (тип ДокументСсылка.ЗаказКлиента) и Количество. Нам нужно раскрасить ячейку с документом. Напрямую использовать реквизит Проведен или ПометкаУдаления через точку в условном оформлении ТЗ нельзя, так как это приведет к катастрофическому падению производительности из-за неявных запросов к базе данных при каждой отрисовке строки.
Правильное решение: добавим в структуру нашей таблицы вспомогательную колонку, которая будет хранить индекс состояния (статус). Назовем её СтатусДокумента (тип Число). Мы будем использовать следующие значения:
Настроить оформление можно как в конфигураторе, так и программно. Рассмотрим программный способ в процедуре ПриСозданииНаСервере, так как он более гибкий. Нам важно оформить именно конкретное поле, а не всю строку.
Проанализируем пример кода для настройки оформления:
&НаСервере
Процедура НастроитьУсловноеОформление()
// Оформление для ПРОВЕДЕННЫХ документов (Зеленый)
ЭлементОформления = УсловноеОформление.Элементы.Добавить();
// Устанавливаем цвет фона
ЭлементОформления.Оформление.УстановитьЗначениеПараметра("ЦветФона", ЦветаСтиля.ЦветФонаПоложительногоИтога); // Или WebЦвета.Зеленый
// Формируем условие: СтатусДокумента Равно 1
ЭлементУсловия = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементУсловия.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Объект.Документы.СтатусДокумента");
ЭлементУсловия.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементУсловия.ПравоеЗначение = 1;
// Важный момент: указываем, какое именно поле оформлять
ОформляемоеПоле = ЭлементОформления.Поля.Элементы.Добавить();
ОформляемоеПоле.Поле = Новый ПолеКомпоновкиДанных("ДокументыДокумент"); // Имя элемента формы (колонки)
// Аналогично добавляются правила для статусов 0 (желтый) и 2 (красный)
КонецПроцедуры
Обратите внимание на ОформляемоеПоле. Если вы не добавите конкретное поле в коллекцию Поля, платформа раскрасит всю строку целиком. Указывая конкретное имя колонки, мы добиваемся точечного оформления.
Выясним, как правильно заполнять колонку СтатусДокумента. Если мы будем в цикле обходить таблицу и обращаться к свойствам ссылки (Стр.Документ.Проведен), это создаст отдельный запрос к СУБД на каждую строку. Для таблицы из 100 строк это будет 100 лишних запросов.
Рассмотрим метод массового получения данных через запрос. Этот подход наиболее профессионален и быстр:
&НаСервере
Процедура ОбновитьСтатусыДокументовВТаблице()
// Выгружаем все ссылки на документы в массив, чтобы передать в запрос
МассивСсылок = Объект.Документы.ВыгрузитьКолонку("Документ");
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ЗаказКлиента.Ссылка КАК Ссылка,
| ВЫБОР
| КОГДА ЗаказКлиента.ПометкаУдаления ТОГДА 2
| КОГДА ЗаказКлиента.Проведен ТОГДА 1
| ИНАЧЕ 0
| КОНЕЦ КАК Статус
|ИЗ
| Документ.ЗаказКлиента КАК ЗаказКлиента
|ГДЕ
| ЗаказКлиента.Ссылка В(&МассивСсылок)";
Запрос.УстановитьПараметр("МассивСсылок", МассивСсылок);
РезультатЗапроса = Запрос.Выполнить().Выгрузить();
// Теперь быстро обновляем данные в ТЧ формы
Для Каждого СтрокаТЧ Из Объект.Документы Цикл
НайденнаяСтрока = РезультатЗапроса.Найти(СтрокаТЧ.Документ, "Ссылка");
Если НайденнаяСтрока <> Неопределено Тогда
СтрокаТЧ.СтатусДокумента = НайденнаяСтрока.Статус;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Этот код выполняется за один транш к базе данных, что значительно ускоряет работу формы, особенно при большом количестве строк.
Проанализируем ситуацию: пользователь открыл форму, статусы определились. В это время другой пользователь провел или пометил на удаление один из этих документов. Данные на форме у первого пользователя устарели.
Поскольку Таблица Значений — это статический объект (в отличие от Динамического списка), она не умеет сама "слушать" изменения в базе данных. Для решения этой проблемы рассмотрим несколько механизмов:
Оповестить("Запись_ЗаказКлиента", СсылкаНаДокумент), то в нашей форме мы можем поймать это событие в обработчике ОбработкаОповещения.
&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
Если ИмяСобытия = "Запись_ЗаказКлиента" Тогда
// Находим строку в ТЧ и обновляем её статус через серверный вызов
ОбновитьСтатусКонкретнойСтроки(Параметр);
КонецЕсли;
КонецПроцедуры
Если таблица документов содержит тысячи строк, передача всей формы на сервер (&НаСервере) при каждом обновлении статуса станет накладной. В таких случаях рекомендуется использовать &НаСервереБезКонтекста. Мы передаем на сервер только массив ссылок, получаем обратно структуру или массив со статусами и обновляем коллекцию на клиенте.
Это позволяет минимизировать объем данных, передаваемых между клиентом и сервером (так называемый "сериализованный контекст формы"), что критично для работы через тонкий клиент в условиях медленного интернета.
Мы выяснили, что для реализации условного оформления ячейки в ТЗ необходимо:
УсловноеОформление с указанием конкретного ОформляемогоПоля.Такой подход обеспечивает не только визуальную привлекательность интерфейса, но и его стабильную, быструю работу под нагрузкой.