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

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

Переход с обычных форм на управляемые часто вызывает вопросы у разработчиков, привыкших к прямой передаче объектов. В обычных формах (ОФ) процедура Инициализировать предоставляла прямой доступ к ТабличноеПолеОбъекта.ТекущиеДанные. Однако в управляемом приложении (УФ) и при использовании Библиотеки стандартных подсистем (БСП) механизм вызова внешних обработок изменился. Рассмотрим подробно, как получить доступ к текущей строке табличной части в новых условиях.

Различие подходов: Обычные формы vs Управляемые формы

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

Инициализировать(Объект, ИмяТабличнойЧасти, ТабличноеПолеОбъекта)

Здесь ТабличноеПолеОбъекта позволяло сразу обратиться к ТекущиеДанные. В управляемых формах основным методом выполнения команды является:

ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначенияМассив)

Параметр ОбъектыНазначенияМассив содержит лишь ссылки на документы, что недостаточно для получения данных конкретной строки, на которой в данный момент стоит курсор пользователя. Выясним, как обойти это ограничение.

Способ 1: Использование свойства ВладелецФормы

Самый простой путь на клиентской стороне — это обращение к владельцу формы. Когда внешняя обработка открывается из формы документа, она сохраняет связь с вызвавшей её формой. Разберем пример кода, который позволяет получить данные строки:


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

Важный нюанс: этот метод работает корректно, если тип команды в функции СведенияОВнешнейОбработке указан как ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовКлиентскогоМетода().

Способ 2: Использование параметров выполнения команды БСП

Современные версии БСП (начиная с 2.x и 3.x) передают в обработку дополнительные параметры контекста. Рассмотрим подробнее структуру ПараметрыВыполненияКоманды. Это наиболее надежный и "чистый" с точки зрения архитектуры БСП способ.

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


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

Способ 3: Работа с данными на сервере через идентификатор строки

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

Посмотрим на пример серверной реализации:


&НаСервере
Процедура ОбработатьСтрокуНаСервере(СсылкаНаДокумент, ИдентификаторСтроки)
    
    // Загружаем объект документа
    ДокОбъект = СсылкаНаДокумент.ПолучитьОбъект();
    
    // Находим строку в табличной части "Товары" по ID
    СтрокаТЧ = ДокОбъект.Товары.НайтиПоИдентификатору(ИдентификаторСтроки);
    
    Если СтрокаТЧ <> Неопределено Тогда
        // Выполняем действия, например, меняем цену
        СтрокаТЧ.Цена = СтрокаТЧ.Цена * 1.1; 
        ДокОбъект.Записать();
    КонецЕсли;
    
КонецПроцедуры

Регистрация обработки для доступа к контексту

Чтобы описанные выше механизмы работали, необходимо правильно заполнить функцию СведенияОВнешнейОбработке в модуле объекта обработки. Выясним основные параметры:

  1. Вид: должен быть ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиЗаполнениеОбъекта() или СозданиеСвязанныхОбъектов().
  2. Использование: для прямого доступа к экранным формам лучше использовать ВызовКлиентскогоМетода.
  3. Безопасный режим: если обработка работает в безопасном режиме, доступ к некоторым свойствам ВладелецФормы может быть ограничен. Рекомендуется регистрировать обработку с разрешением на работу с внешними ресурсами, если планируется глубокое взаимодействие с формой.

Пример настройки команды:


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

Возможные проблемы и пути решения

Рассмотрим ситуацию, когда ВладелецФормы не задан. Такое случается при специфических способах вызова. В этом случае мы можем проанализировать все открытые окна системы и найти нужное по ссылке из ОбъектыНазначенияМассив. Однако это "тяжелый" путь, которого стоит избегать, правильно проектируя вызов обработки через стандартные механизмы БСП.

Также важно помнить, что если ваша задача — заполнить данные в форме до записи объекта, следует использовать тип команды ЗаполнениеФормы. В этом случае БСП автоматически передаст контекст формы в обработку, и вы сможете работать с данными формы как с объектом ДанныеФормыСтруктура.

Итог: Для получения "ТекущихДанных" в УФ используйте клиентский метод вызова, обращайтесь к ПараметрыВыполненияКоманды.ЭтаФорма или ВладелецФормы, и всегда оперируйте идентификаторами строк (ID) при передаче данных между клиентом и сервером.

← На главную