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