Как сделать реквизит справочника уникальным в 1С?

Программист 1С v8.3 (Управляемые формы) Управленческий учет Торговля и дистрибуция
← На главную

При разработке конфигураций на платформе 1С часто возникает задача ограничить ввод дублирующихся данных. Самый распространенный пример — артикул товара. Мы хотим, чтобы один и тот же артикул нельзя было присвоить двум разным элементам справочника. Давайте разберем, как реализовать этот механизм правильно и надежно.

Почему не стоит использовать обработчик «ПередЗаписью»?

Многие начинающие разработчики пытаются реализовать проверку в событии ПередЗаписью. Однако это не совсем корректно с точки зрения архитектуры платформы. Событие ПередЗаписью вызывается уже непосредственно в процессе записи объекта, когда транзакция может быть инициирована. Гораздо правильнее использовать событие ОбработкаПроверкиЗаполнения, которое срабатывает до того, как начнется выполнение каких-либо действий по записи в базу данных.

Реализация проверки в модуле объекта

Рассмотрим пошагово, как реализовать проверку уникальности в модуле объекта справочника. Нам необходимо создать обработчик события ОбработкаПроверкиЗаполнения. Важно помнить, что код должен находиться именно в модуле объекта, а не в модуле формы, так как проверка должна срабатывать при любом способе записи (например, при групповом импорте или записи программным методом).

Для реализации логики мы будем использовать запрос к таблице справочника. Критически важный момент — это исключение самого себя из выборки, иначе система всегда будет видеть текущий элемент как дубликат.

Ниже представлен пример кода, который необходимо разместить в модуле объекта:


Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
    // Пропускаем проверку, если данные загружаются обменом
    Если ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;

    // Формируем запрос для поиска дублей
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	Товары.Ссылка
        |ИЗ
        |	Справочник.Товары КАК Товары
        |ГДЕ
        |	Товары.Артикул = &Артикул
        |	И НЕ Товары.Ссылка = &Ссылка";

    Запрос.УстановитьПараметр("Артикул", Артикул);
    Запрос.УстановитьПараметр("Ссылка", Ссылка);

    РезультатЗапроса = Запрос.Выполнить();

    // Если запрос вернул результат, значит артикул занят
    Если НЕ РезультатЗапроса.Пустой() Тогда
        Отказ = Истина;
        Сообщение = Новый СообщениеПользователю;
        Сообщение.Текст = "Ошибка! Артикул '" + Артикул + "' уже используется другим товаром.";
        Сообщение.Поле = "Артикул";
        Сообщение.Сообщить();
    КонецЕсли;
КонецПроцедуры

Разбор ключевых моментов решения

  1. Проверка ОбменДанными.Загрузка: Всегда добавляйте это условие в начале процедуры. Если вы этого не сделаете, вы не сможете загрузить данные из внешнего файла (например, Excel), если в нем есть дубли, или при обмене данными между базами, так как проверка будет блокировать процесс загрузки.
  2. Условие «НЕ Ссылка = &Ссылка»: Это самая частая ошибка. При попытке сохранить уже существующий элемент, если не исключить его самого из поиска, Запрос обязательно найдет его, и программа выдаст ошибку, не давая даже записать изменения в уже существующем элементе.
  3. Использование ОбработкаПроверкиЗаполнения: Использование этого события позволяет платформе корректно обработать отказ. Если мы установим Отказ = Истина, транзакция записи будет прервана, а пользователь получит понятное сообщение об ошибке, привязанное к конкретному полю формы (если указать свойство Сообщение.Поле).

Советы по отладке

Если после внедрения кода проверка не срабатывает, воспользуйтесь отладчиком 1С:

Применяя этот подход, вы обеспечите целостность данных в справочниках и защитите базу от появления дублирующихся артикулов, что значительно упростит работу пользователей и аналитику по товарам в дальнейшем.

← На главную