Переход с обычных форм на управляемые часто вызывает вопросы у разработчиков, привыкших к прямой передаче объектов. В обычных формах (ОФ) процедура Инициализировать предоставляла прямой доступ к ТабличноеПолеОбъекта.ТекущиеДанные. Однако в управляемом приложении (УФ) и при использовании Библиотеки стандартных подсистем (БСП) механизм вызова внешних обработок изменился. Рассмотрим подробно, как получить доступ к текущей строке табличной части в новых условиях.
В обычных формах при подключении обработки заполнения табличных частей система передавала конкретную ссылку на элемент управления. Проанализируем стандартную сигнатуру старого метода:
Инициализировать(Объект, ИмяТабличнойЧасти, ТабличноеПолеОбъекта)
Здесь ТабличноеПолеОбъекта позволяло сразу обратиться к ТекущиеДанные. В управляемых формах основным методом выполнения команды является:
ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначенияМассив)
Параметр ОбъектыНазначенияМассив содержит лишь ссылки на документы, что недостаточно для получения данных конкретной строки, на которой в данный момент стоит курсор пользователя. Выясним, как обойти это ограничение.
Самый простой путь на клиентской стороне — это обращение к владельцу формы. Когда внешняя обработка открывается из формы документа, она сохраняет связь с вызвавшей её формой. Разберем пример кода, который позволяет получить данные строки:
&НаКлиенте
Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначенияМассив)
// Получаем форму документа, из которой вызвана обработка
ФормаДокумента = ВладелецФормы;
Если ФормаДокумента <> Неопределено Тогда
// Предположим, табличная часть называется "Товары"
ТекущиеДанные = ФормаДокумента.Элементы.Товары.ТекущиеДанные;
Если ТекущиеДанные <> Неопределено Тогда
Сообщить("Выбрана номенклатура: " + ТекущиеДанные.Номенклатура);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Важный нюанс: этот метод работает корректно, если тип команды в функции СведенияОВнешнейОбработке указан как ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовКлиентскогоМетода().
Современные версии БСП (начиная с 2.x и 3.x) передают в обработку дополнительные параметры контекста. Рассмотрим подробнее структуру ПараметрыВыполненияКоманды. Это наиболее надежный и "чистый" с точки зрения архитектуры БСП способ.
В клиентском обработчике команды можно получить доступ к форме через свойство ЭтаФорма, которое передается в параметрах. Проанализируем ситуацию, когда нам нужно передать данные на сервер для обработки:
&НаКлиенте
Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначенияМассив, ПараметрыВыполненияКоманды)
// Получаем контекст вызывающей формы
Источник = ПараметрыВыполненияКоманды.ЭтаФорма;
// Определяем имя таблицы (может быть передано в параметрах или зашито жестко)
ИмяТаблицы = "Товары";
ЭлементТаблица = Источник.Элементы[ИмяТаблицы];
// Получаем идентификатор текущей строки
ИдентификаторСтроки = ЭлементТаблица.ТекущаяСтрока;
Если ИдентификаторСтроки <> Неопределено Тогда
// Передаем данные на сервер для логики
ОбработатьСтрокуНаСервере(ОбъектыНазначенияМассив[0], ИдентификаторСтроки);
КонецЕсли;
КонецПроцедуры
Часто программисты допускают ошибку, пытаясь найти строку по индексу. В управляемом приложении свойство ТекущаяСтрока возвращает не индекс (0, 1, 2...), а внутренний идентификатор строки. Чтобы получить данные этой строки на сервере, необходимо использовать метод НайтиПоИдентификатору().
Посмотрим на пример серверной реализации:
&НаСервере
Процедура ОбработатьСтрокуНаСервере(СсылкаНаДокумент, ИдентификаторСтроки)
// Загружаем объект документа
ДокОбъект = СсылкаНаДокумент.ПолучитьОбъект();
// Находим строку в табличной части "Товары" по ID
СтрокаТЧ = ДокОбъект.Товары.НайтиПоИдентификатору(ИдентификаторСтроки);
Если СтрокаТЧ <> Неопределено Тогда
// Выполняем действия, например, меняем цену
СтрокаТЧ.Цена = СтрокаТЧ.Цена * 1.1;
ДокОбъект.Записать();
КонецЕсли;
КонецПроцедуры
Чтобы описанные выше механизмы работали, необходимо правильно заполнить функцию СведенияОВнешнейОбработке в модуле объекта обработки. Выясним основные параметры:
ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиЗаполнениеОбъекта() или СозданиеСвязанныхОбъектов().ВызовКлиентскогоМетода.ВладелецФормы может быть ограничен. Рекомендуется регистрировать обработку с разрешением на работу с внешними ресурсами, если планируется глубокое взаимодействие с формой.Пример настройки команды:
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.2.2.1");
НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
НоваяКоманда.Представление = "Заполнить текущую строку (УФ)";
НоваяКоманда.Идентификатор = "ЗаполнениеСтроки";
НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовКлиентскогоМетода();
НоваяКоманда.ПоказыватьОповещение = Истина;
Возврат ПараметрыРегистрации;
КонецФункции
Рассмотрим ситуацию, когда ВладелецФормы не задан. Такое случается при специфических способах вызова. В этом случае мы можем проанализировать все открытые окна системы и найти нужное по ссылке из ОбъектыНазначенияМассив. Однако это "тяжелый" путь, которого стоит избегать, правильно проектируя вызов обработки через стандартные механизмы БСП.
Также важно помнить, что если ваша задача — заполнить данные в форме до записи объекта, следует использовать тип команды ЗаполнениеФормы. В этом случае БСП автоматически передаст контекст формы в обработку, и вы сможете работать с данными формы как с объектом ДанныеФормыСтруктура.
Итог: Для получения "ТекущихДанных" в УФ используйте клиентский метод вызова, обращайтесь к ПараметрыВыполненияКоманды.ЭтаФорма или ВладелецФормы, и всегда оперируйте идентификаторами строк (ID) при передаче данных между клиентом и сервером.