В процессе разработки на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда стандартный механизм ОписаниеОповещения при открытии формы выбора возвращает Неопределено. Особенно часто это проявляется в типовых конфигурациях, таких как Зарплата и Управление Персоналом 3.1, при работе со справочником ПодразделенияОрганизаций. Разберем подробно, почему это происходит и какими способами можно гарантированно получить результат выбора.
Рассмотрим типовой код, который на первый взгляд выглядит абсолютно корректным. Программист пытается открыть форму выбора с возможностью множественного подбора и передает описание оповещения для обработки результата:
&НаКлиенте
Процедура ПодборПодразделений(Команда)
ПараметрыОткрытия = Новый Структура;
ПараметрыОткрытия.Вставить("ЗакрыватьПриВыборе", Ложь);
ПараметрыОткрытия.Вставить("ЗакрыватьПриЗакрытииВладельца", Истина);
ПараметрыОткрытия.Вставить("МножественныйВыбор", Истина);
ПараметрыОткрытия.Вставить("РежимВыбора", Истина);
ткОповещение = Новый ОписаниеОповещения("ПодборПодразделенийЗавершение", ЭтотОбъект);
ОткрытьФорму("Справочник.ПодразделенияОрганизаций.ФормаВыбора", ПараметрыОткрытия, ЭтотОбъект, , , , ткОповещение);
КонецПроцедуры
&НаКлиенте
Процедура ПодборПодразделенийЗавершение(РезультатВыбора, Параметры) Экспорт
// Здесь РезультатВыбора оказывается Неопределено
КонецПроцедуры
Проанализируем ситуацию. Основная причина кроется в сочетании параметра ЗакрыватьПриВыборе = Ложь и логики самой формы выбора. Когда мы устанавливаем ЗакрыватьПриВыборе = Ложь, платформа ожидает, что форма останется открытой для выбора нескольких элементов. В этом режиме стандартное закрытие формы с передачей результата в ОписаниеОповещения часто не срабатывает автоматически, так как форма «не знает», в какой момент выбор окончательно завершен пользователем.
Выясним важный технический нюанс: когда в форме выбора вызывается метод ОповеститьОВыборе(), данные передаются не в обратный вызов (callback) ОткрытьФорму, а в событие ОбработкаВыбора той формы, которая была указана владельцем (третий параметр в ОткрытьФорму).
Рассмотрим, как правильно реализовать получение данных через этот механизм. В вызывающей форме (владельце) необходимо создать обработчик события:
&НаКлиенте
Процедура ОбработкаВыбора(ВыбранноеЗначение, ИсточникВыбора)
Если ТипЗнч(ВыбранноеЗначение) = Тип("Массив") Тогда
// Обрабатываем список выбранных подразделений
Для Каждого Элемент Из ВыбранноеЗначение Цикл
Сообщить("Выбрано подразделение: " + Элемент);
КонецЦикла;
ИначеЕсли ЗначениеЗаполнено(ВыбранноеЗначение) Тогда
Сообщить("Выбрано: " + ВыбранноеЗначение);
КонецЕсли;
КонецПроцедуры
Важно: Чтобы этот метод сработал, при вызове ОткрытьФорму в качестве третьего параметра (Владелец) обязательно должен быть передан ЭтотОбъект или ЭтаФорма. Если владелец не указан, событие ОбработкаВыбора не будет вызвано.
Проанализируем специфику конфигурации ЗУП 3.1. Для справочника ПодразделенияОрганизаций часто используются специализированные формы, которые могут вести себя не так, как стандартные формы выбора. В некоторых случаях форма вообще не содержит обработчика кнопки «Выбрать», если она открыта не в режиме выбора.
Если вы обнаружили, что ОбработкаВыбора не срабатывает, стоит проверить, какая именно форма открывается. Попробуйте явно указать путь к форме:
ОткрытьФорму("Справочник.ПодразделенияОрганизаций.Форма.ФормаВыбора", ...)
Также обратите внимание на сообщение в обсуждении: в ЗУП для подразделений часто используется механизм Оповестить() вместо ОповеститьОВыборе(). Это глобальное оповещение, которое можно перехватить через ОбработкаОповещения.
Если форма выбора после нажатия кнопки «ОК» или «Выбрать» выполняет программный код Оповестить("СобытиеВыбораПодразделений", Результат), то нам нужно использовать другой механизм перехвата данных. Разберем по шагам:
ОбработкаОповещения.
&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
Если ИмяСобытия = "ВыборПодразделений" Тогда
// Допустим, форма выбора отправила массив подразделений
РезультатВыбора = Параметр;
// Ваша логика обработки
КонецЕсли;
КонецПроцедуры
Чтобы минимизировать ошибки при получении Неопределено, придерживайтесь следующих правил при формировании структуры ПараметрыОткрытия:
Истина, чтобы форма понимала свой контекст.Истина. Помните, что в этом случае результатом обычно будет Массив, а не одиночная ссылка.Истина. Если вы делаете подбор (выбираете много элементов, не закрывая окно), ставьте Ложь, но тогда результат обрабатывайте через ОбработкаВыбора или ОбработкаОповещения.ЭтотОбъект (текущую форму) в ОткрытьФорму, чтобы система знала, куда «вернуть» результат.Подведем итог: если ОписаниеОповещения возвращает Неопределено, скорее всего, форма выбора не закрывается стандартным образом с возвратом значения через Закрыть(). В этом случае вашим основным инструментом становится событие ОбработкаВыбора в вызывающей форме. Это наиболее надежный способ работы с подбором в управляемом интерфейсе 1С.