Как правильно настроить условное оформление в табличной части управляемой формы 1С 8.3?

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

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

В этой статье мы подробно разберем, почему у автора темы не работал цвет фона, как исправить его код с помощью механизма списков значений, а также рассмотрим наиболее надежное и производительное решение этой задачи в соответствии со стандартами разработки фирмы «1С».

Анализ исходной проблемы и поиск причин

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

Автор попытался сделать это в цикле по строкам табличной части внутри процедуры ПриСозданииНаСервере, накладывая индивидуальные отборы на равенство по полю НомерСтроки. Однако оформление не применилось. Выясним, почему так произошло:

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

Решение №1: Быстрое исправление кода через Список Значений

Если нам необходимо решить задачу «в лоб», используя привязку к номерам строк, то правильным подходом будет сбор всех подходящих номеров строк в единую коллекцию и наложение одного-единственного отбора с видом сравнения ВСписке.

Рассмотрим подробнее программную реализацию этого метода. Мы заменим цикл добавления отдельных отборов на предварительное заполнение объекта СписокЗначений, после чего передадим этот список в правое значение элемента отбора компоновки данных.


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

    Запрет = Константы.ЗапретИзменения.Получить();

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

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

Этот вариант полностью работоспособен и решает проблему затыка при инициализации формы. Тем не менее, с точки зрения архитектуры платформы «1С:Предприятие 8», у него есть критический недостаток.

В чем опасность привязки оформления к «НомерСтроки»?

Давайте проанализируем, почему опытные разработчики крайне не рекомендуют завязывать условное оформление на системное поле НомерСтроки:

Решение №2: Использование служебного реквизита (Стандарт «1С»)

Для создания надежного, отказоустойчивого и быстрого интерфейса мы применим золотой стандарт разработки «1С» — **использование скрытого служебного реквизита** табличной части.

Разберем этот изящный метод по шагам:

Шаг 1. Добавление служебного реквизита в метаданные

В конфигураторе откроем свойства нашего документа, перейдем на вкладку «Данные», найдем табличную часть ГрафикВозврата и добавим новый реквизит ТЧ:

Важно: На форму документа выводить эту колонку не нужно — она должна оставаться скрытой от глаз пользователя.

Шаг 2. Заполнение реквизита при загрузке данных на сервере

В модуле формы документа перепишем процедуру заполнения признака блокировки. Мы будем рассчитывать значение флага при создании формы на сервере, записывая результат непосредственно в данные объекта:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Заполняем служебный реквизит на сервере один раз при открытии
    Запрет = Константы.ЗапретИзменения.Получить();
    Для Каждого СтрокаТЧ Из Объект.ГрафикВозврата Цикл
        СтрокаТЧ.БлокировкаРедактирования = (СтрокаТЧ.Месяц < Запрет);
    КонецЦикла;
    
    // Вызываем процедуру инициализации условного оформления
    НастроитьУсловноеОформлениеБлокировки();
    
КонецПроцедуры

Шаг 3. Статическое условное оформление

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


&НаСервере
Процедура НастроитьУсловноеОформлениеБлокировки()

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

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

Почему этот способ превосходит любые другие?

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

Важные нюансы работы с параметрами «ТолькоПросмотр» и «Доступность»

Настраивая условное оформление управляемых форм, важно понимать разницу в поведении параметров оформления:

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

← На главную