Как правильно передать и получить параметр в отчете СКД на обычных формах 1С 8.2 / 8.3

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

При разработке в среде 1С:Предприятие 8.2 (а также 1С 8.3 при использовании обычных форм, например, в конфигурациях ЗУП 2.5, УПП 1.3 или КА 1.1) программисты часто сталкиваются с необходимостью открыть отчет на базе Системы компоновки данных (СКД) программно из документа или другой формы и передать в него определенный параметр (например, ссылку на текущий документ или выбранную организацию). Для автоматизации подобного сценария подойдёт решение для заполнения параметров и отборов отчетов данными из документов.

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

Анализ и разбор типичных ошибок из практики

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

Ошибка первая: Попытка прямой записи в несуществующее свойство формы

Автор пытается передать параметр напрямую в форму отчета следующим кодом:


Форма = Отчеты.Показатели.ПолучитьФорму("ФормаОтчета"); 
Форма.Параметр = Док; // Вызывает ошибку "Поле объекта не обнаружено (Параметр)"

Выясним причину: в обычных формах 1С объект Форма не имеет предопределенного свойства Параметр. Форма может принимать параметры только в том случае, если в ее метаданных (вкладка "Реквизиты" формы) явно создан соответствующий реквизит (например, с именем Док или ДокументДляОтбора), либо если мы обращаемся напрямую к свойствам отчета через свойство формы ЭтотОбъект (или Отчет).

Ошибка вторая: Отключение параметра через Использование = Ложь

Попытка инициализировать параметр СКД в коде автора выглядит так:


Док2 = КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Find("Док");
Док2.Использование = Ложь; // Критическая ошибка!
Док2.Значение = Док;

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

Ошибка третья: Обращение к ЭлементыФормы в модуле объекта

При попытке переопределить формирование отчета в процедуре ПриКомпоновкеРезультата автор использует код:


ПроцессорВывода.УстановитьДокумент(ЭлементыФормы.Результат); // Ошибка: Переменная не определена (ЭлементыФормы)

Это классическая ошибка нарушения контекста. Метод ПриКомпоновкеРезультата выполняется в модуле объекта отчета. Модуль объекта работает на сервере и ничего не знает о визуальном интерфейсе, экранных формах и их элементах. Коллекция ЭлементыФормы доступна исключительно внутри модуля формы. Попытка обратиться к ней из модуля объекта всегда будет приводить к аварийному завершению работы программы.

---

Способ 1. Передача значения через реквизит формы (Рекомендуемый способ)

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

Шаг 1. Подготовка формы отчета

Откройте форму отчета в конфигураторе. На вкладке "Реквизиты" добавьте новый реквизит формы. Назовем его, например, ДокументОтбора и укажем соответствующий тип данных (например, ссылку на ваш документ).

Шаг 2. Вызов формы из документа

В модуле формы документа (или в его команде) напишем код для открытия отчета и передачи ссылки на текущий документ в созданный реквизит формы отчета:


СсылкаНаДокумент = ЭтотОбъект.Ссылка; 
ФормаОтчета = Отчеты.Показатели.ПолучитьФорму("ФормаОтчета"); 

// Передаем значение в реквизит формы
ФормаОтчета.ДокументОтбора = СсылкаНаДокумент; 
ФормаОтчета.Открыть();

Шаг 3. Обработка параметра при открытии формы

В модуле формы отчета найдем или создадим обработчик события ПриОткрытии. В нем мы считаем переданное значение и установим его в настройки компоновщика СКД:


Процедура ПриОткрытии()
    
    Если ЗначениеЗаполнено(ДокументОтбора) Тогда
        
        // Используем встроенный метод компоновщика для надежной установки параметра
        // Этот метод автоматически устанавливает Использование = Истина
        КомпоновщикНастроек.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("Док", ДокументОтбора);
        
    КонецЕсли;
    
КонецПроцедуры

Использование метода УстановитьЗначениеПараметра() является наилучшей практикой, так как оно избавляет нас от ручного поиска элемента в коллекции параметров через метод Найти() и гарантирует автоматическую установку флага Использование в значение Истина.

---

Способ 2. Учет Пользовательских настроек СКД

