Материал подготовлен совместно с Петром Федотовым
Попробуем разобраться, как работает коннектор 1С. Рассмотрим вариант, когда данные из DIRECTUM выгружаются в интегрированную систему. Упрощенно последовательность действий будет выглядеть так:
После того, как мы произвели настройку интеграции какого-нибудь справочника, в карточке «Настройки обмена данными с интегрированными системами» настроенного справочника необходимо нажать кнопку «Создать XSL». При нажатии на данную кнопку генерируется текст XSL-преобразования данных из формата одной интегрированной системы в другую (в нашем примере из формата DIRECTUM в формат 1С). При нажатии на кнопку «Редакт. XSL», можно посмотреть и отредактировать текст XSL-преобразования для настроенного справочника.

Для начала нам понадобиться исходный XML-файл в формате DIRECTUM, который затем с помощью XSL-преобразования трансформируется в формат 1С. Для этого откроем функцию Connector1C81ImportDataToIntegratedSystem, и добавим в неё сохранение исходной XML во временную папку отладки:
  /***********************************************************************/   
  // Получить и сохранить новый номер сообщения и номер последнего принятого    //
  // сообщения                                                                  //
  /******************************************************************************/   
  NewMessageNo = GetIntegratedSystemParam(IntegratedSystemCode; "MessageNo") + 1 
  SetIntegratedSystemParam(IntegratedSystemCode; "MessageNo"; NewMessageNo)
  ReceivedMessageNo = GetIntegratedSystemParam(IntegratedSystemCode; "ReceivedNo")  
  // Добавить в XML документ данные о номерах пакетов
  MessageHeaderElement = XMLDocument.createElement("MessageHeader")
  XMLDocument.documentElement.appendChild(MessageHeaderElement)
  MessageNoElement = XMLDocument.createElement("MessageNo") 
  ReceivedNoElement = XMLDocument.createElement("ReceivedNo") 
  MessageHeaderElement.appendChild(MessageNoElement) 
  MessageHeaderElement.appendChild(ReceivedNoElement)
  MessageNoElement.text = NewMessageNo
  ReceivedNoElement.text = ReceivedMessageNo
  
  // После отладки удалить
  XMLDocument.Save("C:\Directum\Exchange\Debug\DirXMLDocument.xml")
Назовем его для удобства DirXMLDocument.xml, чтобы было ясно, что это исходный XML-файл в формате DIRECTUM. Пример такого файла:

Откроем XSL-преобразование для интересующего нас справочника по кнопке «Редакт. XSL» и посмотрим на него более внимательно:

Условно его можно разбить на две секции:
  
…
  
В этой секции находятся вспомогательные функции на VBScript, которые вызываются из шаблона преобразования.
  
…
  
Непосредственно сам шаблон преобразования, который задает правила, по которым XML-файл в формате DIRECTUM преобразуется в XML-файл формата 1С.
Чтобы иметь возможность отлаживать XSL-преобразование, нам понадобится функция ведения логов, которую я обычно добавляю в конец секции с вспомогательными функциями:
' Записать строку в лог-файл
Sub WriteLog(str)
  Const ForReading = 1, ForWriting = 2, ForAppending = 8
  Dim fso, tf, FileName
  FileName = "C:\Directum\Exchange\Debug\XSL.log"
  Set fso = CreateObject("Scripting.FileSystemObject")
  Set tf = fso.OpenTextFile(FileName, ForAppending, True)
  ' Вставка строки с переносом на новую.
  tf.WriteLine(str) 
  tf.Close
End Sub
    ]]>
  
Теперь добавив в нужном месте в XSL-шаблоне вызов этой процедуры, мы сможем сохранить интересующую нас отладочную информацию:
WriteLog("Строка для лог-файла")
Например, вот так:
        VQueryText = "select " + SelectPart + " from " + ObjectTypeNameForQuery + "." + IntegratedSystemReferenceName + " as C " + CR + WherePart
        ' Сохраним получившийся запрос для анализа в лог-файл
        WriteLog(VQueryText)
        ' Выполнить запрос 1С 
        VQuery.Text = VQueryText
        Set VQueryResult = VQuery.Execute
