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

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

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

Метод 1. Использование механизма БСП «Заполнение формы»

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

Проанализируем процесс регистрации такой обработки. В модуле объекта внешней обработки необходимо описать функцию СведенияОВнешнейОбработке(). Разберем пример кода для регистрации:


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

После регистрации такой команды в интерфейсе документа появится кнопка. При её нажатии БСП сама передаст контекст формы в обработку. Теперь проанализируем, как принять этот контекст в процедуре ВыполнитьКоманду в модуле объекта обработки:


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

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

Метод 2. Интерактивное заполнение через «Вызов клиентского метода»

Если вам требуется интерактивное взаимодействие с пользователем (например, сначала открыть форму самой обработки, дать пользователю что-то выбрать, а потом перенести это в документ), метод «Заполнение формы» может оказаться недостаточным из-за серверного контекста. В этом случае выясним, как использовать тип команды ВызовКлиентскогоМетода.

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

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


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

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


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

Метод 3. Передача данных через временное хранилище (универсальный путь)

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

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

Посмотрим на пример использования КопироватьДанныеФормы, который является наиболее «чистым» с точки зрения платформы способом обновления интерфейса:


&НаСервере
Процедура ОбновитьДанныеИзОбработки(ДанныеИзОбработки)
    // ДанныеИзОбработки - это может быть структура или ДанныеФормыСтруктура
    КопироватьДанныеФормы(ДанныеИзОбработки, Объект);
КонецПроцедуры

Сравнение подходов и выводы

Выясним, какой метод выбрать в зависимости от задачи:

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

← На главную