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