Почему задваиваются договора при многократной загрузке в 1С и как это исправить?

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

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

В чем первопричина задвоения объектов при повторной загрузке?

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

Задвоение происходит в тот момент, когда поисковый запрос КД в базу-приемник возвращает пустой результат (объект не найден), хотя визуально этот объект в базе уже существует. Выясним, почему стандартный поиск по текстовому полю (такому как Номер или Код) может не находить существующую запись.

Проанализируем конкретный пример. В правиле конвертации свойств для реквизита Номер написан следующий обработчик «Перед выгрузкой»:


Если Не ЗначениеЗаполнено(Источник.Номер) Тогда
    Значение = "1";
КонецЕсли;

Рассмотрим по шагам, что происходит во время первой и последующих загрузок:

  1. Первая загрузка данных: КД считывает из файла выгрузки значение номера "1". В базе-приемнике выполняется поисковый запрос. Поскольку база чистая, договор с номером "1" не найден. КД создает новый договор, присваивает ему номер "1" и записывает объект.
  2. Модификация номера платформой при записи: При выполнении метода Записать() в базе-приемнике срабатывают механизмы платформы 1С (автонумерация) или подписки на события. Длина реквизита Номер (или Код) в базе-приемнике жестко ограничена (например, 9 символов). Платформа автоматически дополняет переданный номер лидирующими нулями до стандартного формата. В результате в базе сохраняется договор с фактическим номером "000000001".
  3. Повторная загрузка данных: Вы снова загружаете тот же файл. КД опять считывает значение номера "1" и ищет в базе-приемнике договор с точным соответствием строки: Номер = "1". Но в базе теперь записана строка "000000001"! С точки зрения СУБД, строки "1" и "000000001" не равны. Поиск завершается неудачей. КД считает, что договора нет, создает новый (второй) договор с номером "1", который при записи снова превращается в "000000001" (или "000000002" в зависимости от работы автонумерации). Происходит задвоение.

Аналогичная проблема возникает, если в строковых реквизитах поиска присутствуют невидимые пробелы. Например, в источнике номер был записан как " 1 " (с пробелами по краям), а при записи в приемник или в процессе выгрузки пробелы были обрезаны функцией СокрЛП(). Поиск по строке с пробелом никогда не сопоставится со строкой без пробелов.

Как решить проблему сопоставления по номеру в КД?

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

Решение 1. Использование встроенного механизма приведения длины

В настройках ПКС для реквизита, по которому осуществляется поиск (в нашем случае Номер или Код), предусмотрено специальное свойство. Перейдем в настройки правила конвертации свойств и установим флаг «Дополнять строку до длины приемника» (или выберем соответствующую настройку выравнивания и заполнения символами, например, лидирующими нулями). В этом случае КД сама преобразует значение "1" в "000000001" перед отправкой поискового запроса к базе данных, и сопоставление отработает корректно.

Решение 2. Программное форматирование значения перед выгрузкой

Если мы хотим полностью контролировать процесс формирования номера, мы можем дописать программный код в обработчик «Перед выгрузкой» ПКС Номер. Принудительно приведем значение номера к формату базы-приемника, удалив лишние пробелы и добавив нули:


// Очищаем от случайных пробелов
Значение = СокрЛП(Источник.Номер);

Если Не ЗначениеЗаполнено(Значение) Тогда
    Значение = "1";
КонецЕсли;

// Приводим к длине приемника (например, 9 символов)
ДлинаПриемника = 9;
Пока СтрДлина(Значение) < ДлинаПриемника Цикл
    Значение = "0" + Значение;
КонецЦикла;

Такой подход гарантирует, что в XML-файл сразу попадет отформатированное значение "000000001", которое гарантированно будет найдено при повторных поисках.

Решение 3. Изменение стратегии поиска объектов

Зачастую поиск по номеру или наименованию является избыточным и ненадежным. Проанализируем, можем ли мы сопоставлять договора по уникальному идентификатору GUID. Если выгрузка идет из одной и той же информационной базы, установите в ПКО договора флаг «Поиск по уникальному идентификатору». В этом случае КД вообще не будет обращать внимания на текстовые номера при поиске, а свяжет объекты по их внутренним системным ключам. Поиск по номеру в ПКС при этом нужно отключить (снять флаг «Поиск»).

Как отлаживать процесс поиска при загрузке?

Если проблема глубже, и простыми методами ее локализовать не удается, нам потребуется воспользоваться отладчиком 1С. Разберем по шагам, как запустить отладку загрузки данных в контексте «1С:Конвертация данных»:

  1. Откроем обработку «Универсальный обмен данными XML» в базе-приемнике в режиме «1С:Предприятие».
  2. Перейдем на вкладку «Дополнительные настройки» и включим флаг «Режим отладки обработчиков загрузки».
  3. Нажмем кнопку для генерации модуля отладки. Платформа предложит сохранить текстовый файл с кодом обработчиков загрузки.
  4. Откроем этот файл, скопируем его содержимое и вставим во внешнюю обработку (или создадим конфигурационный модуль отладки в конфигураторе базы-приемника согласно инструкции КД).
  5. Запустим конфигуратор базы-приемника и подключимся отладчиком к сеансу предприятия.

Теперь выясним, в каких именно местах кода нам нужно установить точки останова, чтобы понять, почему объект не сопоставляется:

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

← На главную