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

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

При работе с динамическими списками в 1С:Предприятии часто возникает задача визуально выделить определенные строки в зависимости от значений их реквизитов, особенно если эти реквизиты являются дополнительными и могут быть связаны с другими объектами. Рассмотрим ситуацию, когда нам необходимо покрасить строки в списке справочника "Номенклатура", у которых дополнительный реквизит "Неликвид" установлен в значение "Истина". Эта задача может быть решена несколькими способами: с помощью программного кода в обработчиках событий, а также без кода, используя стандартные средства платформы.

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

1. Программное условное оформление в обработчике события динамического списка «ПриПолученииДанныхНаСервере»

Один из самых гибких и мощных способов управления оформлением строк в динамическом списке — это использование серверного обработчика события ПриПолученииДанныхНаСервере или ПриПолученииДанныхНаСервереПосле. Этот обработчик позволяет нам получить доступ к данным, которые будут отображаться в списке, и программно изменить их оформление перед выводом на форму. Важным преимуществом этого метода является то, что мы можем выполнять сложные проверки и запросы к базе данных для определения условий оформления.

Рассмотрим по шагам, как реализовать этот подход:

  1. Открытие формы списка справочника: Прежде всего, нам нужно открыть форму списка того справочника, где требуется условное оформление. В нашем случае это форма списка справочника "Номенклатура".
  2. Определение обработчика события: В модуле формы списка справочника найдем динамический список, для которого требуется оформление. Затем в свойствах этого динамического списка (или его родительского элемента управления) найдем событие ПриПолученииДанныхНаСервере или ПриПолученииДанныхНаСервереПосле и создадим обработчик. Для данной задачи подойдет событие ПриПолученииДанныхНаСервере.
  3. Реализация логики в обработчике: Внутри обработчика мы будем выполнять следующие действия:
    1. Сбор ссылок на объекты: Сначала мы соберем все ссылки на элементы справочника "Номенклатура", которые находятся в текущем наборе данных, полученных динамическим списком для отображения. Это позволит нам избежать выполнения запроса для каждой строки по отдельности, что значительно улучшит производительность.
    2. Получение значений дополнительных реквизитов: Затем мы выполним один запрос к базе данных, чтобы получить значения дополнительного реквизита "Неликвид" для всех собранных ссылок. Дополнительные реквизиты обычно хранятся в специальных регистрах сведений, таких как РегистрСведений.ЗначенияСвойствОбъектов, а их виды определены в ПланВидовХарактеристик.ДополнительныеРеквизиты.
    3. Применение оформления: После того как мы получим информацию о неликвидности каждой номенклатуры, мы пройдемся по строкам динамического списка и, если номенклатура имеет статус "Неликвид = Истина", применим к соответствующей строке необходимое оформление (например, изменим цвет фона).

Давайте посмотрим на пример кода для реализации этой логики:


&НаСервере
Процедура СписокПриПолученииДанныхНаСервере(ИмяЭлемента, Настройки, Строки)

    // Шаг 1: Собрать все ссылки из текущего набора строк, для которых нужно проверить реквизит
    МассивСсылокНоменклатуры = Новый Массив;
    Для Каждого ЭлементСтроки Из Строки Цикл
        // Проверяем, что ссылка действительно относится к справочнику Номенклатура
        // и не является пустой
        Если ТипЗнч(ЭлементСтроки.Ссылка) = Тип("СправочникСсылка.Номенклатура")
            И НЕ ЭлементСтроки.Ссылка.Пустая() Тогда
            МассивСсылокНоменклатуры.Добавить(ЭлементСтроки.Ссылка);
        КонецЕсли;
    КонецЦикла;

    // Если нет ссылок для обработки, завершаем процедуру
    Если МассивСсылокНоменклатуры.Количество() = 0 Тогда
        Возврат;
    КонецЕсли;

    // Шаг 2: Получить значения дополнительного реквизита "Неликвид" для собранных ссылок
    // Предполагаем, что дополнительный реквизит хранится в регистре сведений
    // "ЗначенияСвойствОбъектов", а его вид свойства определен в "ПланВидовХарактеристик.ДополнительныеРеквизиты"
    Запрос = Новый Запрос;
    Запрос.Текст =
        "ВЫБРАТЬ
        |   ЗначенияСвойствОбъектов.Объект КАК Ссылка,
        |   ЗначенияСвойствОбъектов.Значение КАК Неликвид
        |ИЗ
        |   РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
        |ГДЕ
        |   ЗначенияСвойствОбъектов.Объект В (&МассивСсылок)
        |   И ЗначенияСвойствОбъектов.Свойство = &СвойствоНеликвид";

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

    РезультатЗапроса = Запрос.Выполнить().Выгрузить();

    СоответствиеНеликвидов = Новый Соответствие;
    Для Каждого СтрокаРезультата Из РезультатЗапроса Цикл
        // Проверяем, что значение реквизита истина (если это булево)
        // Если тип реквизита может быть иным, логику проверки нужно скорректировать.
        Если ТипЗнч(СтрокаРезультата.Неликвид) = Тип("Булево") И СтрокаРезультата.Неликвид Тогда
            СоответствиеНеликвидов.Вставить(СтрокаРезультата.Ссылка, Истина);
        КонецЕсли;
    КонецЦикла;

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

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

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

