Как правильно установить схему компоновки данных при расшифровке другим отчетом

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке отчетов на системе компоновки данных (СКД) в управляемом приложении 1С часто возникает задача открыть детальный отчет с альтернативной схемой компоновки или конкретным макетом расшифровки. Разработчики нередко сталкиваются с ситуацией, когда после программной инициализации компоновщика настроек на сервере и возврата управления на клиент коллекция доступных полей отбора оказывается пустой, что приводит к ошибкам при установке параметров.

Разберем причины такого поведения платформы и рассмотрим рабочие способы реализации расшифровки с динамической подменой схемы или настроек.

Почему очищаются доступные поля компоновщика на клиенте

Выясним причину возникновения проблемы. В управляемом приложении объект типа СхемаКомпоновкиДанных существует только на сервере и не может быть передан на сторону клиента. Когда в коде на сервере выполняется вызов:


КомпоновщикНастроекР.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(СхемаРасшифровки));

источник доступных настроек связывается с серверным объектом схемы в памяти. Однако при возврате управления на клиент платформа не может сериализовать этот объект схемы, в результате чего ссылка на источник настроек утрачивается, а коллекция ДоступныеПоляОтбора.Элементы на клиенте становится пустой.

Способ 1. Инициализация компоновщика через временное хранилище

Чтобы платформа могла сохранять связь компоновщика с доступными полями схемы между вызовами клиента и сервера, стандартный механизм требует помещать схему во временное хранилище и передавать в источник настроек полученный строковый адрес, а не сам объект схемы.

Рассмотрим, как правильно переписать процедуру инициализации схемы:


&НаСервере
Процедура ИнициализироватьСхему(ФормаРасшифровки)
    
    // Получаем макет нужной схемы компоновки
    СхемаРасшифровки = Отчеты.ОтчетРасшифровка.ПолучитьМакет("Расшифровка");
    
    // Помещаем схему во временное хранилище формы расшифровки
    АдресСхемы = ПоместитьВоВременноеХранилище(СхемаРасшифровки, ФормаРасшифровки.УникальныйИдентификатор);
    
    // Инициализируем компоновщик через строковый адрес
    Компоновщик = ФормаРасшифровки.Отчет.КомпоновщикНастроек;
    Компоновщик.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(АдресСхемы));
    Компоновщик.ЗагрузитьНастройки(СхемаРасшифровки.НастройкиПоУмолчанию);
    
КонецПроцедуры

При таком подходе адрес во временном хранилище корректно сериализуется, и на стороне клиента коллекция КомпоновщикНастроек.Настройки.Отбор.ДоступныеПоляОтбора сохраняет все доступные поля и параметры.

Способ 2. Передача параметров в форму отчета расшифровки

Более правильным с точки зрения архитектуры управляемого приложения является перенос логики загрузки схемы непосредственно в форму открываемого отчета. Вместо модификации компоновщика чужой формы извне передадим в форму расшифровки структуру параметров с именем нужной схемы.

Разберем по шагам реализацию этого механизма:

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

Способ 3. Использование предопределенных вариантов отчета

Если структуры данных в расшифровках концептуально похожи или их можно свести в одну универсальную схему, вместо создания нескольких отдельных макетов СКД проще настроить несколько вариантов отчета внутри одной схемы.

В этом случае открытие нужного варианта выполняется стандартными средствами платформы через передачу ключа варианта:


&НаКлиенте
Процедура РезультатОбработкаРасшифровки(Элемент, Расшифровка, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;
    
    ПараметрыОткрытия = Новый Структура;
    ПараметрыОткрытия.Вставить("КлючВарианта", "ВариантРасшифровки1");
    ПараметрыОткрытия.Вставить("СформироватьПриОткрытии", Истина);
    
    ОткрытьФорму("Отчет.ОтчетРасшифровка.Форма", ПараметрыОткрытия);
    
КонецПроцедуры

Важно: При использовании нескольких вариантов отчета не требуется вручную инициализировать компоновщик настроек и работать с временным хранилищем — платформа выполнит инициализацию автоматически.

Способ 4. Программное формирование отчета без открытия интерактивной формы

Если отчет-расшифровка не требует интерактивной корректировки настроек пользователем, можно полностью сформировать результат на сервере и вывести готовый табличный документ:


&НаСервере
Функция СформироватьОтчетРасшифровкиНаСервере(ЗначениеРасшифровки)
    
    ТабДок = Новый ТабличныйДокумент;
    СхемаСКД = Отчеты.ОтчетРасшифровка.ПолучитьМакет("Расшифровка");
    
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    Настройки = СхемаСКД.НастройкиПоУмолчанию;
    
    // Устанавливаем необходимые параметры или отборы
    ЭлементОтбора = Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
    ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Номенклатура");
    ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
    ЭлементОтбора.ПравоеЗначение = ЗначениеРасшифровки;
    ЭлементОтбора.Использование = Истина;
    
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаСКД, Настройки, , , Тип("ГенераторМакетаКомпоновкиДанных"));
    
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
    
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(ТабДок);
    ПроцессорВывода.Вывести(ПроцессорКомпоновки);
    
    Возврат ТабДок;
    
КонецФункции

Такой подход исключает ошибки контекстной передачи объектов между клиентом и сервером и обеспечивает максимальное быстродействие при формировании расшифровки.

← На главную