В платформе 1С:Предприятие 8 отсутствует возможность напрямую выбрать тип Цвет для реквизита справочника или документа. Это создает определенные трудности при разработке интерфейсов, где требуется кастомизация (например, цветовая маркировка статусов заказов или категорий товаров). Однако, используя гибкость платформы, мы можем реализовать этот функционал несколькими способами. В этой статье мы подробно разберем, как организовать хранение цвета и удобный выбор для пользователя в управляемом приложении.
Прежде всего, выясним причину, по которой типа Цвет нет в списке доступных типов реквизитов. Объект Цвет в 1С является сложным типом, который может принимать значения разных видов: абсолютный (RGB), цвет стиля или системный цвет Windows. Поскольку база данных должна хранить простые типы, нам необходимо преобразовать цвет в строку, число или бинарные данные.
Рассмотрим основные варианты хранения данных:
Это самый популярный метод. Мы создаем реквизит справочника с типом Строка (длиной 7-15 символов). Разберем по шагам, как реализовать сохранение и восстановление цвета из RGB-компонентов.
Для преобразования цвета в строку и обратно проанализируем следующий код:
// Преобразование цвета в строку формата "R,G,B"
Функция ЦветВСтроку(ВыбранныйЦвет) Экспорт
Если ВыбранныйЦвет.Вид = ВидЦвета.Абсолютный Тогда
Возврат СтрШаблон("%1,%2,%3", ВыбранныйЦвет.Красный, ВыбранныйЦвет.Зеленый, ВыбранныйЦвет.Синий);
Иначе
// Для неабсолютных цветов можно хранить их строковое представление
Возврат Строка(ВыбранныйЦвет);
КонецЕсли;
КонецФункции
// Восстановление цвета из строки
Функция СтрокаВЦвет(СтрЦвет) Экспорт
Части = СтрРазделить(СтрЦвет, ",");
Если Части.Количество() = 3 Тогда
Возврат Новый Цвет(Число(Части[0]), Число(Части[1]), Число(Части[2]));
КонецЕсли;
Возврат ЦветаСтиля.ТекстИнформационнойНадписи; // Значение по умолчанию
КонецФункции
Преимущество этого метода заключается в том, что данные легко просматривать через консоль запросов, а также просто использовать в веб-клиенте или при интеграции с внешними системами.
Если нам нужно сохранить не только RGB, но и вид цвета (например, чтобы сохранить связь с ЦветаСтиля), лучше использовать сериализацию. Рассмотрим пример записи и чтения:
// Сериализация цвета в XML-строку
ЗаписьXML = Новый ЗаписьXML();
ЗаписьXML.УстановитьСтроку();
СериализаторXDTO.ЗаписатьXML(ЗаписьXML, МойЦвет);
СтрокаСЦветом = ЗаписьXML.Закрыть();
// Десериализация из XML-строки
ЧтениеXML = Новый ЧтениеXML();
ЧтениеXML.УстановитьСтроку(СтрокаСЦветом);
МойЦвет = СериализаторXDTO.ПрочитатьXML(ЧтениеXML);
Этот метод гарантирует, что после восстановления объект Цвет будет идентичен исходному, включая его метаданные.
В типовых конфигурациях, таких как 1С:Управление торговлей 11 или ERP 2, часто используется тип ХранилищеЗначения. Это позволяет хранить мутабельные объекты напрямую. Выясним, как это работает в справочнике "Приоритеты":
ЦветХранилище с типом ХранилищеЗначения.ВыбранныйЦвет с типом Цвет.ПриЧтенииНаСервере извлекаем значение:
ЗначениеЦвета = ИзОбъекта.ЦветХранилище.Получить();
Если ТипЗнч(ЗначениеЦвета) = Тип("Цвет") Тогда
ВыбранныйЦвет = ЗначениеЦвета;
КонецЕсли;
ПередЗаписьюНаСервере помещаем значение обратно:
ДляОбъекта.ЦветХранилище = Новый ХранилищеЗначения(ВыбранныйЦвет);
Проанализируем ситуацию: на форме нам нужно поле, при нажатии на которое открывается стандартная палитра 1С. Поскольку реквизита с типом Цвет в объекте нет, мы используем Реквизит формы.
Разберем алгоритм создания удобного интерфейса:
ЦветРеквизит с типом Цвет.ДиалогВыбораЦвета.Рассмотрим пример программного вызова диалога:
&НаКлиенте
Процедура ВыбратьЦвет(Команда)
Диалог = Новый ДиалогВыбораЦвета;
Диалог.Цвет = Объект.ТекущийЦвет; // Предварительно подгруженный цвет
ОписаниеОповещения = Новый ОписаниеОповещения("ПослеВыбораЦвета", ЭтотОбъект);
Диалог.Показать(ОписаниеОповещения);
КонецПроцедуры
&НаКлиенте
Процедура ПослеВыбораЦвета(ВыбранныйЦвет, ДополнительныеПараметры) Экспорт
Если ВыбранныйЦвет <> Неопределено Тогда
ЭтаФорма.ЦветРеквизит = ВыбранныйЦвет;
// Здесь можно вызвать оповещение о модифицированности данных
ЭтаФорма.Модифицированность = Истина;
КонецЕсли;
КонецПроцедуры
Просто сохранить цвет недостаточно — пользователь должен видеть его в списке справочника. Для этого в управляемых формах используется Условное оформление. Выясним, как раскрасить ячейку динамического списка на основе сохраненного значения.
Если цвет хранится в виде строки RGB или HEX, мы можем программно добавить правило оформления при создании формы:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Предположим, у нас есть список с колонкой "ЦветСтрокой"
// Пройдемся по данным и установим оформление (для фиксированных наборов)
// Или используем вычисляемые поля в СКД для динамических списков
ЭлементОформления = Список.УсловноеОформление.Элементы.Добавить();
ЭлементОформления.Оформление.УстановитьЗначениеПараметра("ЦветФона", Новый Цвет(255, 0, 0)); // Пример
ПолеОформления = ЭлементОформления.Поля.Элементы.Добавить();
ПолеОформления.Поле = Новый ПолеКомпоновкиДанных("Наименование");
ОтборОформления = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ОтборОформления.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Статус");
ОтборОформления.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ОтборОформления.ПравоеЗначение = "Критичный";
КонецПроцедуры
Для произвольных цветов, выбранных пользователем, рекомендуется использовать событие ПриВыводеДанных (в обычных формах) или, что более правильно для УФ, хранить цвет как число и использовать его в оформлении через программную генерацию элементов УсловноеОформление динамического списка.
Для решения задачи "хранения цвета" в 1С 8.3 наиболее сбалансированным является комбинированный подход:
Строка (для простоты) или ХранилищеЗначения (для сохранения системных цветов).Цвет, который синхронизируем с основным реквизитом объекта при открытии и записи.Использование СериализаторXDTO также является отличным современным способом, который позволяет избежать проблем с потерей типа цвета при передаче между клиентом и сервером. Выбор конкретного метода зависит от требований к производительности и необходимости интеграции с другими подсистемами.