Как реализовать градиентную заливку ячеек в табличном документе 1С?

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

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

В этой статье мы подробно рассмотрим и разберем по шагам наиболее эффективные методы реализации градиента в табличных документах 1С: от простых математических расчетов до генерации векторной графики на лету и интеграции HTML5.

Метод 1. Математический расчет плавного перехода цветов (Дискретный градиент)

Этот способ основан на разбиении целевого диапазона на множество мелких ячеек и их последовательном окрашивании в промежуточные тона. Мы рассчитываем плавное изменение каналов RGB (Red, Green, Blue) от начального цвета к конечному.

Проанализируем алгоритм интерполяции цвета. Если у нас есть начальный цвет Цвет1 с составляющими (R1, G1, B1) и конечный цвет Цвет2 с составляющими (R2, G2, B2), а также количество шагов разбиения N, то приращение для каждого канала на один шаг рассчитывается следующим образом:


ШагR = (R2 - R1) / N;
ШагG = (G2 - G1) / N;
ШагB = (B2 - B1) / N;

Для реализации градиента к центру ячейки нам необходимо разделить расчет на две части. Первую половину шагов мы движемся от начального цвета к конечному (центру), а вторую половину — симметрично возвращаемся обратно к исходному цвету. Рассмотрим пример кода, реализующий эту логику:


Функция ПолучитьПромежуточныйЦвет(ЦветНачала, ЦветКонца, ВсегоШагов, ТекущийШаг) Экспорт
	
	// Определяем направление движения (к центру и от него)
	ПоловинаШагов = Цел(ВсегоШагов / 2);
	Если ТекущийШаг > ПоловинаШагов Тогда
		ИндексШага = ВсегоШагов - ТекущийШаг;
	Иначе
		ИндексШага = ТекущийШаг;
	КонецЕсли;
	
	// Вычисляем шаг интерполяции для каждого канала
	ШагR = (ЦветКонца.Красный - ЦветНачала.Красный) / ПоловинаШагов;
	ШагG = (ЦветКонца.Зеленый - ЦветНачала.Зеленый) / ПоловинаШагов;
	ШагB = (ЦветКонца.Синий - ЦветНачала.Синий) / ПоловинаШагов;
	
	// Рассчитываем итоговые составляющие цвета
	НовыйR = ЦветНачала.Красный + Окр(ШагR * ИндексШага);
	НовыйG = ЦветНачала.Зеленый + Окр(ШагG * ИндексШага);
	НовыйB = ЦветНачала.Синий + Окр(ШагB * ИндексШага);
	
	Возврат Новый Цвет(НовыйR, НовыйG, НовыйB);
	
КонецФункции

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

Метод 2. Динамическая генерация SVG-картинок (Векторный градиент)

Начиная с версии 8.3.9, платформа 1С:Предприятие нативно поддерживает векторный формат SVG. Это дает нам мощный инструмент для создания идеальных сглаженных градиентов любой сложности без необходимости разбивать ячейки и перегружать макет.

Выясним, как работает этот подход. Мы можем сформировать XML-текст SVG-изображения, содержащий тег radialGradient для радиального градиента (к центру) или linearGradient для линейного градиента. Затем мы записываем этот текст во временный файл и загружаем его в объект Картинка.

Разберем пример программного формирования фоновой SVG-картинки с градиентом к центру:


Функция СгенерироватьРадиальныйГрадиентSVG(ЦветЦентраHEX, ЦветКраяHEX) Экспорт
	
	// Формируем XML-код SVG-контейнера с радиальным градиентом
	ТекстSVG = 
	"<svg xmlns=""http://www.w3.org/2000/svg"" width=""100%"" height=""100%"">" +
	"	<defs>" +
	"		<radialGradient id=""CenterGrad"" cx=""50%"" cy=""50%"" r=""50%"" fx=""50%"" fy=""50%"">" +
	"			<stop offset=""0%"" style=""stop-color:" + ЦветЦентраHEX + ";stop-opacity:1"" />" +
	"			<stop offset=""100%"" style=""stop-color:" + ЦветКраяHEX + ";stop-opacity:1"" />" +
	"		</radialGradient>" +
	"	</defs>" +
	"	<rect width=""100%"" height=""100%"" fill=""url(#CenterGrad)"" />" +
	"</svg>";
	
	// Сохраняем во временный файл для создания объекта Картинка
	ПутьКФайлу = ПолучитьИмяВременногоФайла("svg");
	ТекстовыйДокумент = Новый ТекстовыйДокумент;
	ТекстовыйДокумент.УстановитьТекст(ТекстSVG);
	ТекстовыйДокумент.Записать(ПутьКФайлу, КодировкаТекста.UTF8);
	
	ГрадиентнаяКартинка = Новый Картинка(ПутьКФайлу);
	
	// Удаляем временный файл с диска
	Попытка
		УдалитьФайлы(ПутьКФайлу);
	Исключение
		// Обработка возможных ошибок блокировки файла процессом
	КонецПопытки;
	
	Возврат ГрадиентнаяКартинка;
	
КонецФункции

Теперь рассмотрим, как применить полученную картинку к табличному документу. Существует два способа позиционирования:

  1. Фоновая картинка области: Назначить полученный объект свойству области табличного документа ФоноваяКартинка. Однако учитывайте, что масштабирование фоновых картинок в ячейках 1С имеет свои особенности и может замостить ячейку мозаикой, если размер области изменится.
  2. Элемент коллекции рисунков: Добавить графический объект поверх нужного диапазона ячеек. Этот метод более гибкий, так как позволяет точно позиционировать рисунок и управлять его свойствами.

