Как передать данные между формами внешней обработки в управляемом приложении 1С

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

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

Шаг 1. Подключение внешней обработки и открытие формы

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


&НаСервере
Функция ПодключитьНаСервере()
    // Получаем двоичные данные обработки и помещаем в хранилище
    ДвоичныеДанныеОбработки = Новый ДвоичныеДанные(РеквизитФормыВЗначение("Объект").ИспользуемоеИмяФайла);
    АдресХранилища = ПоместитьВоВременноеХранилище(ДвоичныеДанныеОбработки);
    
    // Подключаем внешнюю обработку и возвращаем её имя
    ИмяВнешнейОбработки = ВнешниеОбработки.Подключить(АдресХранилища);      
    Возврат ИмяВнешнейОбработки;
КонецФункции

&НаКлиенте
Процедура ОткрытьДополнительнуюФорму()
    Если ПустаяСтрока(ИмяВнешнейОбработки) Тогда
        ИмяВнешнейОбработки = ПодключитьНаСервере();
    КонецЕсли;

    // Подготовка параметров для передачи в новую форму
    ПараметрыФормы = Новый Структура;  
    ПараметрыФормы.Вставить("ПараметрШтрихКод", Объект.ШтрихКодПоиск);

    // Открываем форму, указывая текущую форму в качестве владельца (3-й параметр)
    // РежимОткрытияОкнаФормы.БлокироватьОкноВладельца имитирует модальность для пользователя
    ОткрытьФорму("ВнешняяОбработка." + ИмяВнешнейОбработки + ".Форма.ФормаНоменклатуры", 
                 ПараметрыФормы, 
                 ЭтаФорма, 
                 УникальныйИдентификатор, 
                 , , , 
                 РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
КонецПроцедуры

Шаг 2. Получение параметров в дополнительной форме

После открытия формы нам нужно считать переданные данные. Это происходит на сервере в обработчике ПриСозданииНаСервере. Мы обращаемся к свойству Параметры, в котором хранятся ключи структуры, переданной при вызове ОткрытьФорму.


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

Шаг 3. Возврат данных в основную форму

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


&НаКлиенте
Процедура ПодтвердитьИЗакрыть(Команда)
    // Сохраняем данные на сервере и получаем адрес во временном хранилище
    АдресРезультата = ПоместитьДанныеВХранилищеНаСервере();
    
    // Формируем структуру с ответом
    Результат = Новый Структура("АдресДанных", АдресРезультата);
    
    // Оповещаем владельца (основную форму) о сделанном выборе
    ОповеститьОВыборе(Результат);
КонецПроцедуры

&НаСервере
Функция ПоместитьДанныеВХранилищеНаСервере()
    ТаблицаДляПередачи = Объект.Товары.Выгрузить();
    
    // ВАЖНО: Не используйте УникальныйИдентификатор текущей (дочерней) формы!
    // Если его указать, данные удалятся из хранилища сразу после закрытия этой формы.
    Возврат ПоместитьВоВременноеХранилище(ТаблицаДляПередачи);
КонецФункции

Шаг 4. Обработка результата в основной форме

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


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

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

Разбор ошибки «Неизвестный идентификатор формы»

Проанализируем ситуацию, когда при попытке вызвать серверный метод из ОбработкаВыбора система выдает ошибку «Неизвестный идентификатор формы». Рассмотрим основные причины возникновения этой проблемы:

  1. Очистка временного хранилища: Если при вызове ПоместитьВоВременноеХранилище во второй форме вы передали УникальныйИдентификатор этой самой формы, то в момент закрытия окна данные удаляются. Когда основная форма пытается их прочитать, они уже отсутствуют. Решение: вызывайте метод без второго параметра или передавайте идентификатор основной формы.
  2. Потеря контекста внешней обработки: Платформа 1С иногда теряет связь с динамически подключенным объектом внешней обработки после закрытия одного из его окон. Чтобы гарантировать стабильность, убедитесь, что имя подключенной обработки (ИмяВнешнейОбработки) сохранено в реквизите основной формы и используется при каждом серверном вызове.
  3. Жизненный цикл объекта: Если серверный метод, вызываемый из ОбработкаВыбора, обращается к методам самого объекта обработки (через РеквизитФормыВЗначение("Объект")), убедитесь, что обработка все еще «подключена» в текущем сеансе.

Для более надежной работы в современных версиях платформы рекомендуется также рассмотреть использование метода ОткрытьФорму с параметром ОписаниеОповещенияОЗакрытии. Это позволит обрабатывать результат закрытия в отдельной процедуре-коллбэке, что является наиболее стабильным способом передачи данных в асинхронном режиме управляемого приложения.

← На главную