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