Посмотрим на пример позиционирования градиента через коллекцию рисунков:


Процедура ЗалитьОбластьГрадиентом(ТабДок, АдресОбласти, ЦветЦентра, ЦветКрая)
	
	Область = ТабДок.Область(АдресОбласти);
	КартинкаSVG = СгенерироватьРадиальныйГрадиентSVG(ЦветЦентра, ЦветКрая);
	
	// Добавляем рисунок поверх указанной области
	НовыйРисунок = ТабДок.Рисунки.Добавить(ТипРисункаТабличногоДокумента.Картинка);
	НовыйРисунок.Картинка = КартинкаSVG;
	НовыйРисунок.Расположить(Область);
	
	// Настраиваем поведение картинки при изменении размера ячеек
	НовыйРисунок.РазмернаяКартинка = РазмернаяКартинка.Растянуть;
	НовыйРисунок.ВыводитьНаПечать = Истина;
	
	// Перемещаем рисунок на задний план, чтобы текст в ячейках оставался видимым
	НовыйРисунок.Порядок = ПорядокРисункаТабличногоДокумента.Назад;
	
КонецПроцедуры

Метод 3. Использование Поля HTML-документа на управляемой форме

Если отчет предназначен исключительно для экранного просмотра на форме, отличным решением будет отказ от классического табличного документа в пользу элемента формы ПолеHTMLДокумента. Современные движки рендеринга HTML в 1С обеспечивают полную поддержку спецификации CSS3, включая градиенты.

Преимущество этого метода заключается в том, что нам не нужно писать сложные математические алгоритмы или генерировать временные файлы. Мы просто формируем стандартную HTML-таблицу. Проанализируем пример CSS-стилизации ячеек:


<html>
<head>
<style>
	.gradient-cell {
		background: radial-gradient(circle, #ffffff 0%, #3f51b5 100%);
		font-family: Arial, sans-serif;
		font-size: 12px;
		text-align: center;
		vertical-align: middle;
		color: #000000;
		height: 40px;
		border: 1px solid #ccc;
	}
</style>
</head>
<body>
	<table style="width:100%; border-collapse: collapse;">
		<tr>
			<td class="gradient-cell">Ячейка с градиентом к центру</td>
		</tr>
	</table>
</body>
</html>

Этот код генерируется программно в виде строки и присваивается реквизиту формы, связанному с полем HTML. Такой подход гарантирует безупречное отображение градиента без искажений при любом масштабировании окна.

Метод 4. Построение условного оформления в СКД

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

Разберем этот процесс по шагам:

  1. Выполняем программный запрос к СКД и получаем минимальное и максимальное значения ресурса в сформированном наборе данных.
  2. Делим полученный диапазон значений на фиксированное количество интервалов (например, 10 или 15 шагов).
  3. Для каждого шага рассчитываем свой промежуточный цвет фона по формуле линейной интерполяции.
  4. Программно добавляем правила в коллекцию условного оформления СКД. Каждое правило будет содержать условие вида: Значение > ГраницаИнтервалаНачала И Значение <= ГраницаИнтервалаКонца, и соответствующий цвет оформления фона.

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

Метод 5. Экспорт документа в Excel через COM-соединение

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

В таких случаях применяется интеграция с пакетом MS Excel посредством COM-технологии. Объектная модель Excel имеет штатную поддержку градиентной заливки. Рассмотрим пример кода на 1С, который настраивает градиент непосредственно внутри файла Excel после его генерации:


Процедура НастроитьГрадиентВExcel(ПутьКФайлу, ИмяЛиста, АдресЯчейки)
	
	Попытка
		Excel = Новый COMОбъект("Excel.Application");
		Excel.Visible = Ложь;
		Excel.DisplayAlerts = Ложь;
		
		Книга = Excel.Workbooks.Open(ПутьКФайлу);
		Лист = Книга.Sheets(ИмяЛиста);
		Диапазон = Лист.Range(АдресЯчейки);
		
		// Активируем двухцветный градиент в ячейке Excel
		Диапазон.Interior.Pattern = 4000; // Константа xlPatternLinearGradient / xlPatternRadialGradient
		
		// Очищаем стандартные точки градиента
		Диапазон.Interior.Gradient.ColorStops.Clear();
		
		// Добавляем начальную точку (в центре)
		ТочкаЦентра = Диапазон.Interior.Gradient.ColorStops.Add(0);
		ТочкаЦентра.Color = RGB(255, 255, 255); // Белый цвет
		
		// Добавляем конечную точку (на краях)
		ТочкаКрая = Диапазон.Interior.Gradient.ColorStops.Add(1);
		ToчкаКрая.Color = RGB(255, 0, 0); // Красный цвет
		
		Книга.Save();
		Книга.Close();
		Excel.Quit();
	Исключение
		ЗаписьЖурналаРегистрации("Оформление Excel", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
		Если ЗначениеЗаполнено(Excel) Тогда
			Excel.Quit();
		КонецЕсли;
	КонецПопытки;
	
КонецПроцедуры

Используя этот метод, вы получите гарантированно качественный результат, который откроется у конечного пользователя на любом устройстве с установленным табличным процессором Excel, полностью сохранив задуманный дизайн.

← На главную