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