При разработке двустороннего обмена данными между информационными базами разработчики нередко сталкиваются с ситуацией: при выгрузке из базы-источника в базу-приемник документ корректно идентифицируется и обновляется, но при обратном обмене типовой алгоритм загрузки не находит существующий документ и создает дубль, несмотря на точные совпадения номера и отключенный поиск по уникальному идентификатору (УИД).
Разберем по шагам, почему возникает такое поведение, как устроена внутренняя механика платформы «1С:Предприятие» при поиске документов и какие существуют проверенные способы решения этой проблемы.
Проанализируем механику работы платформы при сопоставлении объектов. В конфигурации у большинства документов нумерация настроена как периодическая (например, в пределах года, месяца или дня). Для таких объектов поиск по номеру не может выполняться абстрактно — платформе всегда требуется контекст периода.
При стандартной загрузке по полям поиска для документов платформа использует встроенный метод менеджера документа НайтиПоНомеру. Рассмотрим особенности его сигнатуры:
Метод Документы[ИмяДокумента].НайтиПоНомеру(Номер, ДатаИнтервала) при периодической нумерации требует обязательного указания даты интервала. Если при настройке правил конвертации свойств (ПКС) флаг «Поиск объекта при загрузке по данному свойству» установлен только у реквизита Номер, а реквизит Дата в поиске не участвует, второй параметр в метод НайтиПоНомеру не передается.
В этом случае платформа пытается найти документ в пустом интервале дат по умолчанию (начало интервала — 0001-01-01). Естественно, документ текущего года с таким номером в пустом периоде отсутствует. Алгоритм «Конвертации данных» считает, что объект в базе-приемнике не существует, и создает новый документ с тем же номером, приводя к появлению дублей.
Рассмотрим самый простой и типовой вариант исправления ситуации. Для корректной работы штатного механизма необходимо передать интервал периодичности в процедуру поиска.
Дата.Важно понимать, что в типовых алгоритмах «Конвертации данных» реквизит Дата в полях поиска документов обрабатывается особым образом: алгоритм не ищет точное совпадение секунда-в-секунду, а использует переданную дату именно для определения границ периода нумерации (например, нужного года). В результате метод НайтиПоНомеру получает требуемый контекст и успешно сопоставляет документ.
Бывают ситуации, когда дату нельзя использовать в качестве стандартного поля поиска — например, если даты документов в двух базах могут различаться, относиться к разным отчетным периодам или дата документа в базе-приемнике заранее неизвестна. В этом случае настроим собственный алгоритм поиска с помощью запроса.
Разберем реализацию в правиле конвертации объекта (ПКО):
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| Событие.Ссылка КАК Ссылка
|ИЗ
| Документ.Событие КАК Событие
|ГДЕ
| Событие.Номер = &Номер
|УПОРЯДОЧИТЬ ПО
| Событие.Дата УБЫВ";
Запрос.УстановитьПараметр("Номер", СвойстваПоиска["Номер"]);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
СсылкаНаОбъект = Выборка.Ссылка;
КонецЕсли;
Обратим внимание на предопределенный параметр СсылкаНаОбъект. Если в данном обработчике переменной присвоено значение существующей ссылки, штатный поиск по полям поиска прерывается, и система сопоставляет загружаемые данные с найденным документом.
Если требуется гибко переключать состав полей в зависимости от переданных данных, используем предопределенную переменную СтрокаИменСвойствПоиска в обработчике «Поля поиска».
Посмотрим на пример управления составом полей:
СтрокаИменСвойствПоиска = "Номер, Дата";
Этот подход позволяет программно формировать список реквизитов, по которым платформа должна произвести стандартную попытку сопоставления.
Если поиск настроен с учетом даты, но объект все равно не находится, проверим технические параметры номера:
000000123, а в другой записан как 123, штатный поиск завершится неудачей. В ПКС для реквизита номера убедимся, что включен флаг «Автоматически приводить значение к длине приемника», либо настроим форматирование в обработчике «Перед выгрузкой» / «Перед загрузкой».Таким образом, для документов с периодической нумерацией всегда необходимо передавать интервал даты или реализовывать прямой поиск через запрос в обработчике «Поля поиска».