Почему не отрабатывает ОбработкаВыбора при вызове формы выбора из внешней обработки 1С?

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

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

Рассмотрим подробно причины такого поведения платформы 1С:Предприятие 8.3 и разберем правильные способы реализации подбора.

Анализ причины: особенности работы БСП и жизненный цикл формы

Выясним, почему процедура выбора не срабатывает при стандартном коде. Обычно проблема кроется в типе команды, зарегистрированной в функции СведенияОВнешнейОбработке() модуля объекта внешней обработки.

Если для команды указан тип ВызовКлиентскогоМетода, механизм БСП работает следующим образом:

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

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

Решение 1. Изменение типа команды на «Открытие формы» (Рекомендуемое)

Чтобы форма внешней обработки оставалась активной в интерфейсе и могла принимать события от подчинённых окон, разберем по шагам перенастройку типа команды.

Шаг 1. В модуле объекта внешней обработки в функции СведенияОВнешнейОбработке() укажем тип команды ОткрытиеФормы:


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

Шаг 2. В модуле формы внешней обработки организуем открытие формы выбора и обработку результата. Поскольку форма обработки теперь открывается штатно, она сохраняет свой контекст:


&НаКлиенте
Процедура ПриОткрытии(Отказ)
    
    // Передаем параметры для открытия формы выбора
    ПараметрыФормы = Новый Структура;
    ПараметрыФормы.Вставить("ЗакрыватьПриВыборе", Истина);
    ПараметрыФормы.Вставить("МножественныйВыбор", Ложь);
    ПараметрыФормы.Вставить("РежимВыбора", Истина);
    
    ОткрытьФорму("Документ.ЗаказНаСборку.ФормаВыбора", ПараметрыФормы, ЭтаФорма);
    
КонецПроцедуры

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

Решение 2. Использование асинхронного оповещения (ОписаниеОповещения)

Если открывать основную форму обработки не требуется и всю логику хочется выполнить асинхронно из вызова клиентского метода, проанализируем использование объекта ОписаниеОповещения.

При использовании этого подхода процедура-обработчик обязательно должна быть помечена ключевым словом Экспорт, а данные контекста передаются через дополнительные параметры описания оповещения:


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

// Процедура должна быть ЭКСПОРТНОЙ
&НаКлиенте
Процедура ОбработкаВыбораЗаказа(РезультатВыбора, ДополнительныеПараметры) Экспорт
    
    Если ЗначениеЗаполнено(РезультатВыбора) Тогда
        // РезультатВыбора содержит выбранный документ
        // ДополнительныеПараметры содержит данные, переданные при открытии
        ИзменитьЗаказНаСборку(РезультатВыбора, ДополнительныеПараметры);
    КонецЕсли;
    
КонецПроцедуры

Проверка сигнатуры процедуры ОбработкаВыбора

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

Если скопировать процедуру элемента формы и привязать её к событию формы, платформа 1С не сможет передать аргументы и вызов процедуры не произойдет.

Резюме

Для корректной работы выбора из внешней обработки выполняйте следующие правила:

  1. При использовании ВызовКлиентскогоМетода не рассчитывайте на сохранение контекста ЭтаФорма. Используйте ОписаниеОповещения с передачей контекста в ДополнительныеПараметры.
  2. Если необходимо работать с реквизитами формы обработки, регистрируйте команду с типом ОткрытиеФормы.
  3. Следите за правильной сигнатурой процедуры-обработчика и наличием ключевого слова Экспорт при использовании асинхронных вызовов.
← На главную