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