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