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

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

При разработке интерфейсов на управляемых формах 1С часто возникает задача визуально выделить строки в списке — например, покрасить заказы в зависимости от их оплаты (удобно через раскраска строк по статусам в списках 1С) или подсветить просроченные накладные. Зачастую разработчики пытаются найти способ сделать это «на клиенте», чтобы не нагружать сервер. Однако архитектура динамического списка в 1С имеет свои особенности, которые диктуют свои правила игры. Чтобы лучше ориентироваться в этих механизмах, полезно изучить приемы построения эффективных интерфейсов, которые учитывают специфику работы с большими таблицами.

Разберем подробно, почему классическая раскраска «в цикле на клиенте» невозможна и какие эффективные инструменты предоставляет платформа для решения этой задачи — для этого подойдёт конструктор адаптивных рабочих столов и интерфейсов.

Почему нельзя просто «покрасить» строку на клиенте

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

По этой причине вы не можете перебрать строки списка в цикле на клиенте и установить им цвет. Любое оформление в 1С 8.3 должно быть дескриптивным: вы описываете правило (условие), а платформа сама применяет его к тем данным, которые попадают в область видимости. Эти правила называются Условным оформлением. Для ускорения процесса разработки подобных интерфейсов часто используются модули для программного изменения форм, позволяющие стандартизировать создание элементов оформления.

Метод 1: Программная установка условного оформления

Самый распространенный и правильный способ — использование механизма условного оформления. Если условия раскраски зависят от данных, которые уже есть в запросе списка (например, «СуммаОплаты» и «СуммаОтгрузки»), мы можем настроить правила программно.

Рассмотрим ситуацию, когда нам нужно подсветить строки в зависимости от логики «Оплачено / Не оплачено». Даже если расчет выполняется программно, мы должны передать это условие в КомпоновщикНастроек динамического списка.

Пример настройки оформления в процедуре ПриСозданииНаСервере:


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

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

Важный нюанс: Если вы меняете настройки оформления динамического списка на клиенте (например, по нажатию кнопки), необходимо обязательно вызвать метод загрузки настроек, чтобы изменения отобразились:


&НаКлиенте
Процедура КомандаСменитьЦвет(Команда)
    // Изменяем настройки в объекте Список.КомпоновщикНастроек.Настройки.УсловноеОформление...
    // ...код добавления элементов УО...
    
    // Применяем настройки
    Список.КомпоновщикНастроек.ЗагрузитьНастройки(Список.КомпоновщикНастроек.Настройки);
КонецПроцедуры

Метод 2: Раскраска по справочнику статусов (Опыт УНФ)

Рассмотрим более сложную ситуацию, когда цвета не зашиты в коде, а хранятся в базе данных (например, в справочнике «Состояния заказов»). В конфигурации «Управление нашей фирмой» (УНФ) реализован интересный механизм: для каждого элемента справочника состояний динамически создается свое правило условного оформления. Помимо цвета, для наглядности можно выводить состояние объектов на форме в виде специальных значков и иконок.

Проанализируем этот алгоритм:

  1. Программа обходит выборку из справочника статусов.
  2. Для каждого статуса, у которого задан цвет, создается отдельный элемент УсловноеОформление.
  3. В условии отбора указывается конкретная ссылка на статус.

Пример реализации такой логики:


&НаСервере
Процедура УстановитьОформлениеПоСтатусам()
    
    Выборка = Справочники.СостоянияЗаказов.Выбрать();
    Пока Выборка.Следующий() Цикл
        
        Цвет = Выборка.Цвет.Получить(); // Предположим, цвет хранится в ХранилищеЗначений
        Если ТипЗнч(Цвет) <> Тип("Цвет") Тогда
            Продолжить;
        КонецЕсли;
        
        ЭлементУО = Список.КомпоновщикНастроек.Настройки.УсловноеОформление.Элементы.Добавить();
        ЭлементУО.Оформление.УстановитьЗначениеПараметра("ЦветТекста", Цвет);
        
        ЭлементОтбора = ЭлементУО.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
        ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Состояние");
        ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
        ЭлементОтбора.ПравоеЗначение = Выборка.Ссылка;
        
    КонецЦикла;

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