Проанализируем важный нюанс: если параметр "Док" вынесен разработчиком в область быстрых настроек отчета на форме (так называемые Пользовательские настройки), то простое изменение свойства КомпоновщикНастроек.Настройки в процедуре ПриОткрытии может не отобразиться визуально на форме, либо будет перетерто значениями по умолчанию из пользовательских настроек.

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


Процедура ПриОткрытии()
    
    Если ЗначениеЗаполнено(ДокументОтбора) Тогда
        
        // 1. Устанавливаем параметр в основных настройках схемы
        КомпоновщикНастроек.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("Док", ДокументОтбора);
        
        // 2. Ищем и обновляем этот же параметр в пользовательских настройках
        Для Каждого Элемент Из КомпоновщикНастроек.ПользовательскиеНастройки.Elements Цикл
            
            Если ТипЗнч(Элемент) = Тип("ЗначениеПараметраКомпоновкиДанных") 
               И Строка(Элемент.Параметр) = "Док" Тогда
                
                Элемент.Значение = ДокументОтбора;
                Элемент.Использование = Истина;
                Прервать; // Искомый параметр найден и изменен, прерываем цикл
                
            КонецЕсли;
            
        КонецЦикла;
        
    КонецЕсли;
    
КонецПроцедуры

---

Способ 3. Передача параметров через модуль объекта отчета (ПриКомпоновкеРезультата)

Иногда требуется принудительно устанавливать параметры отчета непосредственно в момент генерации, независимо от того, какая форма открыта и запускается ли отчет интерактивно или программно (например, в фоновом задании). Для этого используется предопределенный обработчик ПриКомпоновкеРезультата в модуле объекта отчета.

Для реализации этого способа нам понадобится создать реквизит не формы, а самого отчета (в метаданных объекта "Отчет"). Назовем его ДокументОбъекта.

Вызов из документа в этом случае будет выглядеть так:


ДокСсылка = ЭтотОбъект.Ссылка; 
ФормаОтчета = Отчеты.Показатели.ПолучитьФорму("ФормаОтчета"); 

// Обращаемся к реквизиту самого объекта отчета через свойство Отчет (или ЭтотОбъект на форме)
ФормаОтчета.Отчет.ДокументОбъекта = ДокСсылка; 
ФормаОтчета.Открыть();

Теперь исправим код в модуле объекта отчета, избегая ошибок контекста, с которыми столкнулся автор в сообщении 17. Мы заменим обращение к элементам формы на использование переданного в процедуру табличного документа ДокументРезультат:


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

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

---

Особенности работы в типовых конфигурациях (ЗУП 2.5, УПП 1.3)

Если вы работаете в доработанной конфигурации ЗУП 2.5, имейте в виду, что большинство отчетов там используют универсальный программный механизм ТиповыеОтчеты. При открытии таких отчетов система автоматически пытается восстановить настройки последнего сеанса пользователя, что может перезаписать установленные нами программно параметры.

Чтобы обойти эту особенность, принудительное заполнение параметров в модуле формы отчета (обработчик ПриОткрытии) следует выполнять в самом конце процедуры, после того как отработают все типовые вызовы инициализации панели пользователя и восстановления сохраненных настроек.

Резюме и правила хорошего тона при работе с СКД

Подведем итоги нашей совместной работы и составим краткий чек-лист по программному управлению параметрами в системе компоновки данных:

  1. Разделяйте контексты: никогда не используйте ЭлементыФормы в модуле объекта (включая метод ПриКомпоновкеРезультата). Для вывода всегда применяйте переданную переменную ДокументРезультат.
  2. Не забывайте про использование: при программной установке значения параметра всегда проверяйте, чтобы свойство Использование было установлено в Истина. Без этого параметр не применится к запросу.
  3. Используйте безопасные методы: метод компоновщика настроек УстановитьЗначениеПараметра() предпочтительнее прямого поиска элемента через Элементы.Найти(), так как он сам заботится о включении использования параметра и валидации имени.
  4. Следите за пользовательскими настройками: если параметр доступен пользователю на форме для быстрого редактирования, обязательно дублируйте установку его значения в коллекции ПользовательскиеНастройки.Elements.
← На главную