2. Настройка условного оформления с помощью произвольного запроса

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

Рассмотрим по шагам, как это можно сделать:

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

    Пояснения к запросу:

    • Мы используем ЛЕВОЕ СОЕДИНЕНИЕ с виртуальной таблицей РегистрСведений.ЗначенияСвойствОбъектов.СрезПоследних, чтобы получить актуальное значение дополнительного реквизита.
    • В условии соединения (после ПО) мы указываем, что поле Объект регистра должно соответствовать Ссылке номенклатуры.
    • В условии фильтрации виртуальной таблицы (после первой запятой в скобках СрезПоследних()) мы указываем, что нас интересует только то значение, у которого Свойство равно предопределенному параметру &ВидСвойстваНеликвид. Этот параметр нужно будет установить при формировании динамического списка (см. следующий шаг).
    • Функция ЕСТЬNULL(..., ЛОЖЬ) используется для того, чтобы в случае отсутствия записи о дополнительном реквизите для данной номенклатуры, поле Неликвид принимало значение "Ложь" (по умолчанию, номенклатура не является неликвидной).
  4. Настройка параметров запроса: В свойствах динамического списка, на закладке "Параметры" или "Настройки", вам потребуется установить значение параметра &ВидСвойстваНеликвид. Это должна быть ссылка на элемент плана видов характеристик "ДополнительныеРеквизиты", который соответствует вашему дополнительному реквизиту "Неликвид". Вы можете найти этот элемент по наименованию или по его уникальному идентификатору.
  5. Настройка условного оформления: После того как поле Неликвид будет доступно в данных динамического списка, вы можете настроить условное оформление:
    1. В режиме 1С:Предприятие (для конкретного пользователя): Пользователь может самостоятельно открыть динамический список, выбрать меню "Ещё" -> "Настроить список", перейти на вкладку "Условное оформление" и добавить новое правило. В качестве условия указывается Неликвид = Истина, а в качестве оформляемых полей и параметров - желаемый цвет фона.
    2. В режиме Конфигуратора (для всех пользователей): Разработчик может задать это оформление по умолчанию. В форме списка, в свойствах динамического списка перейдите к "Настройки списка" -> "Условное оформление". Здесь процесс аналогичен пользовательскому режиму: добавьте элемент оформления, укажите условие Неликвид = Истина и выберите параметры оформления.

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

3. Программная установка условного оформления через КомпоновщикНастроек

Альтернативным способом программного создания условного оформления является использование объекта КомпоновщикНастроек динамического списка. Этот подход позволяет сформировать правила условного оформления аналогично тому, как это делается в визуальном редакторе, но программно. Обычно это делается в процедуре ПриСозданииНаСервере формы, что позволяет применить оформление один раз при открытии формы.

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

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

Особые моменты и рекомендации, которые следует учитывать

  1. Производительность:
    • Использование произвольных запросов для включения дополнительных реквизитов может повлиять на производительность, особенно если таблицы имеют большой объем или соединения сложны. Всегда анализируйте запрос с помощью конструктора запросов и плана выполнения.
    • Интенсивное использование обработчика ПриПолученииДанныхНаСервере для сложных вычислений или множественных запросов внутри цикла также может замедлить отображение списка. Мы специально показали пример с кэшированием данных в Соответствие, чтобы минимизировать количество обращений к базе данных.
  2. Доступность реквизита:
    • Для успешного применения условного оформления (как программно, так и стандартными средствами), дополнительный реквизит должен быть "доступен" в данных динамического списка. Если динамический список основан не на самом справочнике "Номенклатура", а, например, на документе, в котором есть ссылка на номенклатуру, вам может потребоваться модификация запроса динамического списка для получения дополнительного реквизита через связанные таблицы (как в примере произвольного запроса).
    • Убедитесь, что дополнительные реквизиты корректно настроены в конфигурации и имеются данные для проверки.
  3. Согласованность данных:
    • Если логика оформления зависит от данных, которые могут часто меняться, убедитесь, что обновление оформления происходит своевременно (например, после изменения реквизита на форме элемента).
    • При изменении внешнего вида полей, по которым пользователь может выполнять сортировку, отбор или группировку, убедитесь, что это не приводит к путанице или неожиданным результатам.
  4. Универсальность:
    • Предложенный код для ПриПолученииДанныхНаСервере можно адаптировать для других справочников или документов, изменив тип ссылки и имя дополнительного реквизита.
    • Для универсальности можно создать общую функцию, которая будет принимать параметры (имя справочника, имя доп. реквизита, условие) и возвращать готовые правила оформления.

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

← На главную