Многие опасаются, что создание 20-30 правил оформления приведет к «невообразимому» на сервере. На практике платформа оптимизирована для работы с таким количеством условий, и это является стандартным механизмом для гибких интерфейсов.

Метод 3: Обработчик ПриПолученииДанныхНаСервере

Если условие раскраски настолько сложное, что его невозможно описать обычным отбором компоновки (например, нужно рассчитать остатки по сложному алгоритму или обратиться к внешним данным), следует использовать событие ПриПолученииДанныхНаСервере. Аналогичным образом решаются и другие задачи интерфейса, например, когда требуется реализовать интерактивный флажок в динамическом списке.

Этот обработчик вызывается платформой, когда она подготовила порцию строк для отображения на экране. Мы можем вмешаться в этот процесс и «докрасить» строки.

Разберем, как это работает:

Критически важно: Внутри этого обработчика нельзя выполнять запросы в цикле! Это приведет к катастрофическому падению производительности при прокрутке списка. Правильная методика выглядит так:

  1. Собрать все ссылки из порции строк в массив.
  2. Выполнить один запрос к базе данных для получения всех необходимых параметров для раскраски.
  3. Результат запроса поместить в Соответствие или ТаблицуЗначений.
  4. В цикле по строикам просто прочитать готовое значение и установить цвет.

&НаСервере
Процедура СписокПриПолученииДанныхНаСервере(ИмяЭлемента, НастройкиКомпоновки, Строки)
    
    // Пример изменения оформления для каждой строки из порции
    Для Каждого СтрокаСписка Из Строки Цикл
        
        // Получаем данные текущей строки
        ДанныеСтроки = СтрокаСписка.Значение.Данные;
        
        // Если логика вычислений пройдена
        Если ДанныеСтроки.Сумма > 100000 Тогда
             // Устанавливаем оформление через коллекцию Оформление
             СтрокаСписка.Значение.Оформление["ЦветФона"].Установить(WebЦвета.Золотистый);
        КонецЕсли;
        
    КонецЦикла;
    
КонецПроцедуры

Метод 4: Вычисляемые поля в запросе динамического списка

Рассмотрим ситуацию, когда расчеты можно перенести непосредственно в текст запроса. Это самый производительный метод. Если вам нужно покрасить строку по результату математического вычисления, добавьте это вычисление прямо в ПроизвольныйЗапрос динамического списка. Чтобы упростить работу с объектной моделью запросов и схем, можно использовать СКДБилдер, который делает программный код более лаконичным.

Например, в запросе можно написать:


ВЫБРАТЬ
    Накладная.Ссылка,
    Накладная.СуммаДокумента,
    Накладная.СуммаОплаты,
    ВЫБОР 
        КОГДА Накладная.СуммаОплаты >= Накладная.СуммаДокумента ТОГДА 0 
        ИНАЧЕ 1 
    КОНЕЦ КАК СтатусДолга
ИЗ
    Документ.РеализацияТоваровУслуг КАК Накладная

Теперь в настройках условного оформления вам не нужно строить сложные сравнения полей. Вы просто создаете условие: СтатусДолга Равно 1. Это работает молниеносно, так как расчет выполняет СУБД, а платформа лишь проверяет одно числовое поле.

Резюме и практические советы

Подведем итог нашему анализу:

  1. Вычисления на клиенте невозможны: Из-за виртуализации списка клиент «не знает» о данных строк до момента их отрисовки сервером.
  2. Используйте Условное Оформление: Это стандарт платформы. Его можно настраивать как в конфигураторе, так и программно в коде формы. Для быстрой отладки свойств элементов прямо в режиме пользователя может пригодиться редактор форм в режиме предприятия.
  3. Оптимизируйте запросы: Если раскраска сложная, старайтесь вынести логику в текст запроса динамического списка через поля ВЫБОР...КОГДА.
  4. ПриПолученииДанныхНаСервере — крайний случай: Используйте его только тогда, когда данные нельзя получить одним запросом в динамическом списке (например, сложные итоги или данные из внешних систем).

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

← На главную