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

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

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

Почему возникает ошибка объектного типа?

Разберем типичную ситуацию, с которой сталкиваются разработчики. При попытке выполнить код СхемаКомпоновкиДанных.ВычисляемыеПоля.Найти("Поле").Заголовок = "Текст" система может выдать ошибку «Значение не является значением объектного типа (Заголовок)». Это происходит по двум причинам:

  1. Метод Найти() возвращает Неопределено, если имя поля указано неверно или оно отсутствует в данной коллекции.
  2. Вы пытаетесь изменить описание поля в Схеме, в то время как отчет формируется на основании Настроек компоновщика. Если компоновщик уже инициализирован, изменения в схеме не «пробросятся» в настройки автоматически.

Проанализируем правильные подходы к решению этой задачи.

Способ 1. Изменение через выбранные поля компоновщика настроек

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

Рассмотрим по шагам, как найти нужное поле в настройках и установить ему новый заголовок:


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

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

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

Способ 2. Рекурсивный поиск поля в группах

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


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

Вызвать эту процедуру можно так: ИзменитьЗаголовокПоляРекурсивно(КомпоновщикНастроек.Настройки.Выбор.Элементы, "ВашеПоле", "Новое Имя").

Способ 3. Изменение заголовка через Условное оформление

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

Разберем пример кода:


// Добавляем новый элемент условного оформления
ЭлементОформления = КомпоновщикНастроек.Настройки.УсловноеОформление.Элементы.Добавить();

// Устанавливаем, что именно мы меняем — параметр "Текст"
ЭлементОформления.Оформление.УстановитьЗначениеПараметра("Текст", "Динамический заголовок ресурса");

// Указываем, для какого поля действует оформление
ОформляемоеПоле = ЭлементОформления.Поля.Элементы.Добавить();
ОформляемоеПоле.Поле = Новый ПолеКомпоновкиДанных("СуммаОборот");
ОформляемоеПоле.Использование = Истина;

// Самое важное: указываем, что оформление применяется ТОЛЬКО к заголовку
ЭлементОформления.ИспользованиеВЗаголовкеПоля = Истина;
ЭлементОформления.ИспользованиеВОбщемИтогеЗаголовка = Истина;

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

Способ 4. Изменение в Схеме (с переинициализацией)

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

Проанализируем пример:


// Находим поле в схеме (например, в наборе данных)
ПолеСхемы = СхемаКомпоновкиДанных.НаборыДанных.НаборДанных1.Поля.Найти("Сумма");
Если ПолеСхемы <> Неопределено Тогда
    ПолеСхемы.Заголовок = "Итоговая сумма (изменено)";
КонецЕсли;

// Обязательно перезагружаем компоновщик
КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаКомпоновкиДанных));

Рекомендации по реализации

Подведем итог и выделим лучшие практики:

  1. Где писать код: Если заголовок зависит от параметров отчета, лучшее место — процедура ПриКомпоновкеРезультата в модуле отчета.
  2. Приоритет настроек: Помните, что если пользователь сам изменил заголовок поля в настройках отчета, ваши программные изменения в КомпоновщикНастроек.Настройки могут быть перекрыты данными из КомпоновщикНастроек.ПользовательскиеНастройки. В критических случаях стоит проверять и коллекцию пользовательских настроек по идентификатору.
  3. Ресурсы: Для ресурсов правила те же самые, что и для обычных полей. Ищите их в коллекции Выбор или используйте Условное оформление.

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

← На главную