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