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