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

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

При разработке внешних обработок и печатных форм для управляемого приложения 1С разработчики часто сталкиваются с ситуацией, когда код отлично работает в толстом клиенте, но выдает ошибку в тонком клиенте. Например, при попытке получить выбранного сотрудника из табличной части документа вылетает исключение: «Значение не является значением объектного типа (Элементы)».

Рассмотрим причину возникновения этой проблемы и разберем правильные архитектурные подходы для получения данных активной строки документа.

Выясним причину ошибки: почему код не работает на сервере

Проанализируем, почему вызов ФормаДок.Элементы.Начисления.ТекущиеДанные приводит к ошибке при исполнении серверного кода:

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

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

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

Для реализации этого способа во внешней обработке обязательно должна быть создана управляемая форма.

Рассмотрим пошаговый алгоритм реализации:

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

Посмотрим на пример кода в модуле формы внешней обработки:


&НаСервере
Процедура ПечатьСотрудникаНаСервере(Сотрудник)
    // Формирование отчета или печатной формы по конкретному сотруднику
    // Здесь доступен контекст сервера, выполнение запросов и макетов
КонецПроцедуры

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

Способ 2. Получение данных активной строки через ВладелецФормы при вызове из БСП

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

В модуле формы внешней обработки создается экспортная процедура Печать:


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

Обработка множественного выделения строк

Если пользователю необходимо напечатать расчетные листки сразу по нескольким выделенным строкам в табличной части, свойство ТекущиеДанные не подойдет, так как оно возвращает только один активный элемент. В этом случае на клиенте следует использовать свойство ВыделенныеСтроки:


&НаКлиенте
Процедура ПечатьВыделенныхСотрудников()
    
    МассивСотрудников = Новый Массив;
    ФормаДокумента = ВладелецФормы;
    
    Для Каждого ИдентификаторСтроки Из ФормаДокумента.Элементы.Начисления.ВыделенныеСтроки Цикл
        СтрокаТаблицы = ФормаДокумента.Объект.Начисления.НайтиПоИдентификатору(ИдентификаторСтроки);
        Если СтрокаТаблицы <> Неопределено Тогда
            МассивСотрудников.Добавить(СтрокаТаблицы.Сотрудник);
        КонецЕсли;
    КонецЦикла;
    
    СформироватьОтчетПоМассивуНаСервере(МассивСотрудников);
    
КонецПроцедуры

Подведем итоги

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

← На главную