Как сохранить и редактировать цвет в ресурсе регистра сведений через ХранилищеЗначения

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

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

Проблема использования типа Цвет и Хранилища значений

Основная сложность заключается в том, что реквизит с типом ХранилищеЗначения нельзя просто вынести на управляемую форму. Кроме того, объект типа Цвет в 1С бывает трех видов: абсолютный (RGB), Web-цвет и цвет стиля. Если мы попытаемся хранить цвет просто как строку с RGB-компонентами, то при выборе цвета из системного стиля (например, "Цвет текста кнопки") платформа вернет значения "-1" для красного, зеленого и синего каналов. Это делает невозможным простое сохранение числовых показателей.

Рассмотрим несколько эффективных способов решения этой задачи, начиная от работы с временным хранилищем и заканчивая сериализацией объектов.

Способ 1. Использование временного хранилища на управляемых формах

Это классический подход для работы с ХранилищемЗначения в управляемом приложении. Поскольку мы не можем напрямую связать элемент формы с ресурсом регистра, нам необходимо организовать "транспортировку" данных между сервером и клиентом. Разберем этот процесс по шагам.

  1. На форме создадим реквизит ВыбранныйЦвет с типом Цвет.
  2. В обработчике ПриЧтенииНаСервере извлечем данные из регистра.
  3. В обработчике ПередЗаписьюНаСервере упакуем данные обратно.

Проанализируем пример кода для реализации этой логики:


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

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

Этот метод хорош тем, что он сохраняет объект Цвет целиком, включая информацию о том, является ли он цветом стиля или абсолютным RGB-значением.

Способ 2. Сериализация в XML через XDTO

Если по каким-то причинам вы не хотите использовать ХранилищеЗначения в качестве типа ресурса (например, для облегчения веса базы или удобства выгрузки), можно использовать строковый реквизит большой длины. Чтобы не потерять свойства цвета, воспользуемся XDTO-сериализатором. Он позволяет превратить любой сложный объект 1С в структурированную XML-строку.

Рассмотрим, как реализовать функции преобразования:


// Преобразование цвета в строку XML
Функция ЦветВXML(ЗначениеЦвета) Экспорт
    Возврат СериализаторXDTO.ЗаписатьXML(ЗначениеЦвета);
КонецФункции

// Восстановление цвета из строки XML
Функция XMLВЦвет(СтрокаXML) Экспорт
    Чтение = Новый ЧтениеXML;
    Чтение.УстановитьСтроку(СтрокаXML);
    Возврат СериализаторXDTO.ПрочитатьXML(Чтение, Тип("Цвет"));
КонецФункции

Этот способ гарантирует, что даже специфические системные цвета будут восстановлены корректно. В ресурсе регистра в этом случае должен быть установлен тип Строка (длиной 250+ символов или неограниченная).

Способ 3. Использование ЗначениеВСтрокуВнутр

Наиболее простой в реализации, но менее "красивый" с точки зрения чистоты данных метод — использование системной функции ЗначениеВСтрокуВнутр(). Она переводит объект во внутренний формат 1С, который также содержит все необходимые метаданные о типе цвета.

Посмотрим на пример записи данных:


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

&НаСервереБезКонтекста
Функция ПолучитьВнутреннююСтрокуЦвета(ЗначениеЦвета)
    Возврат ЗначениеВСтрокуВнутр(ЗначениеЦвета);
КонецФункции

Для восстановления объекта используется обратная функция ЗначениеИзСтрокиВнутр(). Этот метод стабильно работает в толстом и тонком клиентах, однако его не рекомендуется использовать для интеграции с внешними системами, так как формат строки является проприетарным для 1С.

Способ 4. Ручная настройка через RGB и визуализация

Если стоит задача сделать интерфейс максимально наглядным, но при этом избежать проблем с типами данных, можно пойти по пути создания "конструктора цвета". Как предлагалось в обсуждении, мы можем создать три числовых поля (Красный, Зеленый, Синий) и одно поле Декорация для предпросмотра.

Выясним причину выбора этого метода: он обеспечивает стопроцентную прозрачность данных. Вы всегда видите конкретные цифры в регистре и можете легко использовать их в запросах или при формировании условного оформления.

Для визуализации выбора используем следующий код:


&НаКлиенте
Процедура ПодобратьЦвет(Команда)
    Диалог = Новый ДиалогВыбораЦвета;
    Диалог.Цвет = Новый Цвет(Элементы.ПолеR, Элементы.ПолеG, Элементы.ПолеB);
    
    Если Диалог.Выбрать() Тогда
        Элементы.ПолеR = Диалог.Цвет.Красный;
        Элементы.ПолеG = Диалог.Цвет.Зеленый;
        Элементы.ПолеB = Диалог.Цвет.Синий;
        
        // Обновляем предпросмотр на форме
        Элементы.ДекорацияЦвет.ЦветФона = Диалог.Цвет;
    КонецЕсли;
КонецПроцедуры

Рекомендации по выбору решения

Проанализировав ситуацию, можно сделать следующие выводы:

  1. Если вы работаете в современной конфигурации на управляемых формах: используйте Способ 1 (ХранилищеЗначения + ПриЧтенииНаСервере). Это наиболее естественный путь для платформы 8.3.
  2. Если данные регистра будут использоваться в веб-сервисах или внешних отчетах: используйте Способ 2 (XDTO) или храните Hex-код цвета в виде строки.
  3. Если важна простота разработки: используйте Способ 3 (Внутренняя строка).
  4. Если нужно предоставить пользователю "тонкую" настройку: реализуйте три ползунка RGB и динамическое обновление декорации через событие ПриИзменении.

Важный момент: при использовании любого из методов не забывайте про производительность. Чтение из ХранилищаЗначения в цикле при выводе списка может замедлить работу. Если цветов много, лучше кэшировать их в переменные модуля или использовать условное оформление динамического списка, предварительно подготовив данные на сервере.

← На главную