Как сохранить цвет в реквизите справочника в 1С?

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

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

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

Ограничения объекта «Цвет» и разложение на RGB

На первый взгляд самым очевидным решением кажется создание трех числовых реквизитов (Красный, Зеленый, Синий) либо упаковка их в одно целое число или строку формата #FFFFFF. Однако при попытке разложить произвольный цвет на составляющие разработчик может столкнуться с неожиданным поведением системы.

Объект Цвет в платформе 1С имеет системное свойство Вид (значение системного перечисления ВидЦвета). Свойства Красный, Зеленый и Синий возвращают корректные числовые значения (от 0 до 255) только тогда, когда цвет является абсолютным (Цвет.Вид = ВидЦвета.Абсолютный). Если пользователь в стандартном диалоге выбрал цвет из палитры веб-цветов, системных стилей оформления или цветов Windows (например, ВидЦвета.WebЦвет или ВидЦвета.WindowsЦвет), свойства каналов вернут значение -1. Любая математическая формула расчета числового кода с такими значениями выдаст ошибку или некорректный результат.

Поэтому выбор способа хранения напрямую зависит от того, разрешено ли пользователю выбирать любые цвета платформы или выбор строго ограничен абсолютными значениями RGB.

Способ 1. Упаковка абсолютного цвета в одно число

Если в системе используются только абсолютные цвета, самым компактным и удобным для выборки в запросах вариантом является хранение цвета в виде одного целого неотрицательного числа (длиной 10 символов, диапазон от 0 до 16 777 215). Это исключает необходимость заводить три отдельных поля в таблице базы данных.

Рассмотрим алгоритм упаковки трех составляющих (Red, Green, Blue) в одно число и обратного восстановления объекта Цвет:


// Преобразование компонент RGB в числовое значение для хранения
Функция ПолучитьЗначениеХраненияЦвета(Красный, Зеленый, Синий) Экспорт
    Возврат Синий * 256 * 256 + Зеленый * 256 + Красный;
КонецФункции

// Преобразование числового значения обратно в объект Цвет
Функция ПолучитьЦветПоЗначениюХранения(КодЦвета) Экспорт
    Синий = Цел(КодЦвета / (256 * 256));
    Зеленый = Цел((КодЦвета - Синий * 256 * 256) / 256);
    Красный = КодЦвета - Синий * 256 * 256 - Зеленый * 256;
    
    Возврат Новый Цвет(Красный, Зеленый, Синий);
КонецФункции

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

Способ 2. Сериализация в XML через XDTO (универсальный строковый вариант)

Если пользователю разрешено выбирать системные цвета, веб-цвета или цвета стилей оформления, разложение по формуле формул RGB не сработает. Чтобы не использовать избыточный тип ХранилищеЗначения, наилучшим решением будет использование механизма XDTO-сериализации в строковый реквизит (длиной 100–150 символов).

Платформа «1С:Предприятие» умеет полностью сериализовать объект Цвет в компактную XML-строку, сохраняя информацию о его виде и свойствах. Разберем реализацию функций сериализации и десериализации:


// Преобразует объект Цвет в XML-строку
Функция ЦветВСтрокуXML(Знач ВыбранныйЦвет) Экспорт
    Если ВыбранныйЦвет = Неопределено Тогда
        Возврат "";
    КонецЕсли;
    
    Запись = Новый ЗаписьXML;
    Запись.УстановитьСтроку();
    СериализаторXDTO.ЗаписатьXML(Запись, ВыбранныйЦвет);
    Возврат Запись.Закрыть();
КонецФункции

// Восстанавливает объект Цвет из XML-строки
Функция ЦветИзСтрокиXML(Знач СтрокаXML) Экспорт
    Если ПустаяСтрока(СтрокаXML) Тогда
        Возврат Новый Цвет();
    КонецЕсли;
    
    Чтение = Новый ЧтениеXML;
    Чтение.УстановитьСтроку(СтрокаXML);
    Возврат СериализаторXDTO.ПрочитатьXML(Чтение);
КонецФункции

Преимущества сериализации через XDTO:

  1. Корректно сохраняются абсолютно любые виды цветов: абсолютные, веб-цвета, стили интерфейса.
  2. Реквизит базы данных остается обычной строкой. В отличие от ХранилищаЗначения, строковые поля не выносятся СУБД в отдельные таблицы для BLOB-данных, не создают накладных расходов на распаковку архива и доступны для анализа.
  3. Это платформенный стандарт сериализации, в отличие от устаревших методов вроде ЗначениеВСтрокуВнутр().

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

Классический подход для хранения сложных объектов — создание реквизита с типом ХранилищеЗначения. В него объект Цвет помещается целиком с помощью конструктора Новый ХранилищеЗначения(ВыбранныйЦвет).

Этот метод гарантирует стопроцентное сохранение структуры объекта, однако обладает существенным недостатком: поле таблицы базы данных невозможно быстро получить через простой запрос вместе с остальными реквизитами без считывания тяжелых данных, а само значение нельзя прочитать без инициализации объекта на сервере методом Получить().

Организация выбора цвета на управляемой форме

Для реализации удобного интерфейса пользователя настроим управляемую форму элемента справочника по следующим шагам:

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

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

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

Применение сохраненного цвета в отчетах

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

Для динамической раскраски отчета применяют программную настройку в событии ПриКомпоновкеРезультата модуля отчета или формы. Перед выводом отчета считываются ссылки на элементы справочника вместе с их сохраненными цветами, после чего программно заполняется коллекция КомпоновщикНастроек.Настройки.УсловноеОформление, где для каждой ссылки создается элемент оформления с соответствующим объектом Цвет в качестве цвета фона или текста.

← На главную