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