Как программно настроить параметры и оси диаграммы в СКД?

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

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

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

Постановка проблемы и анализ структуры СКД

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

Многие разработчики совершают типичную ошибку, пытаясь обратиться к параметрам диаграммы напрямую через индекс, например: КомпоновщикНастроек.Настройки.Структура[0]. Настоятельно рекомендуем избегать подобного подхода в реальных задачах. Если пользователь в режиме предприятия изменит структуру отчета, добавит заголовок, другую таблицу или группировку выше диаграммы, индекс изменится. Это неминуемо приведет к ошибке выполнения кода или к тому, что настройки применятся не к тому объекту.

Давайте выясним, как правильно и безопасно найти элемент структуры настроек, отвечающий за диаграмму, и программно переопределить свойства её оси значений.

Способ 1. Программная модификация структуры настроек СКД

Рассмотрим пошагово первый способ. Нам потребуется обратиться к структуре настроек компоновки, найти нужную диаграмму, извлечь из её параметров вывода вложенные параметры оси значений и задать необходимые ограничения.

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


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

Теперь, когда у нас есть инструмент для безопасного поиска диаграмм, перейдем непосредственно к модификации параметров оси в модуле объекта отчета. Нам нужно переопределить обработчик события ПриКомпоновкеРезультата.

Обратите внимание на важный нюанс современных версий платформы "1С:Предприятие" (начиная с 8.3.13): свойства АвтоМаксимальноеЗначение и АвтоМинимальноеЗначение устарели. Вместо них следует использовать перечисление СпособОпределенияОграничивающегоЗначенияДиаграммы со значением ИспользоватьЗначение. Если этого не сделать, платформа проигнорирует ваши числовые настройки и продолжит рассчитывать масштаб автоматически.

Проанализируем пример кода программной настройки оси значений диаграммы:


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;
    
    СхемаКомпоновкиДанных = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
    Настройки = КомпоновщикНастроек.ПолучитьНастройки();
    ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;
    
    // Безопасный поиск всех диаграмм в структуре текущих настроек
    МассивДиаграмм = НайтиВсеДиаграммы(Настройки.Структура);
    
    Если МассивДиаграмм.Количество() > 0 Тогда
        // Берем первую найденную диаграмму для настройки
        ДиаграммаСКД = МассивДиаграмм[0];
        
        // Переходим к поиску параметра "Тип диаграммы"
        ПараметрТипДиаграммы = ДиаграммаСКД.ПараметрыВывода.НайтиПараметр(Новый ПараметрКомпоновкиДанных("ТипДиаграммы"));
        
        Если ПараметрТипДиаграммы <> Неопределено Тогда
            ВложенныеПараметры = ПараметрТипДиаграммы.ЗначенияВложенныхПараметров;
            ОсьЗначений = ВложенныеПараметры.Найти("ТипДиаграммы.ОсьЗначений");
            
            Если ОсьЗначений <> Неопределено Тогда
                // Задаем числовые границы оси (например, рассчитываем их на основе параметров отчета)
                ОсьЗначений.Значение.МинимальноеЗначение = 60;
                ОсьЗначений.Значение.МаксимальноеЗначение = 90;
                
                // Обязательно отключаем автоопределение границ оси
                ОсьЗначений.Значение.СпособОпределенияМинимальногоЗначения = СпособОпределенияОграничивающегоЗначенияДиаграммы.ИспользоватьЗначение;
                ОсьЗначений.Значение.СпособОпределенияМаксимальногоЗначения = СпособОпределенияОграничивающегоЗначенияДиаграммы.ИспользоватьЗначение;
            КонецЕсли;
        КонецЕсли;
    КонецЕсли;
    
    // Стандартный процесс вывода отчета с измененными настройками
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
    
    ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки);
    
    ДокументРезультат.Очистить();
    
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент; 
    ПроцессорВывода.УстановитьДокумент(ДокументРезультат); 
    ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных);
    
КонецПроцедуры

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

Способ 2. Постобработка сформированного табличного документа

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

В тот момент, когда отчет уже выведен в результирующий ТабличныйДокумент, диаграмма превращается в обычный объект рисования на листе. Мы можем легко перебрать коллекцию рисунков табличного документа, найти объект диаграммы и напрямую изменить свойства его шкалы.

Посмотрим на пример реализации данного метода:


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    // 1. Позволяем платформе сформировать отчет стандартным образом
    // (Или выполняем программный вывод, если это необходимо для других задач)
    
    // 2. После того как документ сформирован, выполняем обход коллекции рисунков
    Для Каждого Рисунок Из ДокументРезультат.Рисунки Цикл
        
        // Проверяем, является ли рисунок диаграммой
        Если Рисунок.ТипРисунка = ТипРисункаТабличногоДокумента.Диаграмма Тогда
            
            // Получаем непосредственный объект "Диаграмма"
            ДиаграммаОбъект = Рисунок.Объект;
            
            // Настраиваем шкалу оси значений напрямую
            Шкала = ДиаграммаОбъект.ОсьЗначений;
            
            Шкала.МинимальноеЗначение = 60;
            Шкала.МаксимальноеЗначение = 90;
            
            // Отключаем автоматический расчет масштаба
            Шкала.СпособОпределенияМинимальногоЗначения = СпособОпределенияОграничивающегоЗначенияДиаграммы.ИспользоватьЗначение;
            Шкала.СпособОпределенияМаксимальногоЗначения = СпособОпределенияОграничивающегоЗначенияДиаграммы.ИспользоватьЗначение;
            
        КонецЕсли;
        
    КонецЦикла;
    
КонецПроцедуры

Сравнение подходов

Выясним преимущества и недостатки каждого из предложенных вариантов, чтобы вы могли сделать осознанный выбор для своего проекта:

  1. Изменение настроек СКД (Способ 1):
    • Плюсы: Изменения происходят на уровне декларативной модели СКД. Это гарантирует корректный экспорт настроек, сохранение структуры при сохранении вариантов отчетов пользователями.
    • Минусы: Сложная структура объектов, громоздкий код поиска параметров, чувствительность к изменениям типов в платформе.
  2. Постобработка табличного документа (Способ 2):
    • Плюсы: Исключительная простота реализации. Понятный и лаконичный код. Нет необходимости знать структуру метаданных СКД. Легко отлаживать.
    • Минусы: Настройки применяются "поверх" уже сгенерированного отчета. Если пользователь решит пересохранить настройки схемы компоновки, эти изменения не попадут во внутреннюю структуру СКД.

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

← На главную