Как вести историю регистрации изменений для обмена данными в 1С и найти причину «пропажи» документов?

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

В процессе поддержки интеграций между базами 1С программисты часто сталкиваются с загадочным поведением планов обмена: некоторые документы упорно не переносятся в базу-приемник. При этом ручная регистрация объекта через стандартные обработки решает проблему — документ перегружается без нареканий. Но при штатном автоматическом обмене объект просто «исчезает» из регистрации в источнике, так и не появившись в приемнике.

В этой статье мы подробно разберем физику этого процесса, выясним, почему документы «выпадают» из обмена, и реализуем надежную систему логирования и трассировки изменений, которая поможет раз и навсегда определить виновную сторону без изнурительной отладки «в лоб» на «живой» базе.

Физика процесса: почему объекты «исчезают» из регистрации?

Для начала давайте разберем, как платформа 1С работает с таблицами регистрации изменений на уровне СУБД. Это критически важно для понимания сути проблемы.

  1. Регистрация изменений: При изменении объекта (например, проведении документа) в физической таблице изменений (например, Документ.РеализацияТоваровУслуг.Изменения) создается запись. В этой записи поле НомерСообщения по умолчанию имеет значение NULL.
  2. Выгрузка данных: При запуске сеанса обмена вызывается метод ВыбратьИзменения(). Платформа временно присваивает всем выбранным записям номер отправляемого сообщения (например, 45).
  3. Квитирование (подтверждение приема): База-приемник успешно принимает файл обмена и в ответном сообщении присылает подтверждение: «Пакет № 45 успешно обработан». Получив это подтверждение, база-источник вызывает метод УдалитьРегистрациюИзменений(), который физически удаляет из таблицы изменений все записи, у которых НомерСообщения меньше или равен 45.

Где же кроется баг?

Проблема возникает в момент формирования файла выгрузки. Сценарий выглядит следующим образом:

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

В результате:

В итоге регистрация стерта, документ не перенесен, а вы пребываете в недоумении. Именно поэтому повторное перепроведение документа (когда номер сообщения снова сбрасывается в NULL) временно решает проблему.

---

Способ 1. Оперативный анализ через прямые запросы к таблицам изменений

Чтобы быстро поймать документ «за руку» прямо во время обмена, мы можем использовать прямые запросы к таблицам регистрации изменений. По умолчанию конструктор запросов не показывает эти таблицы, но к ним можно обратиться программно.

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


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

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

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

Если перед запуском обмена вы видите, что у документа заполнен НомерСообщения, а после завершения обмена запись исчезает, но документ так и не появился в приемнике — значит, проблема на стороне источника (документ отсекается правилами выгрузки).

---

Способ 2. Логирование процесса через Журнал регистрации и Расширения

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

Нам понадобятся точки перехвата в двух базах.

Шаг А. Логирование на стороне источника (при отправке)

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

Создадим расширение и перехватим процедуру выгрузки объектов методом &После или &Перед:


&После("ВыгрузитьОбъектДанных")
Процедура Лог_ВыгрузитьОбъектДанных(ДанныеПриемника, ДанныеИсточника, СопутствующиеДанные, КомпонентОбмена)
    
    СсылкаНаОбъект = ДанныеИсточника.Ссылка;
    ТипОбъекта = СсылкаНаОбъект.Метаданные().Имя;
    
    // Фильтруем только интересующие нас типы документов для экономии места в журнале
    Если ТипОбъекта = "РеализацияТоваровУслуг" Тогда
        
        ИмяСобытияЛога = "ОбменДанными.ВыгрузкаОбъекта";
        ТекстКомментария = СтрШаблон(
            "Объект успешно записан в файл обмена. Узел: %1. Ссылка: %2, Номер: %3",
            Строка(КомпонентОбмена.УзелОбмена),
            Строка(СсылкаНаОбъект),
            СсылкаНаОбъект.Номер
        );
        
        ЗаписьЖурналаРегистрации(
            ИмяСобытияЛога,
            УровеньЖурналаРегистрации.Информация,
            СсылкаНаОбъект.Метаданные(),
            СсылкаНаОбъект,
            ТекстКомментария
        );
        
    КонецЕсли;
    
КонецПроцедуры

Шаг Б. Логирование на стороне приемника (при приеме)

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


&После("ЗаписатьПолученныеДанные")
Процедура Лог_ЗаписатьПолученныеДанные(ПолученныеДанные, КомпонентОбмена)
    
    СсылкаНаОбъект = ПолученныеДанные.Ссылка;
    ТипОбъекта = СсылкаНаОбъект.Метаданные().Имя;
    
    Если ТипОбъекта = "РеализацияТоваровУслуг" Тогда
        
        ИмяСобытияЛога = "ОбменДанными.ЗагрузкаОбъекта";
        ТекстКомментария = СтрШаблон(
            "Объект успешно получен и записан в базу-приемник. Узел: %1. Ссылка: %2, Номер: %3",
            Строка(КомпонентОбмена.УзелОбмена),
            Строка(СсылкаНаОбъект),
            СсылкаНаОбъект.Номер
        );
        
        ЗаписьЖурналаРегистрации(
            ИмяСобытияЛога,
            УровеньЖурналаРегистрации.Информация,
            СсылкаНаОбъект.Метаданные(),
            СсылкаНаОбъект,
            ТекстКомментария
        );
        
    КонецЕсли;
    
КонецПроцедуры

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

---

Способ 3. Использование встроенной диагностики БСП

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

Выполним следующие шаги для включения диагностики:

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

Используя предложенные методы контроля таблиц изменений и логирования событий обмена, мы переводим процесс поиска ошибок из плоскости «угадывания» в плоскость точного инженерного анализа.

← На главную