Почему в Конвертации данных 2 создается дубль документа при поиске по номеру?

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

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

Причины сбоя поиска объекта по номеру

Рассмотрим механизм, который использует универсальная обработка обмена КД 2 при сопоставлении объектов. В отличие от типовых методов платформы, стандартный поиск по полям поиска формирует динамический запрос к таблице базы данных вида:


ВЫБРАТЬ
    Ссылка
ИЗ
    Документ.Событие
ГДЕ
    Номер = &Номер

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

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

Способ 1. Добавление даты в поля поиска

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

  1. Откроем правила конвертации объектов (ПКО) для нужного документа.
  2. В табличной части правил конвертации свойств (ПКС) найдем строку со свойством Дата.
  3. Установим флаг Поле поиска для свойства Дата наряду со свойством Номер.

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

Способ 2. Переопределение логики в обработчике «Поля поиска»

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

Разберем, как реализовать гибкий поиск по номеру и границам года через обработчик Поля поиска в ПКО. В этом обработчике нам доступны специальная структура СвойстваПоиска, переменная СсылкаНаНайденныйОбъект и флаг ПрекратитьПоиск.

Посмотрим на пример переопределения поиска с помощью запроса:


Если Не ЗначениеЗаполнено(СсылкаНаНайденныйОбъект) Тогда
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ ПЕРВЫЕ 1
        |   Событие.Ссылка КАК Ссылка
        |ИЗ
        |   Документ.Событие КАК Событие
        |ГДЕ
        |   Событие.Номер = &Номер
        |   И Событие.Дата МЕЖДУ &НачалоГода И &КонецГода";
        
    Запрос.УстановитьПараметр("Номер", СокрЛП(СвойстваПоиска.Номер));
    Запрос.УстановитьПараметр("НачалоГода", НачалоГода(СвойстваПоиска.Дата));
    Запрос.УстановитьПараметр("КонецГода", КонецГода(СвойстваПоиска.Дата));
    
    Выборка = Запрос.Выполнить().Выбрать();
    Если Выборка.Следующий() Тогда
        СсылкаНаНайденныйОбъект = Выборка.Ссылка;
        ПрекратитьПоиск = Истина;
    КонецЕсли;
КонецЕсли;

Обратите внимание: установка флага ПрекратитьПоиск = Истина; сообщает алгоритмам обмена, что объект успешно сопоставлен, и дальнейшие стандартные запросы выполнять не требуется.

Способ 3. Использование метода «НайтиПоНомеру()»

Рассмотрим альтернативный вариант в том же обработчике Поля поиска с вызовом платформенного метода менеджера документов НайтиПоНомеру(). Этот метод платформы 1С автоматически учитывает периодичность нумератора документа:


НомерПоиска = СокрЛП(СвойстваПоиска.Номер);
ДатаПоиска = СвойстваПоиска.Дата;

НайденнаяСсылка = Документы.Событие.НайтиПоНомеру(НомерПоиска, ДатаПоиска);
Если ЗначениеЗаполнено(НайденнаяСсылка) Тогда
    СсылкаНаНайденныйОбъект = НайденнаяСсылка;
    ПрекратитьПоиск = Истина;
КонецЕсли;

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

Рекомендации по синхронизации строковых номеров

Чтобы исключить непредвиденные ошибки сопоставления, выполним следующие профилактические действия:

  1. В обработчике ПКС ПередВыгрузкой или ПриВыгрузке для номера применим очистку пробелов: Значение = СокрЛП(Источник.Номер);.
  2. Убедимся, что длина реквизитов совпадает в обеих конфигурациях, а лидирующие нули не теряются при записи строкового номера в промежуточный реквизит приемника.
  3. Если конфигурации поддерживают хранение соответствий, надежнее передавать исходный УникальныйИдентификатор документа источника в строковый реквизит приемника и выполнять сопоставление по нему через метод менеджера ПолучитьСсылку().
← На главную