Как избежать дублирования документов при групповой загрузке XML в 1С:Управление торговлей 10.3?

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

При разработке обработок загрузки данных из внешних XML-файлов часто возникает ситуация, когда при повторном запуске процедуры один и тот же файл считывается заново, создавая дублирующие документы ПоступлениеТоваровУслуг и подчиненные счета-фактуры. Разберем, как правильно реализовать проверку наличия ранее созданных документов в базе данных 1С и исключить их дублирование.

Вариант 1. Быстрая проверка с помощью метода НайтиПоРеквизиту

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

Посмотрим на пример встраивания проверки в цикл обработки после чтения XML:


// После прочтения переменных из XML (аа - номер входящего документа)
НайденныйДок = Документы.ПоступлениеТоваровУслуг.НайтиПоРеквизиту("НомерВходящегоДокумента", аа);

Если Не НайденныйДок.Пустая() Тогда
    Сообщить("Документ с входящим номером " + аа + " уже существует в базе! Пропускаем.");
    Продолжить;
КонецЕсли;

// Далее следует стандартный код создания и проведения документа
ДокОбъект = Документы.ПоступлениеТоваровУслуг.СоздатьДокумент();
// ...

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

Вариант 2. Надежная проверка по составному ключу через запрос

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

  1. Организация (наша организация, принимающая товары);
  2. Контрагент (поставщик, выставивший документ);
  3. НомерВходящегоДокумента (номер счета-фактуры или накладной поставщика);
  4. ДатаВходящегоДокумента (дата документа поставщика).

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


КонтрагентПоступления = Справочники.Контрагенты.НайтиПоКоду("УT0000063");
ОрганизацияПоступления = Справочники.Организации.НайтиПоКоду("000000001");
ДатаВх = Дата(вв);

Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ ПЕРВЫЕ 1
    |   Поступление.Ссылка КАК Ссылка
    |ИЗ
    |   Документ.ПоступлениеТоваровУслуг КАК Поступление
    |ГДЕ
    |   Поступление.Проведен = ИСТИНА
    |   И Поступление.Организация = &Организация
    |   И Поступление.Контрагент = &Контрагент
    |   И Поступление.НомерВходящегоДокумента = &НомерВходящегоДокумента
    |   И Поступление.ДатаВходящегоДокумента = &ДатаВходящегоДокумента";

Запрос.УстановитьПараметр("Организация", ОрганизацияПоступления);
Запрос.УстановитьПараметр("Контрагент", КонтрагентПоступления);
Запрос.УстановитьПараметр("НомерВходящегоДокумента", СокрЛП(аа));
Запрос.УстановитьПараметр("ДатаВходящегоДокумента", НачалоДня(ДатаВх));

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

Если Не РезультатЗапроса.Пустой() Тогда
    Выборка = РезультатЗапроса.Выбрать();
    Выборка.Следующий();
    Сообщить("Документ по накладной № " + аа + " от " + Формат(ДатаВх, "ДФ=dd.MM.yyyy") + " уже загружен: " + Строка(Выборка.Ссылка));
    Продолжить;
КонецЕсли;

Вариант 3. Оптимизация пакетной загрузки через единый запрос

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

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

Рекомендации по повышению надежности загрузки

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

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