Как получить цифровое значение RGB из цвета стиля в 1С:Предприятии

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

При разработке интерфейсов или формировании внешних отчетов часто возникает задача предоставить пользователю выбор цвета. Платформа 1С предлагает для этого удобный стандартный объект ДиалогВыбораЦвета. Однако разработчики часто сталкиваются с неожиданным поведением системы: если пользователь выбирает цвет не из палитры «Абсолютные», а из списка «Элементы стиля» (например, «Отрицательное число» или «Цвет текста кнопки»), то попытка получить составляющие Красный, Зеленый или Синий возвращает значение -1.

В этой статье мы разберем, почему так происходит, проанализируем структуру объекта Цвет и реализуем универсальный механизм для получения абсолютных цифровых значений RGB в любых ситуациях.

Почему свойства цвета возвращают -1?

Прежде чем перейти к решению, выясним причину проблемы. В платформе 1С объект Цвет может иметь несколько видов, которые определяются перечислением ВидЦвета. Рассмотрим основные из них:

  1. Абсолютный — цвет задан конкретными числами RGB (0–255). Только в этом случае свойства Красный, Зеленый и Синий содержат реальные данные.
  2. ЭлементСтиля — цвет привязан к метаданным конфигурации. Его реальное значение зависит от того, какая тема оформления выбрана в приложении.
  3. WindowsЦвет — системный цвет операционной системы (например, цвет заголовка активного окна).
  4. WebЦвет — стандартные именованные цвета HTML.

Для всех видов, кроме Абсолютного, платформа возвращает -1, так как значение цвета является «вычисляемым» и зависит от контекста (темы оформления, настроек ОС или версии платформы).

Попытка решения через метаданные

Рассмотрим ситуацию, когда мы пытаемся найти значение цвета через метаданные. Если ВидЦвета определен как ЭлементСтиля, можно попробовать обратиться к объекту метаданных напрямую. Рассмотрим пример кода, который часто пытаются использовать новички:


&НаСервере
Процедура ПолучитьЦветИзМетаданных(ВыбранныйЦвет)
    // Попытка получить имя стиля из строкового представления
    ИмяСтиля = Сред(Строка(ВыбранныйЦвет), 8); 
    ОбъектМетаданныхСтиля = Метаданные.ЭлементыСтиля.Найти(ИмяСтиля);
    
    Если ОбъектМетаданныхСтиля <> Неопределено Тогда 
        ЗначениеЦвета = ОбъектМетаданныхСтиля.Значение;
        // Но здесь нас снова может ждать неудача, если в метаданных указан другой стиль
    КонецЕсли;
КонецПроцедуры

Проблема этого метода: функция Строка() возвращает локализованный синоним (например, "Стиль: Отрицательное число"), в то время как метод Найти() ожидает внутреннее имя объекта метаданных. Кроме того, этот способ совершенно не работает для системных цветов Windows или авто-цветов.

Универсальный «хак» через Табличный документ

Существует проверенный временем способ заставить платформу 1С произвести вычисление цвета и преобразовать его в абсолютный формат. Этот метод основан на использовании объекта ТабличныйДокумент. При сохранении табличного документа в формат MXL7 платформа принудительно конвертирует все стили в конкретные RGB-значения для обеспечения визуальной идентичности документа.

Рассмотрим пошагово, как реализовать этот алгоритм:

  1. Создаем временный ТабличныйДокумент.
  2. Назначаем интересующий нас цвет фоном или цветом текста любой ячейки.
  3. Записываем документ во временный поток (или файл).
  4. Считываем документ обратно.
  5. Извлекаем цвет из той же ячейки — теперь он будет иметь вид Абсолютный.

Реализация с использованием потока в памяти

Использование физических файлов на диске (через Записать()) может привести к ошибкам прав доступа или конфликтам при одновременной работе нескольких пользователей. Проанализируем более современный и надежный вариант с использованием объекта ПотокВПамяти, который работает полностью в оперативной памяти.


&НаСервере
Функция ПолучитьАбсолютныйЦвет(ИсходныйЦвет) Экспорт

    // Если цвет уже абсолютный, возвращаем его без лишних вычислений
    Если ИсходныйЦвет.Вид = ВидЦвета.Абсолютный Тогда 
        Возврат ИсходныйЦвет; 
    КонецЕсли;

    // Инициализируем объекты для трансформации
    Поток = Новый ПотокВПамяти;
    ТабличныйДокумент = Новый ТабличныйДокумент;
    
    // Помещаем цвет в ячейку R1C1
    Ячейка = ТабличныйДокумент.Область("R1C1");
    Ячейка.ЦветФона = ИсходныйЦвет;
    
    // Магия преобразования: запись в формат MXL7 принудительно вычисляет RGB
    ТабличныйДокумент.Записать(Поток, ТипФайлаТабличногоДокумента.MXL7);
    
    // Получаем данные из потока для чтения
    ДвоичныеДанныеДокумента = Поток.ЗакрытьИПолучитьДвоичныеДанные();
    ЧтениеПотока = ДвоичныеДанныеДокумента.ОткрытьПотокДляЧтения();
    
    // Читаем документ обратно
    ТабличныйДокумент.Прочитать(ЧтениеПотока);
    ЧтениеПотока.Закрыть();
    
    // Теперь цвет в ячейке стал абсолютным
    АбсолютныйЦвет = ТабличныйДокумент.Область("R1C1").ЦветФона;
    
    Возврат АбсолютныйЦвет;

КонецФункции

Преобразование цвета в строку RGB

После того как мы получили абсолютный цвет, мы можем легко перевести его в нужный нам строковый формат, например "255,0,0". Разберем вспомогательную функцию для форматирования:


&НаКлиенте
Процедура ПолучитьЦифрыЦвета()
    
    Диалог = Новый ДиалогВыбораЦвета; 
    Если Диалог.Выбрать() Тогда 
        
        // Вызываем серверную функцию преобразования
        АЦвет = ПолучитьАбсолютныйЦвет(Диалог.Цвет);
        
        // Формируем итоговую строку
        СтрокаRGB = СтрШаблон("%1,%2,%3", 
            Формат(АЦвет.Красный, "ЧГ=0"), 
            Формат(АЦвет.Зеленый, "ЧГ=0"), 
            Формат(АЦвет.Синий, "ЧГ=0"));
            
        Сообщить("Выбранный цвет в формате RGB: " + СтрокаRGB);
        
    КонецЕсли;

КонецПроцедуры

Важные нюансы и рекомендации

При использовании данного метода стоит учитывать следующие моменты:

Таким образом, использование временного табличного документа является наиболее надежным способом получения честных RGB-компонентов из абстрактных стилей 1С. Мы рассмотрели и реализовали оптимальный вариант этого решения, исключающий работу с файловой системой и гарантирующий корректный результат независимо от сложности выбранного стиля.

← На главную