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