Разработка и Конфигурация · 12 мин
Как хранить цвет в 1С: практическое руководство
Разбираем, как хранить цвет в 1С: системное перечисление, строка HEX, число, хранилище значения. Примеры кода, сравнение вариантов, типичные ошибки и FAQ.
Задача хранения цвета возникает в 1С чаще, чем кажется: подсветка строк в списках, цветовая маркировка статусов заказов, настройки оформления для пользователей, категории товаров с цветовой индикацией. Проблема в том, что встроенного примитивного типа «цвет» для реквизитов объектов конфигурации нет — тип Цвет существует только во встроенном языке и не может быть напрямую сохранён в базе данных.
Поэтому разработчику приходится выбирать способ сериализации: сохранять цвет как строку, число, ссылку на системное перечисление или сериализованный объект. У каждого варианта есть свои ограничения по читаемости, редактируемости и совместимости с веб-клиентом. Ниже разобраны основные подходы с примерами кода и критериями выбора.
Материал ориентирован на платформу 1С:Предприятие 8.3 с управляемыми формами. Отдельно рассмотрены нюансы тонкого и веб-клиента, где поддержка цветов отличается от толстого клиента.
Почему цвет нельзя сохранить «как есть»
Тип Цвет — это объект встроенного языка, существующий только в оперативной памяти сеанса. При попытке назначить реквизиту справочника или документа тип «Цвет» вы обнаружите, что его нет в списке доступных типов конфигуратора. Платформа поддерживает для реквизитов примитивные типы (строка, число, дата, булево), ссылки, хранилище значения и некоторые служебные типы — цвета среди них нет.
Объект Цвет создаётся тремя способами: конструктором с компонентами RGB (Новый Цвет(255, 0, 0)), выбором из системного перечисления WebЦвета или WindowsЦвета, либо как элемент стиля (ЦветаСтиля.ЦветТекстаПоля). Все эти представления нужно преобразовать в сериализуемый вид перед записью в базу и восстановить обратно при чтении.
Важно понимать, что компоненты RGB объекта Цвет доступны только для чтения через свойства Красный, Зеленый, Синий — и только если цвет задан явно, а не является «авто» (значение ВидЦвета.АвтоЦвет). У авто-цвета компоненты равны -1, и его сериализация требует отдельной обработки.
Способ 1: хранение цвета строкой в формате HEX
Самый распространённый и удобный подход — хранить цвет как строку из 7 символов в формате #RRGGBB, например #FF8800. Создайте реквизит типа Строка(7) в справочнике или документе, и пользователь сможет видеть и даже редактировать значение вручную.
Запись цвета в строку выполняется преобразованием каждого компонента в шестнадцатеричное представление:
Функция ЦветВСтрокуHEX(Цвет)
Если Цвет.Вид = ВидЦвета.АвтоЦвет Тогда
Возврат "";
КонецЕсли;
Возврат "#"
+ Прав("0" + DecToHex(Цвет.Красный), 2)
+ Прав("0" + DecToHex(Цвет.Зеленый), 2)
+ Прав("0" + DecToHex(Цвет.Синий), 2);
КонецФункции
Обратное преобразование — разбор строки и создание объекта Цвет. Здесь важно проверять корректность входных данных, чтобы пользовательская опечатка не вызывала исключение:
Функция ЦветИзСтрокиHEX(СтрокаHEX)
Если СтрДлина(СтрокаHEX) <> 7
Или Лев(СтрокаHEX, 1) <> "#" Тогда
Возврат Новый Цвет(); // авто-цвет
КонецЕсли;
К = HexToDec(Сред(СтрокаHEX, 2, 2));
З = HexToDec(Сред(СтрокаHEX, 4, 2));
С = HexToDec(Сред(СтрокаHEX, 6, 2));
Возврат Новый Цвет(К, З, С);
КонецФункции
Функции DecToHex и HexToDec во встроенном языке отсутствуют — их придётся реализовать самостоятельно через цикл деления на 16 или через Формат() с шаблоном. Это стандартная задача, готовые реализации есть в типовых общих модулях работы со строками.
Способ 2: хранение цвета числом
Альтернатива строке — упаковка трёх компонентов RGB в одно целое число. Классическая формула: ЧислоЦвета = Красный + Зеленый 256 + Синий 65536. Реквизит типа Число(10, 0) вмещает любой цвет, а распаковка выполняется целочисленным делением и остатком:
Функция ЦветИзЧисла(ЧислоЦвета)
К = ЧислоЦвета % 256;
З = Цел(ЧислоЦвета / 256) % 256;
С = Цел(ЧислоЦвета / 65536);
Возврат Новый Цвет(К, З, С);
КонецФункции
Числовой формат экономит несколько байт на запись и удобен для сравнений, но совершенно нечитаем для пользователя: число 16711680 ничего не говорит о том, что это красный цвет. Используйте его, когда цвет хранится в служебных регистрах и никогда не показывается человеку как значение.
Дополнительный недостаток — невозможность отличить чёрный цвет (число 0) от незаполненного значения. Если это критично, храните отдельный признак «цвет задан» или используйте значение -1 как маркер авто-цвета.
Способ 3: системные перечисления и цвета стиля
Если набор допустимых цветов ограничен и известен заранее (например, 10 цветов для маркировки статусов), рационально хранить не сам цвет, а его символьный код. Создайте собственное перечисление «ЦветаМаркировки» или храните строковое имя цвета из WebЦвета: «Красный», «БледноЗеленый» и так далее.
Восстановление цвета по имени выполняется через вычисление значения перечисления:
Цвет = WebЦвета[ИмяЦвета]; // ИмяЦвета = "Красный"
Для элементов стиля аналогично: ЦветаСтиля[ИмяЭлементаСтиля]. Преимущество подхода — цвет автоматически подстраивается под тему оформления конфигурации, что важно при смене стиля интерфейса. Недостаток — нельзя сохранить произвольный пользовательский цвет, только предопределённый набор.
Сравнение способов хранения цвета
Читаема, редактируема вручную, компактна. Ограничение: нужны функции конвертации, нет поддержки авто-цвета без соглашения.
Минимальный объём, быстрые сравнения. Ограничение: нечитаемо, не отличить чёрный от незаполненного.
Поддержка тем оформления, понятные значения. Ограничение: только предопределённый набор цветов.
Сохраняет объект целиком, включая вид цвета. Ограничение: бинарные данные не видны в запросах и списках, сложнее отладка.
Способ 4: ХранилищеЗначения и сериализация
Реквизит типа ХранилищеЗначения позволяет сохранить в базе произвольный сериализуемый объект. Объект Цвет сериализуется через ЗначениеВСтрокуВнутр или напрямую помещается в хранилище:
// Запись
Объект.ЦветХранилище = Новый ХранилищеЗначения(ВыбранныйЦвет);
// Чтение
СохраненныйЦвет = Объект.ЦветХранилище.Получить();
Если СохраненныйЦвет = Неопределено Тогда
СохраненныйЦвет = Новый Цвет(); // авто
КонецЕсли;
Этот способ единственный корректно сохраняет вид цвета (абсолютный, авто, элемент стиля). Однако содержимое хранилища невозможно увидеть в списке, отфильтровать запросом или сравнить в отчёте — данные лежат в бинарном виде. Применяйте его, когда важна точная реконструкция объекта, а поиск по значению не требуется.
Выбор цвета пользователем на форме
Хранение — половина задачи; пользователю нужен удобный способ указать цвет. В управляемых формах для этого служит диалог выбора цвета, открываемый программно:
&НаКлиенте
Процедура ВыбратьЦвет(Команда)
Диалог = Новый ДиалогВыбораЦвета;
ОписаниеОповещения = Новый ОписаниеОповещения(
"ПослеВыбораЦвета", ЭтотОбъект);
Диалог.Показать(ОписаниеОповещения);
КонецПроцедуры
&НаКлиенте
Процедура ПослеВыбораЦвета(ВыбранныйЦвет, ДопПараметры) Экспорт
Если ВыбранныйЦвет <> Неопределено Тогда
Объект.ЦветHEX = ЦветВСтрокуHEX(ВыбранныйЦвет);
КонецЕсли;
КонецПроцедуры
Для визуализации сохранённого цвета на форме используйте элемент «Поле надписи» или декорацию с программно устанавливаемым ЦветФона. При открытии формы читайте строку HEX, конвертируйте в Цвет и назначайте свойству — пользователь сразу увидит текущее значение.
Ограничения веб-клиента и тонкого клиента
Диалог выбора цвета работает во всех клиентах, но отображение произвольных цветов фона элементов формы в веб-клиенте может отличаться от толстого. Перед внедрением проверьте ключевые формы во всех используемых клиентах. Также помните, что условное оформление динамических списков поддерживает только цвета, заданные в самой настройке оформления, — подставить туда цвет из реквизита строки напрямую нельзя, потребуется программная установка через УсловноеОформление списка на сервере.
- 1Определите, нужен ли произвольный цвет или достаточно фиксированного набора
- 2Для произвольного цвета добавьте строковый реквизит Строка(7) под HEX
- 3Реализуйте функции конвертации Цвет↔HEX в общем модуле
- 4Добавьте на форму кнопку выбора цвета с ДиалогВыбораЦвета и декорацию-предпросмотр
- 5Обработайте авто-цвет и пустое значение при чтении
- 6Проверьте отображение в тонком и веб-клиенте
Применение цвета в списках и отчётах
Типовой сценарий — раскрасить строки динамического списка по цвету из реквизита. Поскольку условное оформление списка настраивается статически, для произвольных цветов используйте событие ПриПолученииДанныхНаСервере (для обычных форм) или программное добавление элементов условного оформления при создании формы — по одному элементу на каждый используемый цвет с отбором по значению реквизита HEX.
В СКД (системе компоновки данных) цвет из данных отчёта можно применить через вычисляемое выражение в настройках условного оформления, но набор цветов там снова ограничен заранее созданными элементами. Практичный компромисс — ограничить палитру маркировки 8–12 цветами и хранить их коды перечислением.
Проверка результата и отладка
После внедрения проверьте полный цикл: выбор цвета в диалоге → запись объекта → закрытие и повторное открытие формы → корректное отображение. Особое внимание уделите граничным случаям: чёрный цвет (#000000), белый (#FFFFFF), отмена выбора в диалоге (возвращается Неопределено), ручной ввод строки с ошибкой.
Для отладки конвертации удобно вывести тестовую таблицу: список известных цветов из WebЦвета, их HEX-представление и обратное преобразование. Если пары совпадают, функции работают корректно. Помните, что регистр букв в HEX не влияет на результат, но для единообразия приводите строку к верхнему регистру при записи.
Как проверить результат
Цвет в предпросмотре совпадает с выбранным
Цвет сброшен или отличается оттенком
Отображается как "не задан", ошибок нет
Исключение при чтении компонентов RGB
Показано понятное сообщение, значение не применено
Вызвано необработанное исключение
Цвета отображаются так же, как в тонком
Цвет фона игнорируется или искажён
Часто задаваемые вопросы
Можно ли хранить цвет в реквизите типа «Строка» без ограничения длины?
Технически да, но это нерационально: неограниченная строка хранится иначе и медленнее участвует в запросах. Для формата #RRGGBB достаточно Строка(7) с фиксированной длиной. Если планируете хранить имя цвета из WebЦвета, заложите 30–50 символов.
Как сохранить цвет с прозрачностью (альфа-канал)?
Объект Цвет в 1С не поддерживает альфа-канал — только RGB. Если прозрачность критична (например, для выгрузки в веб), храните её в отдельном числовом реквизите 0–100 и обрабатывайте на стороне приёмника.
Что выбрать для подсветки статусов документов?
Оптимально собственное перечисление или строковый код цвета с заранее настроенными элементами условного оформления списка. Произвольный HEX-цвет из реквизита в условное оформление динамического списка напрямую не подставить — придётся генерировать элементы оформления программно на каждый цвет.
Сработает ли ХранилищеЗначения на разных версиях платформы?
Само хранилище стабильно, но если вы сериализуете объект через ЗначениеВСтрокуВнутр и сохраняете как строку, формат может не прочитаться после смены версии платформы. Для данных с длинным сроком жизни надёжнее открытые форматы — HEX или упакованное число.
Как дать пользователю выбор цвета без программирования формы?
Если форма генерируется автоматически, добавьте реквизит с типом, связанным с перечислением цветов, или строковый реквизит с кнопкой выбора из предложенного списка значений. Полноценный ДиалогВыбораЦвета без кода на форме вызвать нельзя.
Влияет ли способ хранения цвета на производительность?
Для типовых объёмов разница ничтожна. Число и короткая строка сопоставимы по скорости; ХранилищеЗначения медленнее при массовом чтении, так как требует десериализации каждой записи. Выбирайте формат по удобству поддержки, а не по скорости.
Что важно запомнить
Типа «Цвет» для реквизитов базы не существует — цвет всегда сериализуется. Для большинства задач используйте строку HEX с функциями конвертации; для фиксированной палитры — перечисление или имена WebЦвета; ХранилищеЗначения оставьте для случаев, где нужна точная реконструкция объекта. Всегда обрабатывайте авто-цвет и проверяйте отображение во всех используемых клиентах.