При разработке сложных отчетов в системе 1С:Предприятие программисты часто сталкиваются с ситуацией, когда один отчет содержит десятки различных макетов. В процессе выполнения кода, особенно когда макет передается между различными процедурами и функциями в качестве параметра, возникает необходимость точно знать: какой именно макет сейчас находится в обработке? Проблема заключается в том, что объект типа ТабличныйДокумент, который возвращается методом ПолучитьМакет(), является автономным и «забывает» свое имя из метаданных сразу после создания.
В этой статье мы подробно разберем, как обойти это ограничение платформы, рассмотрим различные архитектурные подходы и выберем наиболее надежные способы идентификации макетов.
Проанализируем самый простой и интуитивно понятный способ, предложенный участниками сообщества. Если мы не можем спросить у макета его имя напрямую, мы можем поискать в нем «отличительные знаки».
Для этого в каждом макете в конфигураторе можно создать специфическую область, которая не будет выводиться на печать, но будет служить техническим маркером. Рассмотрим пример кода, который проверяет наличие такой области:
Макет = ПолучитьМакет("МакетДляСотрудников");
// Проверяем, есть ли в полученном макете специфический маркер
Если Макет.Области.Найти("Идентификатор_МакетДляСотрудников") <> Неопределено Тогда
Сообщить("Программа определила: используется макет сотрудников.");
ИначеЕсли Макет.Области.Найти("Идентификатор_МакетДляПодразделений") <> Неопределено Тогда
Сообщить("Программа определила: используется макет подразделений.");
КонецЕсли;
Преимущества: метод прост в реализации и не требует изменения структуры вызовов функций. Недостатки: необходимость вручную поддерживать уникальность имен областей во всех макетах отчета.
Разберем еще один вариант идентификации, который часто применяется в типовых конфигурациях. Мы можем выделить в макете ячейку (например, в самой первой строке, которой назначена нулевая высота) и вписать туда техническое имя макета.
Процесс анализа в этом случае будет выглядеть следующим образом:
R1C1 записываем строку с именем макета.
Макет = ПолучитьМакет("ОсновнойМакет");
// Считываем идентификатор из скрытой ячейки (1-я строка, 1-я колонка)
ИмяМакета = Макет.Область(1, 1, 1, 1).Текст;
Если ИмяМакета = "ОсновнойМакет" Тогда
// Выполняем специфическую логику
КонецЕсли;
Давайте проанализируем ситуацию с точки зрения архитектуры кода. Вместо того чтобы пытаться угадать имя макета «постфактум», правильнее будет передавать его имя вместе с самим объектом. Это избавляет от необходимости анализа структуры ТабличныйДокумент и делает код более читаемым и надежным.
Посмотрим на пример упаковки макета в структуру:
// Вместо простой передачи макета, создадим контейнер
ДанныеМакета = Новый Структура;
ДанныеМакета.Вставить("Объект", ПолучитьМакет("СводныйОтчет"));
ДанныеМакета.Вставить("Имя", "СводныйОтчет");
ДанныеМакета.Вставить("ТипДанных", "Финансы");
// Передаем структуру в процедуру заполнения
ЗаполнитьПараметрыМакета(ДанныеМакета);
...
Процедура ЗаполнитьПараметрыМакета(Параметры)
Имя = Параметры.Имя;
МакетОбъект = Параметры.Объект;
Сообщить("Работаем с макетом: " + Имя);
КонецПроцедуры
Если ваш отчет построен на базе СКД, ситуация меняется. Вывод данных часто происходит автоматически, и макеты генерируются процессором компоновки. Однако, если вы используете собственные макеты внутри схемы компоновки, выясним, как определить текущий вариант.
Имя текущего варианта отчета, который зачастую жестко связан с используемым макетом, можно получить через компоновщик настроек:
// Получаем имя текущего варианта настройки
ИмяВарианта = ЭтаФорма.Отчет.КомпоновщикНастроек.Настройки.ИмяВарианта;
// Если имя варианта не задано, можно взять из пользовательских настроек
Если ПустаяСтрока(ИмяВарианта) Тогда
ИмяВарианта = ЭтаФорма.Отчет.SettingsComposer.UserSettings.AdditionalProperties.Get("VariantName");
КонецЕсли;
В современных конфигурациях (например, 1С:ERP или 1С:Бухгалтерия 3.0) используется Библиотека стандартных подсистем (БСП). В этом случае печать и формирование отчетов проходят через стандартизированные механизмы.
Рассмотрим, как это работает в БСП:
ДобавитьКомандыПечати.Печать передается параметр ИменаМакетов.
В данном контексте задача «определения имени» сводится к простому чтению входящего параметра процедуры Печать.
Мы проанализировали различные методы определения имени макета. Если вы работаете с простым самописным отчетом, использование структуры-контейнера (Метод 3) является наиболее профессиональным и «чистым» решением. Если же вы ограничены существующей архитектурой и не можете менять интерфейсы функций, используйте уникальные именованные области (Метод 1) или скрытые ячейки (Метод 2) в качестве надежных маркеров.