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

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

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

Почему ваш код не останавливает запись?

Главная проблема заключается в непонимании контекста событий. Переменная Отказ является системным параметром только в определенных методах платформы, которые вызываются в процессе записи объекта (например, ПередЗаписью или ОбработкаПроверкиЗаполнения в модуле объекта).

Когда вы объявляете Отказ = Истина внутри процедуры Расш1_НомерПриИзмененииПосле на клиенте, для платформы это обычная локальная переменная. Она никак не связана с процессом записи документа в базу данных. Событие ПриИзменении предназначено лишь для управления интерфейсом формы, а не для блокировки транзакции записи. Более того, выполнение тяжелых запросов к базе данных в клиентском событии крайне не рекомендуется из-за проблем с производительностью и архитектурных ограничений.

Как реализовать проверку правильно

Для корректной проверки уникальности номера необходимо использовать серверные события модуля объекта. Только там платформа предоставляет механизм полноценной блокировки записи через параметр Отказ.

Шаг 1: Используйте модуль объекта

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

Для поиска дублирующихся номеров лучше всего использовать встроенный метод НайтиПоНомеру. Он оптимизирован платформой и работает гораздо быстрее, чем написание сложных запросов вручную.

Шаг 2: Пример реализации проверки

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


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

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

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

Помните, что использование клиентских событий для таких задач — это «борьба с платформой». Всегда старайтесь переносить логику проверки целостности данных на сервер, ближе к самим данным. Такой подход не только решает проблему с невозможностью отменить запись, но и делает вашу конфигурацию значительно стабильнее и быстрее.

← На главную