В процессе работы с полем ввода могут возникнуть самые разные ситуации, связанные с обработкой ввода по строке или автоподбора.
Как мы уже говорили, ввод по строке возможен только для ссылочных значений. Однако автоподбор и окончание ввода текста отрабатываются для любых типов в поле ввода.
Поэтому, например, поле ввода может иметь строковый тип, но в обработчике события Автоподбор может анализироваться один или несколько справочников, из которых будет получаться список элементов, соответствующих введенной подстроке.
Другой случай, когда поле ввода имеет ссылочный тип и при обработке события Обработка получения данных выбора в модуле менеджера объекта еще до того, как платформа сформирует список выбора, необходимо получить этот список для модификации.
Для таких особенных случаев у менеджеров прикладных объектов конфигурации существуют методы ПолучитьДанныеВыбора(). Эти методы полностью имитируют формирование списка выбора платформой, вплоть до вызова события Обработка получения данных выбора.
Такой метод есть и в глобальном контексте. В его параметре нужно указывать тип объекта, для которого он должен быть вызван.
В использовании этих методов нет ничего сложного, за исключением того случая, когда этот метод вызывается в обработчике Обработка получения данных выбора. Если не предпринять специальных действий, это приведет к бесконечной рекурсии. Но от нее можно избавиться довольно простым способом. Рассмотрим это на примере.
Примечание
Пример можно посмотреть в демонстрационной базе «Поле ввода», документ Накладная, реквизит Поставщик. В модуле менеджера справочника Поставщики снять комментарии с варианта «Пример 2».
Рассмотрим следующий обработчик в модуле менеджера справочника Поставщики (листинг 3.155).
Листинг 3.155. Обработчик события «Обработка получения данных выбора»
Процедура ОбработкаПолученияДанныхВыбора(ДанныеВыбора, Параметры, СтандартнаяОбработка)
// Если это рекурсивный вызов – ничего не делать.
Если НЕ Параметры.Свойство("Рекурсия") Тогда
СтандартнаяОбработка = Ложь;
// Получить стандартный список выбора.
Параметры.Вставить("Рекурсия");
СтандартныйСписок = ПолучитьДанныеВыбора(Параметры);
// Добавить к стандартному списку собственный элемент.
ДополнительныйЭлемент = Справочники.Поставщики.НайтиПоКоду("000000003");
СтандартныйСписок.Добавить(ДополнительныйЭлемент);
ДанныеВыбора = СтандартныйСписок;
КонецЕсли;
КонецПроцедуры
Для защиты от рекурсии перед вызовом метода ПолучитьДанныеВыбора() в структуру параметров будем добавлять служебный параметр с ключом Рекурсия.
Весь код, написанный в обработчике, будем выполнять только в том случае, если в параметрах отсутствует элемент Рекурсия, т. е. при первом «заходе» в этот обработчик (листинг 3.156).
Листинг 3.156. Проверка на отсутствие рекурсии
Если НЕ Параметры.Свойство("Рекурсия") Тогда
При втором заходе в этот обработчик (когда платформа будет формировать стандартный список выбора) в параметрах уже будет присутствовать элемент Рекурсия. Таким образом, никакой код выполняться не будет (листинг 3.157).
Листинг 3.157. Добавление элемента «Рекурсия» в данные выбора
Параметры.Вставить("Рекурсия");
СтандартныйСписок = ПолучитьДанныеВыбора(Параметры);
После получения стандартного списка мы добавляем в него еще одного поставщика, который нам очень нравится и, возможно, пригодится пользователю для выбора (листинг 3.158).
Листинг 3.158. Добавление «собственного» поставщика
ДополнительныйЭлемент = Справочники.Поставщики.НайтиПоКоду("000000003");
СтандартныйСписок.Добавить(ДополнительныйЭлемент);
И в конце полученный список помещаем в переменную ДанныеВыбора. Так как в начале мы отказались от стандартной обработки, именно этот список и будет показан пользователю (рис. 3.202).

Рис. 3.202. Список поставщиков, предложенных для выбора