Теперь посмотрим более внимательно на секцию xsl:template XSL-преобразования. Для вычисления значения реквизитов там присутствуют такие строчки:
                    <ДатаДоговора>
                      
                         
                       
                       
                    ДатаДоговора>
Получается, что при формировании XML-файла в формате 1С значение реквизита вычисляется в функции GetIntegratedSystemRequisiteValue, которой передается ИД записи взятой из исходного XML-файла в формате DIRECTUM, имя реквизита и промежуточный XML-документ DataCache. Если подняться выше, к началу секции xsl:template, то мы увидим там такую строчку:
Отсюда видно, что промежуточный XML-документ формируется в функции GetDataCache, которой передается исходный XML-документ в формате DIRECTUM. Чтобы увидеть содержимое DataCache добавим в конце функции GetDataCache сохранение этого документа в файл (самая первая функция в секции с вспомогательными функциями):
    Call AllCatalogsData.selectSingleNode("/CatalogsData").appendChild(CatalogData.selectSingleNode("/Reference[@Name=""" + DIRECTUMReferenceName + """]"))
    ReferenceIndex = ReferenceIndex - 1
  Wend
  
  Set GetDataCache = AllCatalogsData.selectNodes("/CatalogsData")
' Сохраним DataCache в файл
AllCatalogsData.Save("C:\Directum\Exchange\Debug\DataCache.xml")
End Function   
После того, как мы проведем пробный обмен (кнопка «Выполнить» в карточке «Интегрированные системы»), мы сможем посмотреть содержимое этого XML-файла:

Как видно из представленного скриншота, в DataCache содержится соответствие ID записи справочника DIRECTUM и его UUID записи справочника 1С. В моем случае DataCache формировался неправильно, из-за чего в результирующий XML-файл формата 1С подставлялись неправильные значения UUID для записей справочников, в результате при обмене в значения справочных реквизитов подставлялась ошибка: «объект не найден». Проблему пришлось решать правкой функции GetDataCache. Если внимательнее посмотреть на эту функцию, то мы увидим, что в ней много где из XML-документов выбираются записи согласно определенным условиям в формате XPath:
Set RefRequisites = XMLDocumentElement.item(0).selectNodes("//Object[@Name=""" + ListOfDIRECTUMReferenceName(0) + """]//Requisite[@Type=""Reference""]")
Чтобы разобраться, что же в итоге является результатом этой выборки, можно воспользоваться утилитой Altova XMLSpy.
XMLSpy — редактор XML и среда разработки программного обеспечения (IDE) от компании Altova. XMLSpy позволяет разработчикам создавать приложения на основе XML и веб-сервисы, используя такие технологии как XML, XML Schema, XSLT, XPath, XQuery, WSDL и SOAP. XMLSpy также может работать как дополнение для Microsoft Visual Studio и Eclipse.
XMLSpy доступен для загрузки на сайте производителя (http://www.altova.com/download/xmlspy/xml_editor_enterprise.html) и предоставляется бесплатно сроком на 30 дней. Мне этого времени вполне хватило, чтобы решить проблему, но если кто-то найдет бесплатный аналог данной утилиты, то может использовать его.
Открыв в XMLSpy наш исходный XML-файл в формате DIRECTUM и задав для него условие XPath, мы увидим результат выборки:

Таким образом, можно разобраться, как формируется DataCache для интересующего нас настроенного справочника для обмена, и сформировать его в том виде, в котором нам необходимо.
Используя возможности ведения логов при формировании XML-файла интегрированной системы, наличие во время отладки исходного XML-файла в формате DIRECTUM и промежуточных XML-документов, формируемых коннектором во время формирования этого XML-файла интегрированной системы, мы сможем разобраться в том, как работает XSL-преобразование для интересующего нас настроенного справочника для интеграции. Добавив сюда возможности XMLSpy для просмотра формируемых выборок, заданных условиями XPath, мы сможем корректировать XSL-шаблон по своему усмотрению, чтобы он работал так, как нам надо исходя из поставленной перед нами задачи. Так же все это может пригодиться для поиска ошибок в XSL-шаблоне, если у вас, как и в моем случае неправильно формируется результирующий XML-файл формата интегрированной системы.
После завершения настройки, не забудьте удалить изменения, которые вносили для отладки.
Авторизуйтесь, чтобы написать комментарий