Как сохранить выбор цвета в справочнике и раскрасить динамический список

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

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

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

Почему тип «Цвет» недоступен для реквизитов базы данных

Проанализируем ситуацию: тип данных Цвет в 1С может принимать значения из системных стилей (например, «Цвет текста кнопки»), Web-цветов или абсолютных значений RGB (Red, Green, Blue). Поскольку структура этого объекта неоднородна, платформа не может создать для него одну универсальную колонку в таблице SQL. Для решения этой задачи нам необходимо преобразовать объект Цвет в один из типов, которые платформа умеет сохранять в базу: Строка, Число или ХранилищеЗначения.

Способ 1: Сериализация в строку (ЗначениеВСтрокуВнутр)

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

Для начала создадим в справочнике реквизит ЦветФонаСтрокой с типом Строка (длина неограниченна или достаточно большая, например, 100 символов). На самой форме создадим реквизит формы (не путать с реквизитом объекта!) с именем ВыбранныйЦвет и типом Цвет. Именно его мы вынесем на экран для взаимодействия с пользователем.

Разберем программный код для синхронизации этих данных:


&НаСервере
Процедура ПриЧтенииНаСервере(ТекущийОбъект)
    // Извлекаем сохраненный цвет из строки обратно в объект типа Цвет
    Если ЗначениеЗаполнено(ТекущийОбъект.ЦветФонаСтрокой) Тогда
        ЭтаФорма.ВыбранныйЦвет = ЗначениеИзСтрокиВнутр(ТекущийОбъект.ЦветФонаСтрокой);
    КонецЕсли;
КонецПроцедуры

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

Этот метод хорош тем, что он «всеяден»: если пользователь выберет системный цвет или абсолютный RGB, функция ЗначениеВСтрокуВнутр корректно упакует его, а ЗначениеИзСтрокиВнутр — восстановит.

Способ 2: Хранение цвета в виде числа (RGB)

Если нам нужно использовать цвет в запросах или динамических списках с высокой производительностью, лучше использовать числовой формат. Цвет в формате RGB можно представить как одно целое число по формуле: Красный + (Зеленый * 256) + (Синий * 65536). Для удобного визуального подбора таких параметров в интерфейсе отлично подойдет внешняя веб-палитра для выбора цвета в 1С.

Выясним, как это реализовать. Создадим реквизит ЦветЧислом (тип Число, длина 10, точность 0). Для удобства работы пользователя используем стандартный диалог выбора цвета:


&НаКлиенте
Процедура ВыбратьЦвет(Команда)
    Диалог = Новый ДиалогВыбораЦвета;
    // Если в реквизите уже есть данные, попробуем установить их в диалоге
    // (требуется обратная конвертация числа в объект Цвет)
    
    ОписаниеОповещения = Новый ОписаниеОповещения("ПослеВыбораЦвета", ЭтотОбъект);
    Диалог.Показать(ОписаниеОповещения);
КонецПроцедуры

&НаКлиенте
Процедура ПослеВыбораЦвета(ВыбранныйЦвет, ДополнительныеПараметры) Экспорт
    Если ВыбранныйЦвет <> Неопределено Тогда
        // Сохраняем составляющие цвета в число
        Объект.ЦветЧислом = ВыбранныйЦвет.Красный + (ВыбранныйЦвет.Зеленый * 256) + (ВыбранныйЦвет.Синий * 65536);
    КонецЕсли;
КонецПроцедуры

Преимущество данного способа: числовые данные обрабатываются СУБД мгновенно, что критично для больших списков.

Способ 3: Использование «Хранилища значения»

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

Пример записи:


НовыйЦвет = Новый Цвет(255, 0, 0); // Красный
Объект.ДанныеОформления = Новый ХранилищеЗначения(НовыйЦвет);

Пример чтения:


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

Важное замечание: данные из ХранилищаЗначения невозможно получить напрямую в запросе динамического списка. Этот метод подходит только для отображения в карточке элемента.

Применение цвета в динамическом списке (Условное оформление)

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

Рассмотрим пример, когда мы храним идентификатор цвета (число) и хотим применить оформление программно при создании формы:


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

Если цветов много и они произвольные, можно использовать «хитрый» способ из обсуждения: в запросе динамического списка через конструкцию ВЫБОР КОГДА... вычислять индекс цвета, а в условном оформлении заранее подготовить 10-15 стандартных цветовых схем, привязанных к этим индексам.

Подведем итоги

Проанализировав все варианты, мы можем сделать следующие выводы:

  1. Если важна точность передачи цвета (стили, web-цвета) — используйте ЗначениеВСтрокуВнутр и хранение в строковом реквизите.
  2. Если важна скорость работы списков и возможность фильтрации — храните составляющие цвета в числовых реквизитах (RGB) или используйте предопределенные индексы цветов. При необходимости миграции таких данных между неидентичными базами применяется обработка для переноса данных между похожими конфигурациями 1С с сопоставлением по произвольным полям.
  3. Для выбора цвета пользователем всегда применяйте объект ДиалогВыбораЦвета, так как он обеспечивает привычный интерфейс Windows/macOS/Linux.

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

← На главную