Как в управляемой форме выделить цветом строки с минимальным и максимальным значением в табличной части?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При переходе на управляемые формы многие разработчики сталкиваются с проблемой изменения оформления строк табличной части в зависимости от значений в ячейках. В обычных формах мы привыкли использовать событие ПриВыводеСтроки, но в управляемом интерфейсе логика работы принципиально иная.

Рассмотрим распространенную задачу: в табличной части есть колонка с числами, и нам необходимо подсветить строку с минимальным значением красным цветом, а с максимальным — зеленым. Разберем ошибки, которые возникают при попытке решить это "в лоб", и правильные способы реализации через механизм Условного оформления.

Почему возникает ошибка "Итератор для значения не определен"?

Часто новички пытаются перебрать строки таблицы, обращаясь к коллекции элементов формы. Код выглядит примерно так:


// ОШИБОЧНЫЙ КОД
Для Каждого Строка Из Элементы.ТаблицаДанных Цикл
    Если Строка.ЧисловойКод = МинимальныйКод Тогда
        Строка.ЦветФона = WebЦвета.Красный; // Так делать нельзя
    КонецЕсли;
КонецЦикла;

При выполнении этого кода платформа выдаст ошибку: "Итератор для значения не определен". Это происходит по следующим причинам:

  1. Элементы.ТаблицаДанных — это элемент интерфейса (визуальное представление), а не коллекция данных. У него нет строк, которые можно перебрать циклом Для Каждого.
  2. В управляемых формах жестко разделены данные (объект, реквизиты) и интерфейс. Мы не можем менять цвет конкретной ячейки императивно в цикле, как это делали в Excel или обычных формах.

Для динамического изменения цвета, шрифта или доступности полей в 1С 8.3 используется механизм Условного оформления. Рассмотрим два способа решения нашей задачи.

Способ 1: Использование служебной колонки (Простой метод)

Этот способ проще для понимания и часто используется, если логика раскраски очень сложная и ее трудно описать декларативными правилами компоновки данных. Суть метода заключается в добавлении в таблицу скрытой колонки, куда мы будем писать признак цвета ("Красный", "Зеленый"), и настройки условного оформления в конфигураторе на основе этой колонки.

Шаг 1. Подготовка данных

Добавим в табличную часть строковый реквизит, например ЦветОформления. Его можно не выводить на форму пользователю.

Шаг 2. Заполнение признаков цвета

После заполнения таблицы данными (например, по кнопке "Заполнить"), мы должны пройтись по данным (коллекции Объект.ТаблицаДанных, а не Элементы) и проставить метки.


// Находим минимум и максимум (примерный алгоритм)
// Лучше это делать запросом или методами выгрузки в ТЗ, 
// но для примера покажем перебор
МинЗначение = 999999;
МаксЗначение = -999999;

Для Каждого Стр Из Объект.ТаблицаДанных Цикл
    Если Стр.ЧисловойКод < МинЗначение Тогда МинЗначение = Стр.ЧисловойКод; КонецЕсли;
    Если Стр.ЧисловойКод > МаксЗначение Тогда МаксЗначение = Стр.ЧисловойКод; КонецЕсли;
КонецЦикла;

// Устанавливаем признаки цвета
Для Каждого Стр Из Объект.ТаблицаДанных Цикл
    Стр.ЦветОформления = ""; // Сброс
    Если Стр.ЧисловойКод = МинЗначение Тогда
        Стр.ЦветОформления = "Красный";
    ИначеЕсли Стр.ЧисловойКод = МаксЗначение Тогда
        Стр.ЦветОформления = "Зеленый";
    КонецЕсли;
КонецЦикла;

Шаг 3. Настройка Условного оформления

В дизайнере формы откройте свойства формы, найдите Условное оформление и добавьте два элемента:

  1. Условие: ЦветОформления Равно "Красный". Оформление: Цвет фона = Красный. Оформляемые поля: Выберите нужные колонки или всю таблицу.
  2. Условие: ЦветОформления Равно "Зеленый". Оформление: Цвет фона = Зеленый.

Недостаток метода: При изменении значения в колонке ЦветОформления платформа считает, что данные формы модифицированы (появляется "звездочка" в заголовке), хотя для пользователя данные по сути не менялись.

Способ 2: Программная настройка Условного оформления (Правильный метод)

Более профессиональный подход — не менять данные в строках, а настроить правила оформления так, чтобы они сравнивали значение в строке с глобальными значениями минимума и максимума. Для этого нам понадобятся реквизиты формы (не таблицы) для хранения границ.

Шаг 1. Реквизиты формы

Добавьте на форму два реквизита (числовых): МинимальныйКод и МаксимальныйКод. Выводить их на экран не обязательно.

Шаг 2. Вычисление границ

При заполнении таблицы вычислите минимум и максимум и сохраните их в созданные реквизиты формы.


// Пример получения данных с сервера, где сразу возвращаются границы
Результат = ЗаполнитьТаблицуНаСервере(ДанныеВвода);
// Присваиваем значения реквизитам формы
ЭтаФорма.МинимальныйКод = Результат.МинимальныйКод;
ЭтаФорма.МаксимальныйКод = Результат.МаксимальныйКод;

Шаг 3. Программное создание правил оформления

Настроим условное оформление один раз при создании формы на сервере. Правило будет звучать так: "Если Объект.Таблица.Код равно МинимальныйКод (реквизит формы), то красить в красный".

Разберем код процедуры настройки:


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

КонецПроцедуры

В этом варианте, когда вы меняете значения реквизитов МинимальныйКод или МаксимальныйКод, подсветка в таблице обновляется автоматически платформой без необходимости перебора строк.

Особенности и оптимизация

Рассмотрим несколько важных моментов при реализации:

  1. Очистка старых правил. Если вы создаете элементы условного оформления динамически (например, по нажатию кнопки, а не при открытии), убедитесь, что вы не дублируете их при каждом нажатии. Перед добавлением можно очищать коллекцию: УсловноеОформление.Элементы.Очистить(), но будьте осторожны, если у вас есть настроенные в конфигураторе правила — они тоже удалятся.
  2. Получение Min/Max через запрос. Если таблица заполняется результатом запроса, используйте агрегатные функции МИНИМУМ() и МАКСИМУМ() прямо в запросе. Это работает намного быстрее перебора коллекции в коде 1С.
  3. Приоритет. Порядок добавления элементов в УсловноеОформление важен. Если значение одновременно является и минимумом, и максимумом (например, в таблице одна строка), применится то оформление, которое находится ниже в списке.

Используя второй метод, вы получаете чистое, оптимизированное решение, которое соответствует стандартам разработки на платформе 1С:Предприятие 8.3.

← На главную