При настройке обмена данными между конфигурациями 1С с помощью «Конвертации данных 2.1» (КД 2.1) разработчики часто сталкиваются с неочевидным поведением системы. Классический пример — ситуация, когда подчиненный документ (например, Счет-фактура выданный) создается или проводится только со второй попытки загрузки одного и того же файла. Для решения подобных проблем необходимо понимать, как именно данные хранятся в оперативной памяти в процессе импорта, как их можно перехватить «на лету» и как управлять очередностью создания объектов.
В этой статье мы подробно разберем внутреннее устройство механизмов загрузки КД 2.1, научимся выполнять полноценную отладку кода обработчиков и рассмотрим три надежных способа устранения проблемы с повторной загрузкой документов.
Для начала проанализируем, как обработка загрузки (обычно это Универсальный обмен данными XML) работает с памятью. Система осуществляет потоковое чтение XML-файла. Это означает, что весь файл не загружается в оперативную память целиком в виде огромной таблицы. Вместо этого чтение происходит последовательно: узел за узлом, объект за объектом. По мере разбора очередного XML-узла данные десериализуются во временные структуры данных 1С.
Тем не менее в обработчиках событий КД 2.1 разработчику доступен целый набор предопределенных переменных, через которые можно анализировать и изменять загружаемые данные:
Объект — это ключевая переменная. Она содержит непосредственно создаваемый или найденный в информационной базе-приемнике объект (например, ДокументОбъект.ОтчетКомиссионераОПродажах). Переменная доступна в большинстве обработчиков загрузки («После загрузки», «Перед записью», «При записи», «После записи»). Через нее мы можем напрямую обращаться к реквизитам и табличным частям, например: Объект.Товары или Объект.Контрагент.Свойства — это структура (или соответствие), содержащая считанные из XML-файла значения реквизитов до того, как они будут окончательно перенесены в сам Объект. Это позволяет анализировать входящие данные еще до модификации объекта в базе.ПараметрыОбъекта — соответствие типа «ключ-значение». В нем содержатся дополнительные параметры, которые были переданы вместе с конкретным объектом при выгрузке. Это крайне удобный инструмент для передачи нетиповой или служебной информации, которой нет в реквизитах самого загружаемого документа.Параметры — глобальная структура, существующая на протяжении всего сеанса обмена. Записав туда данные при загрузке одного объекта, мы можем прочитать их при обработке другого.Поскольку обработчики событий КД 2.1 компилируются динамически с помощью оператора Выполнить(), мы не можем просто так поставить точку останова в конфигураторе на коде правил обмена. Чтобы обойти это ограничение и увидеть значения переменных во время загрузки, выполним настройку полноценной отладки.
Рассмотрим пошагово алгоритм генерации и подключения модуля отладки:
Шаг 1. Подготовка модуля отладки в КД 2.1
Откроем конфигурацию «Конвертация данных 2.1» и перейдем в форму настройки наших правил обмена. Перейдем на вкладку «Настройка правил обмена», выберем пункт «Отладка обработчиков» и нажмем кнопку «Сформировать модуль обработчиков загрузки». Система сгенерирует программный код, содержащий все наши обработчики событий. Скопируем этот текст в буфер обмена.
Шаг 2. Создание внешней обработки отладки
В конфигураторе базы-приемника создадим новую внешнюю обработку. Назовем ее, например, ОтладкаЗагрузки. Откроем модуль этой обработки и вставим туда скопированный ранее текст. Сохраним обработку в локальный каталог на жестком диске.
Шаг 3. Включение отладки на сервере 1С
Если обмен выполняется в клиент-серверном варианте работы, убедимся, что на сервере включена отладка (сервер запущен с ключом -debug). В конфигураторе базы-приемника в меню «Отладка» -> «Подключение» настроим автоматическое подключение к фоновым заданиям.
Шаг 4. Настройка обработки «Универсальный обмен данными XML»
Запустим базу-приемник в режиме «1С:Предприятие». Откроем обработку загрузки V8Exchan83.epf и перейдем на вкладку «Загрузка данных». В нижней части формы найдем параметры отладки, установим флаг «Режим отладки обработчиков загрузки», выберем вариант подключения внешней обработки с диска и укажем путь к файлу ОтладкаЗагрузки.epf. При необходимости можно воспользоваться доработанной обработкой универсального обмена с поддержкой режима отладки.
Шаг 5. Пошаговый анализ
Теперь мы можем открыть код созданной обработки в конфигураторе, найти нужное событие (например, «После загрузки» для Отчета комиссионера) и поставить стандартную точку останова (клавиша F9). Запустим процесс загрузки в режиме предприятия. Система остановит выполнение кода на нашей точке останова, и мы сможем детально изучить содержимое переменных Объект, ПараметрыОбъекта и Свойства в табло отладчика.
Если у нас нет возможности запустить отладчик (например, на закрытом рабочем сервере клиента), мы можем применить программное логирование. Для этого запишем интересующие нас параметры в Журнал регистрации или во внешний текстовый файл.
Проанализируем пример кода, который можно поместить в обработчик «После загрузки» нужного документа для фиксации данных:
// Запись ключевых данных загружаемого документа в Журнал регистрации
ТекстЛога = "Загружен объект: " + Строка(Объект.Ссылка) +
" | Дата: " + Строка(Объект.Дата) +
" | Сумма: " + Строка(Объект.СуммаДокумента);
ЗаписьЖурналаРегистрации(
"ОтладкаОбменаДанными",
УровеньЖурналаРегистрации.Информация,,,
ТекстЛога
);
Выясним причину классической проблемы, когда Счет-фактура выданный загружается и проводится только со второго раза. Данное поведение связано с **очередностью создания объектов** в XML-файле и механизмом работы **неразрешенных (битых) ссылок**.
Счет-фактура жестко подчинен своему документу-основанию (в нашем случае — Отчету комиссионера о продажах). Если в XML-файле узел Счета-фактуры расположен физически выше, чем узел Отчета комиссионера, происходит следующее:
Рассмотрим три способа решения этой проблемы непосредственно в правилах КД 2.1.
Самое простое и логичное решение — изменить очередность выгрузки объектов. В конфигурации «Конвертация данных 2.1» откроем дерево правил. Нам нужно гарантировать, что ПКО для Отчета комиссионера расположено **выше**, чем ПКО для Счета-фактуры. При выгрузке данных КД 2.1 ориентируется на порядок ПКО в списке: сначала будут выгружены (и, соответственно, первыми загружены) родительские документы, а затем уже подчиненные им Счета-фактуры. Для быстрой организации структуры правил можно использовать инструмент автоматической сортировки ПКО и ПКС.
Чтобы полностью исключить рассинхронизацию, мы можем вообще отказаться от переноса Счетов-фактур как самостоятельных объектов через XML. Вместо этого мы будем создавать их автоматически программным кодом при загрузке Отчета комиссионера.
Для этого в ПКО Отчета комиссионера в обработчике «После загрузки» (или «После записи») пропишем следующий алгоритм проверки и создания подчиненного документа:
// Проверяем, проведен ли загруженный отчет комиссионера
Если Объект.Проведен Тогда
// Выполним запрос для проверки существования Счета-фактуры по данному основанию
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Ссылка ИЗ Документ.СчетФактураВыданный
|ГДЕ
| ДокументОснование = &Основание";
Запрос.УстановитьПараметр("Основание", Объект.Ссылка);
РезультатЗапроса = Запрос.Выполнить();
Если РезультатЗапроса.Пустой() Тогда
// Счета-фактуры еще нет, создаем его программно
НовыйСФ = Документы.СчетФактураВыданный.СоздатьДокумент();
НовыйСФ.Дата = Объект.Дата;
НовыйСФ.ДокументОснование = Объект.Ссылка;
// Переносим ключевые реквизиты из родительского документа
ЗаполнитьЗначенияСвойств(НовыйСФ, Объект, "Организация, Контрагент, ДоговорКонтрагента");
Попытка
НовыйСФ.Записать(РежимЗаписиДокумента.Проведение);
Исключение
ЗаписьЖурналаРегистрации(
"ОшибкаСозданияСФ",
УровеньЖурналаРегистрации.Предупреждение,,,
"Не удалось провести СФ для документа: " + Строка(Объект.Ссылка) + ". Ошибка: " + ОписаниеОшибки()
);
КонецПопытки;
КонецЕсли;
КонецЕсли;
Если нам критически важно переносить Счета-фактуры именно как отдельные объекты обмена (например, на них завязаны сложные правила конвертации свойств), мы можем использовать стратегию отложенного проведения.
Разберем этот подход:
Применяя данные методики анализа переменных и управления очередностью загрузки, мы сможем сделать наши интеграционные процессы стабильными, прозрачными и устойчивыми к любым ошибкам коллизии ссылок.