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