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