В процессе разработки на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с ограничением: реквизиту справочника или документа невозможно напрямую назначить тип Цвет. В то же время в обработках или на формах этот тип доступен. Это связано с тем, что Цвет является сложным объектом оформления, который не имеет прямого соответствия в типах данных СУБД. Однако задача хранения индивидуального цвета для элементов справочника (например, для выделения категорий товаров или статусов заказов в списке) встречается повсеместно.
В данной статье мы разберем, как обойти это ограничение, рассмотрим несколько способов хранения данных о цвете и научимся применять эти данные для оформления динамических списков.
Проанализируем ситуацию: тип данных Цвет в 1С может принимать значения из системных стилей (например, «Цвет текста кнопки»), Web-цветов или абсолютных значений RGB (Red, Green, Blue). Поскольку структура этого объекта неоднородна, платформа не может создать для него одну универсальную колонку в таблице SQL. Для решения этой задачи нам необходимо преобразовать объект Цвет в один из типов, которые платформа умеет сохранять в базу: Строка, Число или ХранилищеЗначения.
Это наиболее надежный способ, так как он позволяет сохранить объект целиком со всеми его свойствами. Рассмотрим реализацию этого метода на управляемой форме справочника.
Для начала создадим в справочнике реквизит ЦветФонаСтрокой с типом Строка (длина неограниченна или достаточно большая, например, 100 символов). На самой форме создадим реквизит формы (не путать с реквизитом объекта!) с именем ВыбранныйЦвет и типом Цвет. Именно его мы вынесем на экран для взаимодействия с пользователем.
Разберем программный код для синхронизации этих данных:
&НаСервере
Процедура ПриЧтенииНаСервере(ТекущийОбъект)
// Извлекаем сохраненный цвет из строки обратно в объект типа Цвет
Если ЗначениеЗаполнено(ТекущийОбъект.ЦветФонаСтрокой) Тогда
ЭтаФорма.ВыбранныйЦвет = ЗначениеИзСтрокиВнутр(ТекущийОбъект.ЦветФонаСтрокой);
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
// Перед сохранением преобразуем объект Цвет в строку внутреннего формата
ТекущийОбъект.ЦветФонаСтрокой = ЗначениеВСтрокуВнутр(ЭтаФорма.ВыбранныйЦвет);
КонецПроцедуры
Этот метод хорош тем, что он «всеяден»: если пользователь выберет системный цвет или абсолютный RGB, функция ЗначениеВСтрокуВнутр корректно упакует его, а ЗначениеИзСтрокиВнутр — восстановит.
Если нам нужно использовать цвет в запросах или динамических списках с высокой производительностью, лучше использовать числовой формат. Цвет в формате RGB можно представить как одно целое число по формуле: Красный + (Зеленый * 256) + (Синий * 65536). Для удобного визуального подбора таких параметров в интерфейсе отлично подойдет внешняя веб-палитра для выбора цвета в 1С.
Выясним, как это реализовать. Создадим реквизит ЦветЧислом (тип Число, длина 10, точность 0). Для удобства работы пользователя используем стандартный диалог выбора цвета:
&НаКлиенте
Процедура ВыбратьЦвет(Команда)
Диалог = Новый ДиалогВыбораЦвета;
// Если в реквизите уже есть данные, попробуем установить их в диалоге
// (требуется обратная конвертация числа в объект Цвет)
ОписаниеОповещения = Новый ОписаниеОповещения("ПослеВыбораЦвета", ЭтотОбъект);
Диалог.Показать(ОписаниеОповещения);
КонецПроцедуры
&НаКлиенте
Процедура ПослеВыбораЦвета(ВыбранныйЦвет, ДополнительныеПараметры) Экспорт
Если ВыбранныйЦвет <> Неопределено Тогда
// Сохраняем составляющие цвета в число
Объект.ЦветЧислом = ВыбранныйЦвет.Красный + (ВыбранныйЦвет.Зеленый * 256) + (ВыбранныйЦвет.Синий * 65536);
КонецЕсли;
КонецПроцедуры
Преимущество данного способа: числовые данные обрабатываются СУБД мгновенно, что критично для больших списков.
Рассмотрим вариант для тех случаев, когда нужно хранить не только цвет, но и другие настройки оформления в одном поле. Тип ХранилищеЗначения позволяет записывать в базу практически любые объекты 1С в бинарном виде.
Пример записи:
НовыйЦвет = Новый Цвет(255, 0, 0); // Красный
Объект.ДанныеОформления = Новый ХранилищеЗначения(НовыйЦвет);
Пример чтения:
СохраненныйЦвет = Объект.ДанныеОформления.Получить();
Если ТипЗнч(СохраненныйЦвет) = Тип("Цвет") Тогда
// Используем полученный цвет
КонецЕсли;
Важное замечание: данные из ХранилищаЗначения невозможно получить напрямую в запросе динамического списка. Этот метод подходит только для отображения в карточке элемента.
Когда мы научились сохранять цвет, разберем, как заставить динамический список «раскрашиваться» в соответствии с этими данными. Оптимальнее всего использовать Условное оформление формы. Чтобы упростить этот процесс и не писать код настроек вручную, можно использовать генератор программного кода условного оформления формы.
Рассмотрим пример, когда мы храним идентификатор цвета (число) и хотим применить оформление программно при создании формы:
&НаСервере
Процедура НастроитьУсловноеОформление()
// Очистим текущие настройки, если нужно
Список.УсловноеОформление.Элементы.Очистить();
// Создаем элемент оформления для красного цвета (код 255)
ЭлементОформления = Список.УсловноеОформление.Элементы.Добавить();
// 1. Что оформляем (Цвет текста или Цвет фона)
ЭлементОформления.Оформление.УстановитьЗначениеПараметра("ЦветФона", WebЦвета.СветлоЛососевый);
// 2. Условие (Когда применять)
ЭлементОтбора = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ЦветИдентификатор");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.ПравоеЗначение = 1; // Например, 1 - это "Критично"
// 3. Поля (Какие колонки красить)
ПолеОформления = ЭлементОформления.Поля.Элементы.Добавить();
ПолеОформления.Поле = Новый ПолеКомпоновкиДанных("Наименование");
КонецПроцедуры
Если цветов много и они произвольные, можно использовать «хитрый» способ из обсуждения: в запросе динамического списка через конструкцию ВЫБОР КОГДА... вычислять индекс цвета, а в условном оформлении заранее подготовить 10-15 стандартных цветовых схем, привязанных к этим индексам.
Проанализировав все варианты, мы можем сделать следующие выводы:
ЗначениеВСтрокуВнутр и хранение в строковом реквизите.ДиалогВыбораЦвета, так как он обеспечивает привычный интерфейс Windows/macOS/Linux.Используя предложенные методики, вы сможете реализовать гибкую систему цветовой индикации в любой конфигурации 1С, сделав интерфейс более интуитивно понятным для конечного пользователя. При тиражировании подобных доработок сразу в несколько информационных систем автоматическое обновление и тестирование баз 1С в фоновом режиме упрощает техническое обслуживание.