Где и как правильно хранить цвет в 1С v8.3: лучшие практики и разбор методов

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

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

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

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


Выясняем причину: почему обычное число не подходит?

Объект Цвет в платформе 1С — это не просто абстрактная тройка чисел или шестнадцатеричный код. Это комплексный системный объект, который может иметь совершенно разные виды происхождения. Всего в платформе существует четыре вида цвета:

  1. Абсолютный цвет — классический цвет, задаваемый тремя составляющими шкалы RGB (Красный, Зеленый, Синий) в диапазоне от 0 до 255.
  2. Web-цвет — предопределенные цвета, стандартизированные для веб-браузеров (например, WebЦвета.Аквамарин).
  3. Элемент стиля — цвет, жестко привязанный к текущему оформлению конфигурации (например, ЦветаСтиля.ЦветФонаКнопки).
  4. Windows-цвет — системные цвета операционной системы.

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


Способ №1: Хранение в виде строки формата RGB (Ручной парсинг)

Один из самых простых и понятных способов — сериализация цвета в строковый формат с разделителями (например, "R;G;B" или "Вид;R;G;B"). Этот метод удобен тем, что строковое поле в справочнике легко прочитать при отладке, оно занимает мало места и не нагружает базу данных тяжелыми бинарными объектами.

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

При изменении элемента цвета на форме мы преобразуем его свойства в форматированную строку:


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

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


&НаСервере
Функция ПолучитьМассивИзСтроки(Знач ВходнаяСтрока, Разделитель = ";")
    
    Результат = Новый Массив;
    ТекущаяСтрока = СокрЛП(ВходнаяСтрока);
    
    ПозРазделителя = СтрНайти(ТекущаяСтрока, Разделитель);
    Пока ПозРазделителя > 0 Цикл
        Значение = Лев(ТекущаяСтрока, ПозРазделителя - 1);
        Результат.Добавить(СокрЛП(Значение));
        ТекущаяСтрока = Сред(ТекущаяСтрока, ПозРазделителя + СтрДлина(Разделитель));
        ПозРазделителя = СтрНайти(ТекущаяСтрока, Разделитель);
    КонецЦикла;
    
    Если Не ПустаяСтрока(ТекущаяСтрока) Тогда
        Результат.Добавить(СокрЛП(ТекущаяСтрока));
    КонецЕсли;
    
    Возврат Результат;
    
КонецФункции

Теперь мы можем легко инициализировать объект цвета на сервере, прочитав его из строкового реквизита справочника:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    Если Не ПустаяСтрока(Объект.СтрокаЦвета) Тогда
        
        ПараметрыЦвета = ПолучитьМассивИзСтроки(Объект.СтрокаЦвета, ";");
        
        // Проверяем корректность структуры и тип цвета
        Если ПараметрыЦвета.Количество() >= 4 И ПараметрыЦвета[0] = "Абсолютный" Тогда
            
            ЦветДляОформления = Новый Цвет(
                Число(ПараметрыЦвета[1]), 
                Число(ПараметрыЦвета[2]), 
                Число(ПараметрыЦвета[3])
            );
            
            // Применяем полученный цвет к декорации или элементу управления
            Элементы.ИндикаторЦвета.ЦветФона = ЦветДляОформления;
            
        КонецЕсли;
        
    КонецЕсли;
    
КонецПроцедуры

Способ №2: Использование системного "Хранилища значения" (Рекомендация БСП)

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

Рассмотрим, как правильно организовать взаимодействие реквизита справочника и элемента управляемой формы. Напрямую вывести реквизит типа ХранилищеЗначения на форму нельзя, поэтому мы создадим на форме вспомогательный реквизит ЦветОформления с типом Цвет.

Процесс сохранения и чтения данных будет выглядеть следующим образом:


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

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

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


Способ №3: Использование системной сериализации через "ЗначениеВСтрокуВнутр"

Для тех ситуаций, когда нет возможности добавлять в метаданные реквизит с типом ХранилищеЗначения (например, если мы работаем в расширении или ограничены структурой существующей базы данных), можно использовать встроенный системный механизм преобразования объектов в специальную внутреннюю JSON/XML строку платформы.

Функции ЗначениеВСтрокуВнутр и ЗначениеИзСтрокиВнутр идеально подходят для сериализации простых объектов прикладного типа, в том числе и цвета.

Посмотрим на пример записи цвета в обычный строковый реквизит неограниченной длины:


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

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

Данный метод гарантирует 100% совместимость при восстановлении и сохраняет тип цвета (абсолютный, веб-цвет или стиль).


Способ №4: Сериализация через XDTO в XML-формат

Современным и более гибким стандартом в экосистеме 1С является сериализация данных через XDTO (XML Data Transfer Objects). Данный метод крайне удобен, если вам необходимо обмениваться сохраненными цветами с внешними информационными системами, передавать настройки оформления через HTTP-сервисы или использовать их в мобильных клиентах.

Рассмотрим, как преобразовать объект Цвет в XML-строку и обратно:


&НаСервере
Функция СериализоватьЦветВ_XML(ОбъектЦвет) Экспорт
    
    ЗаписьXML = Новый ЗаписьXML;
    ЗаписьXML.УстановитьСтроку();
    
    // Записываем структуру объекта Цвет через фабрику XDTO
    СериализаторXDTO.ЗаписатьXML(ЗаписьXML, ОбъектЦвет);
    
    Возврат ЗаписьXML.Закрыть();
    
КонецФункции

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

Важный нюанс: Проблема видов цвета и Темная тема в 1С

Анализируя все вышеописанные методы, необходимо затронуть важнейший аспект современного интерфейса платформы «1С:Предприятие 8.3» — работу с темной темой оформления.

Начиная с современных релизов платформы, пользователи могут динамически переключаться между темным и светлым режимом отображения интерфейса. Если при выборе цвета вы будете использовать жесткую фиксацию RGB составляющих (как в Способе №1), то при переходе на темную тему сохраненные статические цвета могут сделать текст абсолютно нечитаемым (например, темно-синий текст на черном фоне приложения).

Рекомендация экспертов: Для сохранения читаемости интерфейса при использовании кастомизации цвета стремитесь сохранять элементы не в виде жесткого RGB, а в виде ссылок на Элементы стилей. При использовании Способа №2 (ХранилищеЗначений), Способа №3 (ЗначениеВСтрокуВнутр) или Способа №4 (XDTO) платформа сохранит именно привязку к элементу стиля. При изменении темы оформления с дневной на ночную платформа автоматически на лету выполнит гармоничную инверсию или замену цветов стилей, сохранив высокую эргономику вашего интерфейса!

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

← На главную