Как динамически добавить значение параметра в заголовок колонки СКД?

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

При проектировании отчетов на базе Системы компоновки данных (СКД) разработчики часто сталкиваются с требованием заказчиков выводить динамические данные в шапку таблицы. Классический пример — колонка с суммами или остатками, в заголовке которой должна быть указана конкретная дата (например, «Остаток на 31.12.2023» вместо статичного «Остаток»).

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

Метод 1. Настройка динамического заголовка без кода (Вычисляемое поле + Условное оформление)

Этот способ является наиболее предпочтительным, так как он сохраняет отчет на стандартных настройках СКД, не требует написания кода в модулях и работает полностью в рамках декларативной модели 1С. Мы обойдем ограничение условного оформления, при котором прямая подстановка параметра выводит его техническое имя (например, &КонецПериода), с помощью промежуточного вычисляемого поля.

Разберем этот алгоритм по шагам:

  1. Откроем схему компоновки данных и перейдем на вкладку «Вычисляемые поля».
  2. Добавим новое поле со следующими свойствами:
    • Путь к данным: укажем понятное имя, например, ЗаголовокСДатой.
    • Выражение: здесь мы пишем формулу формирования нашей будущей шапки. Мы можем комбинировать строковые литералы, системные функции форматирования и параметры схемы. Пример выражения:
      "Остаток на " + Формат(&КонецПериода, "ДЛФ=Д").
    • Заголовок: можно оставить пустым или продублировать имя.
  3. Перейдем на вкладку «Настройки» и выберем вкладку «Условное оформление» в нижней части окна настроек отчета.
  4. Создадим новое правило условного оформления:
    • В колонке «Оформление» найдем свойство «Текст». Нажмем на кнопку выбора (три точки), затем кликнем по кнопке выбора типа («крестик»/стрелка) и переключим режим на «Поле компоновки данных». Из списка доступных полей выберем наше созданное вычисляемое поле ЗаголовокСДатой.
    • В колонке «Оформляемые поля» укажем то поле отчета, заголовок которого мы хотим динамически заменить. Например, выберем поле СуммаОстаток.
  5. Самый важный шаг: перейдем на вкладку «Область использования» в окне редактирования элемента условного оформления. По умолчанию там активны все флажки. Снимем все галочки и оставим активным только один пункт — «К заголовку полей».

Проанализируем, как это работает. При формировании отчета СКД рассчитывает значение вычисляемого поля ЗаголовокСДатой, подставляя туда актуальное отформатированное значение параметра &КонецПериода. Механизм условного оформления берет полученный текст и заменяет им стандартную шапку выбранной колонки. Благодаря правильной области использования, сами данные в строках отчета остаются нетронутыми, а заголовок становится полностью динамическим.

Метод 2. Безопасное программное изменение заголовков через настройки Компоновщика

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

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

Рассмотрим пример кода, реализующий этот подход:


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

В данном примере мы манипулируем свойствами поля внутри коллекции ВыбранныеПоля текущего компоновщика настроек. Это абсолютно безопасно для многопользовательской работы и гарантирует корректное отображение заголовков у каждого конкретного пользователя.

Метод 3. Универсальный шаблонный метод для сложных отчетов

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

Идея заключается в том, что в конфигураторе (или пользовательском режиме) разработчик или пользователь задает заголовок поля в специальном формате шаблона, например: Продажи за #ПериодОтчета или Остаток на #КонецПериода. Программа перед выводом отчета автоматически сканирует все выбранные поля, находит символ решетки #, извлекает имя параметра, получает его значение и выполняет подстановку.

Реализуем этот механизм с помощью рекурсивного обхода структуры выбранных полей в модуле отчета:


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

Процедура ОбработатьВыбранныеПоляРекурсивно(КоллекцияЭлементов, ПараметрыДанных)
    
    Для Каждого Элемент Из КоллекцияЭлементов Цикл
        
        // Если это группа полей (папка), заходим внутрь нее
        Если ТипЗнч(Элемент) = Тип("ГруппаВыбранныхПолейКомпоновкиДанных") Тогда
            ОбработатьВыбранныеПоляРекурсивно(Элемент.Элементы, ПараметрыДанных);
            
        // Если это обычное выбранное поле
        ИначеЕсли ТипЗнч(Элемент) = Тип("ВыбранноеПолеКомпоновкиДанных") Тогда
            
            СтрокаЗаголовка = Элемент.Заголовок;
            ИндексШаблона = Найти(СтрокаЗаголовка, "#");
            
            Если ИндексШаблона > 0 Тогда
                
                // Выделяем имя параметра, идущее после символа '#'
                ИмяПараметра = СокрЛП(Сред(СтрокаЗаголовка, ИндексШаблона + 1));
                
                // Находим значение параметра в настройках компоновщика
                ПараметрСхемы = ПараметрыДанных.Найти(ИмяПараметра);
                
                Если ПараметрСхемы <> Неопределено И ПараметрСхемы.Использование Тогда
                    
                    // Форматируем значение в зависимости от его типа
                    ЗначениеСтрокой = "";
                    Если ТипЗнч(ПараметрСхемы.Value) = Тип("Дата") Тогда
                        ЗначениеСтрокой = Формат(ПараметрСхемы.Value, "ДФ=dd.MM.yyyy");
                    Иначе
                        ЗначениеСтрокой = Строка(ПараметрСхемы.Value);
                    КонецЕсли;
                    
                    // Собираем новый заголовок и заменяем шаблон значением
                    ШаблонТекста = Лев(СтрокаЗаголовка, ИндексШаблона - 1);
                    Элемент.Заголовок = ШаблонТекста + " " + ЗначениеСтрокой;
                    Элемент.ИспользованиеЗаголовка = ИспользованиеЗаголовкаКомпоновкиДанных.Использовать;
                    
                КонецЕсли;
                
            КонецЕсли;
            
        КонецЕсли;
        
    КонецЦикла;
    
КонецПроцедуры

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

Метод 4. Особенности вывода динамических шапок в таблицах (кросс-таблицах)

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

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

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

← На главную