Как получить значение реквизита или таблицу значений из модуля объекта отчета на форму в 1С

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

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

Выясним причину: почему данные «теряются»?

Для начала проанализируем жизненный цикл объекта отчета в управляемом приложении. Когда пользователь нажимает стандартную кнопку «Сформировать», платформа 1С выполняет следующие действия:

  1. На сервере создается новый временный экземпляр объекта отчета.
  2. В этот временный объект копируются настройки из формы (компоновщик настроек).
  3. Вызывается стандартный цикл формирования или процедура ПриКомпоновкеРезультата в модуле объекта.
  4. После того как отчет выведен в табличный документ, этот временный экземпляр объекта уничтожается.

Важный момент: тот объект «Отчет», с которым вы работаете в модуле формы, и тот, который создается для формирования — это разные экземпляры в памяти. Изменения, внесенные в реквизиты объекта внутри ПриКомпоновкеРезультата, не передаются обратно в реквизиты формы автоматически. Именно поэтому автор вопроса видел старое значение «Тест111» вместо нового.

Способ 1: Использование временного хранилища и дополнительных свойств (Рекомендуемый)

Рассмотрим самый надежный способ передачи «тяжелых» данных, таких как ТаблицаЗначений. Поскольку мы не можем напрямую передать таблицу через реквизиты, мы воспользуемся временным хранилищем, а адрес этого хранилища передадим через настройки компоновки.

Разберем реализацию в модуле объекта. В процедуре ПриКомпоновкеРезультата мы помещаем нашу таблицу в хранилище и записываем адрес в ДополнительныеСвойства компоновщика:


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

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


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

Способ 2: Передача простых значений через параметры СКД

Если вам нужно передать не таблицу, а простое значение (строку, число или дату), проанализируем более простой вариант — использование параметров компоновки данных. Вы можете создать в схеме (СКД) параметр, который не будет отображаться пользователю, и записывать значение в него.

В модуле объекта:


Параметр = КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Найти("ИмяВашегоПараметра");
Если Параметр <> Неопределено Тогда
    Параметр.Значение = "Новое значение";
    Параметр.Использование = Истина;
КонецЕсли;

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

Способ 3: Создание собственной кнопки формирования

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

Рассмотрим шаги реализации:

  1. Создаем на форме свою команду и кнопку «Сформировать отчет».
  2. В обработчике команды вызываем серверную процедуру.
  3. В серверной процедуре преобразуем реквизит формы в объект, выполняем формирование и возвращаем объект назад в реквизит формы.

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

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

Когда лучше использовать обработку?

Проанализируем совет из обсуждения на форуме. Если ваша задача состоит в том, чтобы получить данные, сильно их модифицировать «руками» в коде, а затем вывести в особом виде или выполнить с ними бизнес-действия — возможно, архитектура «Отчета» вам не подходит.

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

Резюмируем: для передачи данных из модуля отчета на форму используйте Временное хранилище и передавайте адрес через Дополнительные свойства компоновщика. Это наиболее корректный путь, который работает даже при фоновом выполнении отчетов в современных конфигурациях.

← На главную