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

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

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

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

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

Способ 1. Использование системного приоритета типов (без создания колонок)

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

  1. NULL (самый низший приоритет)
  2. Неопределено
  3. Булево
  4. Число
  5. Дата
  6. Строка
  7. Ссылочные типы (самый высокий приоритет)

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

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

Отсюда рождается элегантное и простое условие для условного оформления:

ИмяВашегоПоля < Справочник.ИмяСправочника.ПустаяСсылка

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

Чтобы настроить это решение визуально в конфигураторе, выполните следующие шаги:

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

Важное ограничение метода: Если в вашей колонке составного типа помимо строк и ссылок могут также находиться Числа или Даты, они тоже имеют более низкий приоритет, чем ссылки, и система окрасит их как строки. Если ваш тип строго ограничен только строками и ссылками одного справочника — этот метод идеален.

Способ 2. Проверка заполненности системных реквизитов ссылки

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

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

Давайте настроим отбор по следующему принципу:

  1. В условном оформлении добавьте условие отбора.
  2. В качестве левого значения выберите поле через точку: ИмяВашегоПоля.ВерсияДанных (или ИмяВашегоПоля.Код, если у справочника точно включены коды).
  3. Вид сравнения установите в значение «Не заполнено».

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

Способ 3. Использование вспомогательного реквизита формы (классический подход)

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

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

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

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

Рассмотрим пример программной реализации в модуле формы:


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

&НаКлиенте
Процедура НашаТабличнаяЧастьПриИзменении(Элемент)
    
    // Получаем текущую строку, в которой пользователь изменил данные
    ТекущиеДанные = Элементы.НашаТабличнаяЧасть.ТекущиеДанные;
    Если ТекущиеДанные <> Неопределено Тогда
        // Быстро обновляем флаг для измененной строки
        ТекущиеДанные.ЭтоСтроковоеЗначение = ПроверитьЯвляетсяЛиСтрокой(ТекущиеДанные.ЗначениеКолонки);
    КонецЕсли;
    
КонецПроцедуры

&НаКлиенте
Функция ПроверитьЯвляетсяЛиСтрокой(Значение)
    Возврат ТипЗнч(Значение) = Тип("Строка");
КонецФункции

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

Способ 4. Программное создание условного оформления

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

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


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

    // 1. Создаем новый элемент условного оформления
    ЭлементОформления = УсловноеОформление.Elements.Добавить();

    // 2. Указываем, как именно мы хотим выделить ячейку (задаем светло-желтый цвет фона)
    ЭлементОформления.Оформление.УстановитьЗначениеПараметра("ЦветФона", WebЦвета.СветлоЖелтый);

    // 3. Указываем поле, к которому будет применяться наше оформление
    ОформляемоеПоле = ЭлементОформления.Поля.Элементы.Добавить();
    ОформляемоеПоле.Поле = Новый ПолеКомпоновкиДанных("НашаТабличнаяЧастьКолонкаЗначение");

    // 4. Формируем условие: НашаТабличнаяЧасть.КолонкаЗначение < ПустаяСсылкаНоменклатуры
    ЭлементОтбора = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
    ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Объект.НашаТабличнаяЧасть.КолонкаЗначение");
    ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Меньше;
    
    // В качестве правого значения передаем пустую ссылку справочника Номенклатура
    ЭлементОтбора.ПравоеЗначение = Справочники.Номенклатура.ПустаяСсылка(); 

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

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

Выбирайте наиболее подходящий для вашей задачи метод: быстрый и хитрый способ с приоритетом типов или надежный классический вариант со вспомогательным реквизитом формы!

← На главную