Планы обмена в 1С: где задается выборка данных и почему регистрируются не те объекты?

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

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

Как работает выборка изменений на уровне платформы

Для начала проанализируем базовый платформенный механизм. Когда мы вызываем метод ПланыОбмена.ВыбратьИзменения(Узел, НомерСообщения), платформа 1С не запускает какой-то конкретный, написанный программистом запрос в конфигурации. Этот процесс автоматизирован:

Таким образом, «состав» выборки жестко ограничен списком объектов, указанных на вкладке «Состав» конкретного плана обмена в Конфигураторе. Если объект не включен в состав плана обмена, его изменения физически не могут быть зарегистрированы для этого узла.

Где задается выборка в Конвертации данных (КД 2.1)

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

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


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

Запрос.УстановитьПараметр("Узел", УзелОбмена);
ВыборкаДанных = Запрос.Выполнить().Выгрузить();

Если в вашей системе используется именно такой механизм, то искать код «запроса» нужно не в конфигурации 1С, а в самом XML-файле правил обмена, открыв его через специализированную конфигурацию «Конвертация данных».

Почему при перепроведении документа регистрируется справочник, а не документ?

Рассмотрим частую проблему: при создании нового документа обмен проходит успешно (регистрируется сам документ), а при его перепроведении в плане обмена регистрируется только связанный справочник (например, контрагент или договор), а сам документ в выборку не попадает. Выясним основные причины такого поведения.

1. Авторегистрация в составе плана обмена

В Конфигураторе для каждого объекта в составе плана обмена можно задать свойство «Авторегистрация»:

Если для документа авторегистрация установлена в «Запретить», а для связанного справочника — в «Разрешить», то при проведении документа справочник зарегистрируется автоматически (так как у него изменились связи или свойства), а сам документ — нет.

2. Программная регистрация в подписках на события

В типовых конфигурациях (особенно на БСП) регистрацией часто управляет программный код. Существуют подписки на события (например, ПередЗаписьюДокумента, ПриЗаписиДокумента), внутри которых разработчики прописывают вызовы процедур регистрации. При перепроведении документа может срабатывать условие (отбор), которое решает, что сам документ выгружать не нужно, но нужно обновить связанный справочник. В итоге в очередь регистрируется только ссылка на справочник.

3. Правила регистрации объектов (ПРО) в БСП

Если обмен работает через Библиотеку стандартных подсистем (БСП), то логика регистрации описывается в специальных правилах регистрации (разрабатываемых в КД 2.1 или КД 3.0). В этих правилах настраиваются отборы. Например, документ должен регистрироваться только в том случае, если он проведен и дата входит в определенный период. Если при перепроведении документа какое-то условие не выполняется, БСП автоматически удаляет его регистрацию из плана обмена, оставляя только сопутствующие справочники.

Как найти и исправить проблему: пошаговое руководство

Проанализируем ситуацию на практике и разберем последовательность действий для локализации и устранения этой ошибки.

Шаг 1. Анализ зарегистрированных изменений в пользовательском режиме

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

  1. Откроем обработку и выберем интересующий нас узел плана обмена.
  2. Найдем в дереве объектов наш документ и связанный справочник.
  3. Проведем документ и посмотрим, какие именно объекты зарегистрировались в дереве. Если документ там не появился, а появился только справочник — проблема гарантированно кроется в правилах или коде регистрации.

Шаг 2. Запрос к таблицам изменений (для отладки)

Мы можем программно проверить, зарегистрирован ли документ для конкретного узла, выполнив прямой запрос к таблице изменений. Для этого воспользуемся консолью запросов (в конструкторе запросов нужно включить отображение таблиц изменений):


ВЫБРАТЬ
    РеализацияИзменения.Ссылка КАК ДокументСсылка,
    РеализацияИзменения.Узел КАК Узел
ИЗ
    Документ.РеализацияТоваровУслуг.Изменения КАК РеализацияИзменения
ГДЕ
    РеализацияИзменения.Узел = &УзелОбмена

Если этот запрос возвращает пустой результат после перепроведения, значит, платформа или логика БСП целенаправленно не регистрирует документ.

Шаг 3. Поиск программного кода регистрации

Если авторегистрация для документа в плане обмена выключена (стоит «Запретить»), выполним глобальный поиск (клавиши Ctrl + Shift + F) по конфигурации:

Шаг 4. Обработка типов в цикле выборки

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


ВыборкаИзменений = ПланыОбмена.ВыбратьИзменения(УзелОбмена, НомерСообщения);

Пока ВыборкаИзменений.Следующий() Цикл
    Данные = ВыборкаИзменений.Получить();
    
    // Проверяем тип полученных данных
    Если ТипЗнч(Данные) = Тип("ДокументСсылка.РеализацияТоваровУслуг") Тогда
        // Обрабатываем документ
        ПроцессингДокумента(Данные);
        
    ИначеЕсли ТипЗнч(Данные) = Тип("СправочникСсылка.Контрагенты") Тогда
        // Обрабатываем справочник отдельно или игнорируем
        ПроцессингСправочника(Данные);
        
    КонецЕсли;
КонецЦикла;

Такой подход защитит ваш алгоритм обмена от падения с ошибкой, если в выборку неожиданно попадет объект другого типа, и позволит гибко обрабатывать каждый тип данных по своим правилам.

← На главную