При разработке интерфейсов на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с задачей индивидуализации интерфейса под требования пользователей. Это может быть выделение цветом строк в динамических списках, маркировка задач по приоритетам в канбан-досках или окрашивание элементов интерактивных отчетов. Для реализации подобного функционала необходимо предоставить пользователю возможность самостоятельно выбрать цвет в диалоговом окне, сохранить его в информационной базе (например, в справочнике), а затем динамически применять этот цвет при открытии форм.
Основная сложность заключается в том, что системное оформление управляемой формы (свойства ЦветФона, ЦветТекста и т.д.) строго требует передачи системного объекта типа Цвет. Если попытаться сохранить цвет в базе данных в виде простого числа (числового представления цвета) или трех раздельных реквизитов (RGB), то при попытке напрямую передать эти данные в оформление формы платформа закономерно выбросит ошибку "Несоответствие типов".
В этой статье мы подробно разберем, почему возникает эта проблема, проанализируем архитектурные особенности объекта Цвет в 1С и изучим 5 надежных практических способов хранения и восстановления цвета с готовыми примерами кода.
Объект Цвет в платформе 1С — это не просто абстрактная тройка чисел или шестнадцатеричный код. Это комплексный системный объект, который может иметь совершенно разные виды происхождения. Всего в платформе существует четыре вида цвета:
WebЦвета.Аквамарин).ЦветаСтиля.ЦветФонаКнопки).Когда вы пытаетесь записать цвет в реквизит с типом Число, вы теряете всю эту метаинформацию. Платформа не умеет автоматически преобразовывать произвольное число в полноценный объект Цвет при назначении его оформлению формы. Следовательно, нам нужен надежный мост-конвертер между базой данных и программным интерфейсом формы.
Один из самых простых и понятных способов — сериализация цвета в строковый формат с разделителями (например, "R;G;B" или "Вид;R;G;B"). Этот метод удобен тем, что строковое поле в справочнике легко прочитать при отладке, оно занимает мало места и не нагружает базу данных тяжелыми бинарными объектами.
Давайте по шагам разберем, как реализовать сохранение выбранного пользователем цвета в строку и его обратную сборку на сервере.
При изменении элемента цвета на форме мы преобразуем его свойства в форматированную строку:
&НаКлиенте
Процедура ЦветПриИзменении(Элемент)
// Получаем выбранный пользователем цвет из элемента формы
ВыбранныйЦвет = Объект.ЦветПользователя;
// Формируем строковое представление в формате: "Вид;Красный;Зеленый;Синий"
Объект.СтрокаЦвета = "" + ВыбранныйЦвет.Вид + ";"
+ Формат(ВыбранныйЦвет.Красный, "ЧЦ=3; ЧН=; ЧВН=") + ";"
+ Формат(ВыбранныйЦвет.Зеленый, "ЧЦ=3; ЧН=; ЧВН=") + ";"
+ Формат(ВыбранныйЦвет.Синий, "ЧЦ=3; ЧН=; ЧВН=");
КонецПроцедуры
Для восстановления цвета при открытии формы на сервере нам потребуется вспомогательная функция, которая разобьет нашу строку обратно в массив составляющих. Рассмотрим пример реализации такой функции:
&НаСервере
Функция ПолучитьМассивИзСтроки(Знач ВходнаяСтрока, Разделитель = ";")
Результат = Новый Массив;
ТекущаяСтрока = СокрЛП(ВходнаяСтрока);
ПозРазделителя = СтрНайти(ТекущаяСтрока, Разделитель);
Пока ПозРазделителя > 0 Цикл
Значение = Лев(ТекущаяСтрока, ПозРазделителя - 1);
Результат.Добавить(СокрЛП(Значение));
ТекущаяСтрока = Сред(ТекущаяСтрока, ПозРазделителя + СтрДлина(Разделитель));
ПозРазделителя = СтрНайти(ТекущаяСтрока, Разделитель);
КонецЦикла;
Если Не ПустаяСтрока(ТекущаяСтрока) Тогда
Результат.Добавить(СокрЛП(ТекущаяСтрока));
КонецЕсли;
Возврат Результат;
КонецФункции
Теперь мы можем легко инициализировать объект цвета на сервере, прочитав его из строкового реквизита справочника:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Не ПустаяСтрока(Объект.СтрокаЦвета) Тогда
ПараметрыЦвета = ПолучитьМассивИзСтроки(Объект.СтрокаЦвета, ";");
// Проверяем корректность структуры и тип цвета
Если ПараметрыЦвета.Количество() >= 4 И ПараметрыЦвета[0] = "Абсолютный" Тогда
ЦветДляОформления = Новый Цвет(
Число(ПараметрыЦвета[1]),
Число(ПараметрыЦвета[2]),
Число(ПараметрыЦвета[3])
);
// Применяем полученный цвет к декорации или элементу управления
Элементы.ИндикаторЦвета.ЦветФона = ЦветДляОформления;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Если вы хотите использовать максимально штатные возможности платформы 1С и не писать собственные парсеры строк, обратите внимание на объект ХранилищеЗначения. Именно этот способ применяется во всех типовых конфигурациях, разработанных на базе 1С:Библиотеки Стандартных Подсистем (БСП). Объект Цвет полностью сериализуем, а значит, платформа способна без труда упаковать его в двоичный формат и сохранить в реквизите типа ХранилищеЗначения.
Рассмотрим, как правильно организовать взаимодействие реквизита справочника и элемента управляемой формы. Напрямую вывести реквизит типа ХранилищеЗначения на форму нельзя, поэтому мы создадим на форме вспомогательный реквизит ЦветОформления с типом Цвет.
Процесс сохранения и чтения данных будет выглядеть следующим образом:
&НаСервере
Процедура ПриЧтенииНаСервере(ТекущийОбъект)
// Извлекаем объект Цвет из двоичных данных хранилища значения
Если ТипЗнч(ТекущийОбъект.ХранилищеЦвета) = Тип("ХранилищеЗначения") Тогда
ЦветОформления = ТекущийОбъект.ХранилищеЦвета.Получить();
Иначе
ЦветОформления = Новый Цвет; // Цвет по умолчанию
EndIf;
КонецПроцедуры
&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
// Упаковываем объект Цвет обратно в ХранилищеЗначения перед записью объекта в базу
ТекущийОбъект.ХранилищеЦвета = Новый ХранилищеЗначения(ЦветОформления);
КонецПроцедуры
Преимущества метода: Платформа берет на себя всю работу по сериализации. Сохраняется исходный вид цвета — если пользователь выберет цвет из предопределенной палитры стилей конфигурации (например, цвет выделения текста), он сохранится именно как ссылка на элемент стиля, а не как жесткие цифры RGB.
Для тех ситуаций, когда нет возможности добавлять в метаданные реквизит с типом ХранилищеЗначения (например, если мы работаем в расширении или ограничены структурой существующей базы данных), можно использовать встроенный системный механизм преобразования объектов в специальную внутреннюю JSON/XML строку платформы.
Функции ЗначениеВСтрокуВнутр и ЗначениеИзСтрокиВнутр идеально подходят для сериализации простых объектов прикладного типа, в том числе и цвета.
Посмотрим на пример записи цвета в обычный строковый реквизит неограниченной длины:
&НаСервере
Процедура СохранитьЦветВСтрокуВнутр(ВыбранныйЦвет)
// Преобразуем объект Цвет в системное строковое представление
Объект.ВнутренняяСтрокаЦвета = ЗначениеВСтрокуВнутр(ВыбранныйЦвет);
КонецПроцедуры
&НаСервере
Функция ВосстановитьЦветИзСтрокиВнутр()
Если ПустаяСтрока(Объект.ВнутренняяСтрокаЦвета) Тогда
Возврат Новый Цвет; // Возвращаем пустой цвет, если запись отсутствует
КонецЕсли;
Попытка
// Восстанавливаем полноценный объект Цвет
Возврат ЗначениеИзСтрокиВнутр(Объект.ВнутренняяСтрокаЦвета);
Исключение
// Обработка непредвиденных ошибок при изменении структуры данных
ЗаписьЖурналаРегистрации("Оформление.Цвет", УровеньЖурналаРегистрации.Ошибка,,,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
Возврат Новый Цвет;
КонецПопытки;
КонецФункции
Данный метод гарантирует 100% совместимость при восстановлении и сохраняет тип цвета (абсолютный, веб-цвет или стиль).
Современным и более гибким стандартом в экосистеме 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С:Предприятие 8.3» — работу с темной темой оформления.
Начиная с современных релизов платформы, пользователи могут динамически переключаться между темным и светлым режимом отображения интерфейса. Если при выборе цвета вы будете использовать жесткую фиксацию RGB составляющих (как в Способе №1), то при переходе на темную тему сохраненные статические цвета могут сделать текст абсолютно нечитаемым (например, темно-синий текст на черном фоне приложения).
Рекомендация экспертов: Для сохранения читаемости интерфейса при использовании кастомизации цвета стремитесь сохранять элементы не в виде жесткого RGB, а в виде ссылок на Элементы стилей. При использовании Способа №2 (ХранилищеЗначений), Способа №3 (ЗначениеВСтрокуВнутр) или Способа №4 (XDTO) платформа сохранит именно привязку к элементу стиля. При изменении темы оформления с дневной на ночную платформа автоматически на лету выполнит гармоничную инверсию или замену цветов стилей, сохранив высокую эргономику вашего интерфейса!
Используйте предложенные методики в зависимости от архитектуры вашего решения, и ваши интерфейсы в 1С всегда будут яркими, отзывчивыми и стабильными в работе!