Как получить текущую строку открытого документа из внешнего отчета или обработки в управляемых формах 1С?

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

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

Почему возникает ошибка при обращении к свойству «Элементы»?

Проанализируем две основные причины, из-за которых обращение к свойству Элементы или ТекущиеДанные завершается ошибкой платформы:

  1. Разделение контекста выполнения (Клиент / Сервер): коллекция Элементы и свойство строки таблицы ТекущиеДанные существуют исключительно в контексте &НаКлиенте. Если вызов выполняется в модуле объекта, в серверной процедуре (&НаСервере, &НаСервереБезКонтекста) или в общем модуле с признаком выполнения на сервере, платформа выдаст ошибку о том, что свойство не обнаружено.
  2. Особенности метода ПолучитьФорму(): вызов ПолучитьФорму(...) инициализирует новый экземпляр формы в памяти. Однако этот экземпляр не связан с интерактивным окном, в котором работает пользователь. В таком объекте свойство ТекущиеДанные всегда будет равно Неопределено, поскольку пользователь физически не устанавливал фокус на строки внутри программно полученного экземпляра.

В архитектуре управляемого приложения формы изолированы друг от друга. Правильный подход заключается не в попытке «залезть» из внешнего отчета в чужую форму, а в передаче контекста из формы документа в отчет при его открытии.

Способ 1. Получение текущей строки через контекст команды

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

Посмотрим на пример клиентского кода в модуле команды отчета:


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

В данном сценарии мы на клиенте безопасно считываем свойство ТекущиеДанные у табличной части вызывающей формы и передаем полученные значения в структуру параметров открываемого отчета.

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

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

Разберем по шагам реализацию в форме документа:


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

Далее в форме внешнего отчета в серверном обработчике ПриСозданииНаСервере принимаем переданные параметры и применяем их в схеме компоновки данных или реквизитах формы:


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

Альтернативные архитектурные решения

В зависимости от конечной цели разработки стоит рассмотреть следующие стандартные подходы платформы и Библиотеки стандартных подсистем (БСП):

  1. Разработка внешней печатной формы (БСП): если задача сводится к формированию печатной формы расчетного листка, наиболее правильным архитектурным решением является регистрация обработки через механизм дополнительных отчетов и обработок БСП. При вызове печатной формы платформа автоматически передает массив ссылок ОбъектыНазначения в контекст формирования.
  2. Автономные отборы в отчете (СКД): если отчет должен работать и независимо от открытых документов, отборы по документу и сотруднику выносятся в стандартные настройки схемы компоновки данных. Это позволяет пользователю как открывать отчет с предустановленными значениями, так и формировать его вручную с произвольными фильтрами.
← На главную