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

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

В процессе разработки, интеграции или переноса данных в системе «1С:Предприятие» программисты нередко сталкиваются с ситуацией, когда необходимо обойти стандартные жесткие ограничения платформы. Одним из таких ограничений является контроль уникальности кодов справочников. Когда в свойствах объекта конфигурации включены свойства «Автонумерация» и «Контроль уникальности», стандартная интерактивная или программная запись элемента с уже существующим в базе кодом вызовет ошибку СУБД, и транзакция будет отменена.

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

Решение проблемы: Свойство ОбменДанными.Загрузка

Для того чтобы заставить платформу «закрыть глаза» на контроль уникальности кодов (а также номеров документов), необходимо использовать специальное свойство объекта — ОбменДанными.Загрузка. Установив его значение в Истина непосредственно перед вызовом метода Записать(), мы отключаем стандартные проверки.

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


// Создаем новый элемент справочника Номенклатура
НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();

// Заполняем обязательные реквизиты
НовыйЭлемент.Наименование = "Дубликат товара";

// Явно указываем код, который уже существует в системе
НовыйЭлемент.Код = "000000001";

// Включаем режим загрузки данных для обхода проверок
НовыйЭлемент.ОбменДанными.Загрузка = Истина;

// Записываем элемент без стандартных проверок платформы
Попытка
    НовыйЭлемент.Записать();
    Сообщить("Элемент успешно записан с дублирующимся кодом!");
Исключение
    Сообщить("Не удалось записать элемент: " + ОписаниеОшибки());
КонецПопытки;

Давайте разберем по шагам, что происходит в системе при выполнении этого кода и почему данный способ срабатывает.

Что именно отключает платформа при ОбменДанными.Загрузка = Истина?

Когда мы присваиваем свойству ОбменДанными.Загрузка значение Истина, платформа переходит в специальный режим записи «как есть». Этот режим изначально проектировался для механизмов синхронизации (например, при обмене данными через XML или планы обмена), чтобы принимающая база могла беспрепятственно записать любые данные, пришедшие из источника.

В этом режиме происходят следующие важные изменения в поведении платформы:

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

Важный нюанс: Поведение обработчиков событий и бизнес-логики

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

Предотвращение проверок кастомной бизнес-логики происходит исключительно благодаря соблюдению стандартов разработки фирмы «1С» (в частности, стандартов Библиотеки Стандартных Подсистем — БСП). Согласно этим стандартам, любой обработчик событий в модуле объекта или подписке должен начинаться со следующей конструкции:


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

Если разработчик конфигурации (или автор некачественной доработки) забыл написать эту проверку в начале процедуры модуля конкретного справочника, то даже при установленном флаге Загрузка = Истина весь кастомный код проверки выполнится. В этом случае транзакция записи может быть заблокирована, если внутри обработчика прописаны собственные жесткие алгоритмы контроля.

Какими еще путями в базе могут появиться дубли кодов?

Помимо прямого использования свойства ОбменДанными.Загрузка = Истина в обработках, дублирующиеся коды могут появиться в системе следующими путями:

Последствия создания элементов с одинаковыми кодами

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

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

← На главную