Почему при массовом обмене данными в документах не заполняются контрагенты и номенклатура

Программист 1С v8.3 (Обычные формы) Бухгалтерский учет IT и автоматизация бизнеса
← На главную

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

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

Внутренние механизмы поиска и сопоставления в КД 2.x

Для понимания природы плавающей ошибки разберем, как именно платформа и обработка загрузки ищут и идентифицируют ссылочные типы данных (справочники Контрагенты, Номенклатура и др.) при чтении XML-файла:

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

Анализ кода правил: поиск и подготовка данных

Рассмотрим пример сложной логики сопоставления из правил конвертации данных, где используется многовариантный поиск. В обработчике ПоляПоиска для справочника Контрагенты часто создаются ветки подбора по коду ЕДРПОУ (ИНН), наименованию и кодам:


Если СвойстваПоиска["ЭтоГруппа"] = Истина Тогда
    СтрокаИменСвойствПоиска = "Код, Наименование, Родитель, ЭтоГруппа, ПометкаУдаления";
Иначе
    Если ЗначениеЗаполнено(СвойстваПоиска["КодПоЕДРПОУ"]) Тогда
        Если НомерВариантаПоиска = 1 Тогда
            СтрокаИменСвойствПоиска = "Код, КодПоЕДРПОУ, Наименование, Родитель, ЭтоГруппа";
        ИначеЕсли НомерВариантаПоиска = 2 Тогда
            СтрокаИменСвойствПоиска = "Код, КодПоЕДРПОУ, Родитель, ЭтоГруппа";
        ИначеЕсли НомерВариантаПоиска = 3 Тогда
            СтрокаИменСвойствПоиска = "КодПоЕДРПОУ, Наименование, Родитель, ЭтоГруппа";
        Иначе
            СтрокаИменСвойствПоиска = "Наименование, Родитель, ЭтоГруппа";
        КонецЕсли;
    Иначе
        СтрокаИменСвойствПоиска = "Наименование, Родитель, ЭтоГруппа";
    КонецЕсли;
КонецЕсли;

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


КоллекцияОбъектов = Новый ТаблицаЗначений;
КоллекцияОбъектов.Колонки.Добавить("ЕдиницаИзмерения");
КоллекцияОбъектов.Колонки.Добавить("Коэффициент");

Если НЕ Источник.ЭтоГруппа Тогда
    Запросы.ПолучитьЕдиницыИзмеренияДляНоменклатуры.УстановитьПараметр("Владелец", Источник.Ссылка);
    Выборка = Запросы.ПолучитьЕдиницыИзмеренияДляНоменклатуры.Выполнить().Выбрать();
    Пока Выборка.Следующий() Цикл
        Строка = КоллекцияОбъектов.Добавить();
        ЗаполнитьЗначенияСвойств(Строка, Выборка);
    КонецЦикла;
    КоллекцияОбъектов.Свернуть("ЕдиницаИзмерения, Коэффициент");
КонецЕсли;

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

Главная причина сбоя: «битые» сопоставления в регистре

Ключевая проблема заключается в поведении типового регистра сведений СоответствиеОбъектовДляОбмена. Механизм дает сбой в следующих ситуациях:

  1. Наличие пустых ссылок или записей вида <Объект не найден>. Если в базе-приемнике объект когда-то был физически удален, помечен на удаление или загрузка завершилась сбоем посередине транзакции, в регистре остается привязка идентификатора источника к несуществующей ссылке. При обработке входящего документа алгоритм находит запись в регистре, считает объект уже идентифицированным и вставляет в реквизит битую ссылку (которая на форме отображается пустым полем), вообще минуя код из обработчика ПоляПоиска.
  2. Эффект малых выборок. При выгрузке 5–10 документов вероятность наткнуться на конкретного проблемного контрагента минимальна. Но при выгрузке 1000 документов поврежденные сопоставления неизбежно всплывают, создавая впечатление случайности ошибок.
  3. Дублирование сопоставлений по идентификаторам. Если при предыдущих попытках обмена записи задвоились, платформа может непредсказуемо выбирать строку, содержащую пустое значение ссылки.

Дополнительные факторы: отложенные ссылки и транзакции

Помимо регистра сведений, на потерю данных при массовой загрузке влияют архитектурные ограничения платформы 1С:

  1. Размер транзакции при загрузке. В настройках обмена стандартно задано свойство Количество объектов в транзакции (например, 100). Если внутри этой порции возникает некритичная блокировка СУБД или ошибка записи дополнительного регистра (например, сведений по счетам учета номенклатуры), ссылка на номенклатуру может не успеть зафиксироваться в базе до того, как документ уже записан.
  2. Перенос логики из ПВД в ПКО. Попытки создавать сопутствующие записи независимых регистров (например, СчетаУчетаНоменклатуры) внутри правил выгрузки данных (ПВД) через процедуру ВыгрузитьПоПравилу на больших объемах приводят к рассинхронизации потоков. Создание таких записей надежнее выполнять непосредственно в обработчиках ПКО (например, в ПослеЗагрузки).
  3. Лимиты адресного пространства 32-разрядных процессов. Если загрузка выполняется на 32-битном сервере или клиенте, кэш объектов КД 2.1 переполняется при обработке десятков тысяч строковых соответствий, приводя к сбоям вычисления хэш-таблиц отложенных ссылок.

Пошаговое решение проблемы

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

  1. Ревизия и очистка регистра сведений:

    В базе-приемнике проанализируем записи регистра СоответствиеОбъектовДляОбмена. Выполним запрос на поиск записей, где собственная ссылка указывает в пустоту или на несуществующий объект:

    
    ВЫБРАТЬ
        Рег.УзелОбмена,
        Рег.СобственнаяСсылка,
        Рег.Идентификатор
    ИЗ
        РегистрСведений.СоответствиеОбъектовДляОбмена КАК Рег
    ГДЕ
        Рег.СобственнаяСсылка ССЫЛКА Справочник.Контрагенты
        И Рег.СобственнаяСсылка.Ссылка ЕСТЬ NULL
    

    Все записи с «битыми» ссылками и ссылками на удаленные элементы необходимо удалить из регистра для целевого узла плана обмена.

  2. Оптимизация правил конвертации:

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

  3. Корректировка параметров транзакций:

    Если в процессе обмена в рабочей базе активно работают пользователи, временно уменьшим параметр загрузки Количество объектов в транзакции до 1–10. Это предотвратит потерю ссылок при блокировках параллельными сеансами.

  4. Разделение процессов загрузки и проведения:

    При массовых выгрузках не следует выполнять автоматическое проведение документов «на лету». Оптимально загружать документы только с признаком записи (РежимЗаписи = РежимЗаписиДокумента.Запись), а массовое проведение запускать отдельной процедурой или регламентным заданием в монопольном режиме после завершения сопоставления всех справочников.

← На главную