Начну с того, что расскажу свою историю, как я открыл для себя XDTO. И зачем оно мне неожиданно пригодилось.
Итак, типичная беда - обмен на КД 2.0. Конфигурации: 1С:ERP. Агропромышленный комплекс и 1C: Itilium. Интересный обмен написал мой коллега, но по каким-то обстоятельствам не смог с ним закончить, и вот оно пришло ко мне. Вся суть: в Itilium есть документы по учету активов и конфигурации (термины из ITIL), и нужно эти документы превращать в документы регламентированной системы, в роли которой выступал 1C: ERP. Вся история в том, что иногда нужно было создавать в ERP несколько документов на основании одного документа источника. И в целях упрощения жизни в обоих конфигурациях создали два идентичных документа (универсальный документ обмена) и заполняли его при проведении ключевых документов.
Всё бы круто: вся основная логика находится в конфигурациях, а не в самих правилах обмена, но есть одно плохое "но". Документы при приходе в конфигурацию-приемник создаются в обработке проведения универсального документа. Ну и, как многие уже подумали, частая беда этого обмена "В данной транзакции уже происходили ошибки".
Для тех, кто не понял, поясню: Проведение документа - это транзакция (ну много чего может записываться во время проведения документа, и соответственно нужно либо чтобы все записалось в БД, либо вернулось к исходному состоянию, если есть ошибки) и т.к. 1С, к сожалению, не придумала вложенные транзакции (тут я уже говорю, как я понял после блуждания по форумам в поисках ответа "почему такая ошибка"), то при ошибке проведения документов, которые проводятся при проведении другого документа, мы получаем "информативную ошибку": "В данной транзакции уже происходили ошибки".
Вот и беда эта была достаточно частой, т.к. обмен был ещё "сыроват". Ну и бессонные ночи были обеспечены. Большая куча времени уходила, чтобы понять, в какой момент и из-за чего именно нельзя было провести тот или иной документ, который создавался на основе универсального документа.
И вот однажды в процессе выполнения других своих задач мой лучший друг по имени "Синтакс-помощник" показал вот такой вот объект: СериализаторXDTO. Стало интересно: а что я могу сериализовать? Оказалось что очень много чего можно сериализовать, а если еще и подготовить данные в нужном виде (привести к определенным типам данных), то вообще без проблем можно сериализовать все, что угодно.
Ну и вот пару часов экспериментов и получилось:
- отладочное расширение, которое содержит функцию для Сериализации переменной типа "ДокументОбъект, СправочникОбъект и т.п." и выдачи их в тексте xml;
- обработка для преобразовании записанного объекта в xml;
- и обработка для просмотра объекта записанного в xml.
Ну и вот такое странное применение всему этому:
- ловим ошибку "в данной транзакции уже происходили ошибки";
- тратим минут 15 на поиск документа который вызывает эту ошибку;
- находим место где вызывается запись этого документа и ставим там точку останова;
- когда точка остановилась вызываем функцию (через Shift+F9) из расширения в которую передаём ДокументОбъект;
- нам возвращается текст xml и мы его копируем;
- вставляем полученный текст в обработку для просмотра объектов из xml (см. п.3 выше);
- и смотрим как заполнился наш документ;
- при необходимости пробуем его провести или записать;
- смотрим на ошибки которые выдаются при записи/проведении;
- что-то осознаем и сравниваем с похожим документом созданным вручную, который мы выгрузим обработкой из п.2 (см. выше) и посмотрим обработкой из п.3 (см. выше).
Самая прелесть этого всего, что здесь, так же как и в коде, не отрабатывают лишние обработчики которые срабатывают при записи из формы (потому что такие обработчики могут дозаполнять объект за вас, а вы об этом и не подозреваете)
А теперь самое интересное. Как это всё работает?
Что делает отладочное расширение:
В отладочном расширении есть один серверный общий модуль с одной экспортной функцией. Функция в итоге возвращает объект, сериализованный в xml.
Содержимое у функции примерно такое:
//Объект передается в эту функцию и превращается в текст XML, который станет понятен для СериализатораXDTO при преобразовании обратно в объект
ЗаписьXML = Новый ЗаписьXML; //здесь создаем объект для записи в XML, ну это и ежу понятно
ЗаписьXML.УстановитьСтроку(); //делаем так чтобы при закрытии записи нам вернулась строка а не файл
СериализаторXDTO.ЗаписатьXML(ЗаписьXML, Объект); //собсна, сериализуем
Возврат ЗаписьXML.Закрыть(); //и возвращаем текст xml
В обработке, которая выгружает в xml уже записанный объект, все то же самое. Принципиальное отличие только в том, что отладочное расширение более нужно для того, чтобы выгрузить то, что не может записаться в базу, а обработка для того, чтобы выгрузить то, что мы создали ручками и смогли записать. И дальше уже сравнивать реквизиты, чтобы понять, что у нас не так.
Ну и как же потом это вот всё преобразовать в объект, спросите вы. А всё очень просто. Код примерно такой вернет вам обратно ДокументОбъект и делайте с ним что хотите:
//XML - это текст XML который мы получили из нашего сериализатора
ЧтениеXML = Новый ЧтениеXML; //создаем объект для чтения XML, ну это и ежу понятно
ЧтениеXML.УстановитьСтроку(XML); //пихаем в Чтение нашу строку
Объект = СериализаторXDTO.ПрочитатьXML(ЧтениеXML); // получаем объект из Чтения
ЧтениеXML.Закрыть(); //как все приличные люди закрываем Чтение
Вот такие небольшие приёмчики с СериализаторомXDTO мне помогли сократить бессонные ночи под отладкой обмена, до нескольких минут локализации ошибки.
Позже напишу, как я разрабатывал интеграцию с внешней системой посредством XML и какие выводы и полезные приемы я для себя вынес.
Всем спасибо за внимание. Свои обработки для отладки я выложу позже отдельной публикацией.