При разработке отчетов на базе Системы компоновки данных (СКД) программисты часто сталкиваются с задачей вывода параметров периода (например, даты окончания отчета) в печатную форму, подвал или заголовок программным способом. Казалось бы, задача проста: обратиться к компоновщику настроек и забрать значение. Однако в обычных формах (например, в конфигурации БГУ 1.0, УПП или ЗУП 2.5) этот процесс имеет свои нюансы, из-за которых вместо нужной даты часто возвращается пустое значение. Рассмотрим подробно, почему так происходит и как правильно получить данные.
Чаще всего разработчики пытаются получить значение следующим кодом:
ЗначениеПараметраКонецПериода = КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеParemetra(Новый ПараметрКомпоновкиДанных("КонецПериода")).Значение;
Проанализируем ситуацию: почему в Значение оказывается Дата('00010101')? Основная причина кроется в архитектуре СКД. Настройки в компоновщике разделены на несколько уровней:
Если параметр "КонецПериода" вынесен на пользовательскую панель (включен флажок "Включать в пользовательские настройки"), то его актуальное значение хранится не в основном свойстве Настройки, а в коллекции ПользовательскиеНастройки. Прямое обращение к Настройки в этом случае вернет значение из конфигуратора, которое часто бывает пустым.
Чтобы не искать значение по всем коллекциям вручную, в 1С предусмотрен метод ПолучитьНастройки(). Он собирает воедино все уровни настроек (основные, пользовательские и фиксированные) и выдает результирующий объект, который и будет использоваться при компоновке результата. Это самый правильный путь с точки зрения логики СКД.
Разберем пример кода для получения даты:
// Получаем полные настройки, объединяющие выбор пользователя и схему
ПолныеНастройки = КомпоновщикНастроек.ПолучитьНастройки();
// Ищем параметр по имени
ПараметрКонец = ПолныеНастройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("КонецПериода"));
Если ПараметрКонец <> Неопределено Тогда
ДатаОтчета = ПараметрКонец.Значение;
// Если параметр имеет тип СтандартныйПериод, нужно извлечь дату окончания
Если ТипЗнч(ДатаОтчета) = Тип("СтандартныйПериод") Тогда
ДатаОтчета = ДатаОтчета.ДатаОкончания;
КонецЕсли;
КонецЕсли;
В типовых конфигурациях на обычных формах (таких как БГУ 1.0) параметры периода часто связаны напрямую с реквизитами формы. На форме может присутствовать реквизит с типом СтандартныйПериод или две отдельные даты. Выясним причину, почему это иногда надежнее: в момент нажатия кнопки "Сформировать" настройки из этих реквизитов еще могут не успеть "прогрузиться" в объект компоновщика, если вы обращаетесь к ним слишком рано или слишком поздно в жизненном цикле формы.
Проанализируем самый простой способ, который часто выручает в обычных формах:
// Если на форме есть реквизит "СтандартныйПериод"
Если ЗначениеЗаполнено(СтандартныйПериод.ДатаОкончания) Тогда
ОбластьВывести.Параметры.Дата = СтандартныйПериод.ДатаОкончания;
КонецЕсли;
Важно: Этот способ работает, если реквизит СтандартныйПериод действительно добавлен на форму и связан с элементами управления.
Если вы хотите быть абсолютно уверены в получении данных или вам нужно отладить, какие именно параметры сейчас заполнены, можно воспользоваться перебором коллекции. Посмотрим на пример кода, который позволяет извлечь значение любого параметра по его имени:
Настройки = КомпоновщикНастроек.ПолучитьНастройки();
СоответствиеПараметров = Новый Соответствие;
Для Каждого ЭлементПараметра Из Настройки.ПараметрыДанных.Элементы Цикл
// Заполняем соответствие для удобного поиска
СоответствиеПараметров.Вставить(Строка(ЭлементПараметра.Параметр), ЭлементПараметра.Значение);
КонецЦикла;
// Получаем конкретное значение
ЗначениеКонПериода = СоответствиеПараметров.Получить("КонецПериода");
Проанализируем типичную ошибку: попытка получить значение после вызова процедуры СформироватьОтчет() или ПриКомпоновкеРезультата(). В некоторых типовых механизмах (особенно в универсальных отчетах) настройки компоновщика могут очищаться или переинициализироваться сразу после того, как табличный документ был сформирован.
Рассмотрим правильный алгоритм действий в модуле формы:
СформироватьОтчет(...).Пример реализации в обработчике кнопки:
Процедура КнопкаСформироватьНажатие(Кнопка)
// 1. Сохраняем дату до начала всех манипуляций
Настройки = КомпоновщикНастроек.ПолучитьНастройки();
Параметр = Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("КонецПериода"));
ДатаДляПодписи = ?(Параметр <> Неопределено, Параметр.Значение, ТекущаяДата());
// Если это СтандартныйПериод - извлекаем дату
Если ТипЗнч(ДатаДляПодписи) = Тип("СтандартныйПериод") Тогда
ДатаДляПодписи = ДатаДляПодписи.ДатаОкончания;
КонецЕсли;
// 2. Формируем основной отчет
ЭлементыФормы.Результат.Очистить();
СформироватьОтчет(ЭлементыФормы.Результат, ДанныеРасшифровки);
// 3. Выводим свой макет с подписями и датой
Макет = ПолучитьМакет("МакетПодписи");
Область = Макет.ПолучитьОбласть("Подпись");
Область.Параметры.ДатаДокумента = Формат(ДатаДляПодписи, "ДФ=dd.MM.yyyy");
ЭлементыФормы.Результат.Вывести(Область);
КонецПроцедуры
Использование ПолучитьНастройки() вместо прямого обращения к свойству Настройки — это ключ к стабильной работе отчетов в СКД. Помните, что СКД — это динамическая система, и то, что видит пользователь на экране, находится в ПользовательскиеНастройки, а объединить их помогает именно этот метод.