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

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

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

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

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

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

Если параметр Заголовок выведен в состав пользовательских настроек, то любое изменение КомпоновщикНастроек.Настройки.ПараметрыВывода будет перекрыто значением из КомпоновщикНастроек.ПользовательскиеНастройки. Именно поэтому в обсуждении на форуме автору помог сброс настроек к стандартным — это удалило "застрявшие" пользовательские настройки, мешавшие коду.

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

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


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

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

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

Способ 2. Постобработка табличного документа (Метод подмены)

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

Рассмотрим реализацию в процедуре ПриКомпоновкеРезультата:


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

Этот метод хорош тем, что он не зависит от иерархии настроек компоновщика, так как работает напрямую с визуальными данными в объекте Результат (тип ТабличныйДокумент).

Способ 3. Использование пользовательских настроек напрямую

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

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


// Находим идентификатор настройки заголовка
ИдНастройки = КомпоновщикНастроек.Настройки.ПараметрыВывода.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("Заголовок")).ИдентификаторПользовательскойНастройки;

// Ищем этот идентификатор в пользовательских настройках
Если ЗначениеЗаполнено(ИдНастройки) Тогда
    ЭлементНастройки = КомпоновщикНастроек.ПользовательскиеНастройки.Элементы.Найти(ИдНастройки);
    Если ЭлементНастройки <> Неопределено Тогда
        ЭлементНастройки.Значение = "Новый динамический текст";
        ЭлементНастройки.Использование = Истина;
    КонецЕсли;
КонецЕсли;

Особенности многострочных заголовков

В исходном вопросе автор использовал Символы.ВК (возврат каретки) для создания многострочного заголовка. Это абсолютно правильно, но есть важный технический момент. Чтобы заголовок не "схлопывался" в одну строку, необходимо убедиться, что для ячейки в макете оформления или в результирующем документе установлено свойство Размещать: Переносить.

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

  1. Перейдите на закладку Макеты в схеме компоновки.
  2. Выберите или создайте макет для заголовка.
  3. В свойствах ячейки установите РазмещениеТекста в значение Переносить.
  4. Убедитесь, что высота строки установлена в значение Авто, иначе вторая и последующие строки просто не будут видны.

Итоги и рекомендации

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

Посмотрим на финальный чек-лист для проверки:

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

← На главную