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