DatenbankManufaktur

XML2VBA  =  XML  ▷  VBA-Code  ▷  XML

XML ist eines der wichtigsten Formate für den systemübergreifenden Datenaustausch. Mit Office-Bordmitteln können einfache Strukturen schnell exportiert werden. Mit etwas VBA und wenigen Hilfsfunktionen lassen sich aber auch sehr komplexe, tief verschachtelte Strukturen erzeugen, die sogar Attribute enthalten können.

Wo liegt das Problem?

Das Erstellen des VBA-Codes, mit dem die Hilfsfunktionen aufgerufen werden, ist der eigentliche Aufwand. Für jedes (Eltern-)Element muss ein Objekt deklariert und zugewiesen werden, dem dann ein Unterelement oder Attribut hinzugefügt wird, jedes Element mit einem eigenen Namen und Schlüssel. Schon eine niedrige zweistellige Anzahl an Elementen (evtl. sogar mit Namespace-Prefixes und mehreren Attributen) erfordert viel Fleißarbeit. Und die teilweise langen und kryptischen Elementnamen machen die Arbeit und die Kontrolle des Ergebnisses nicht einfacher.

Geht das nicht einfacher?

Ich habe das Tool XML2VBA entwickelt, mit dem ich eine Musterdatei im XML-Format einlese und den notwendigen VBA-Code erzeuge, um diese wieder zu generieren. Der VBA-Code wird dann auch gleich in einem eigenen Modul gespeichert, ausgeführt und die damit generierte Datei zur Sicherheit noch mit der Musterdatei verglichen.

Das fertige Modul kann dann in die eigentliche Anwendung kopiert werden, wo 'nur noch' die konstanten Werte aus der Musterdatei an die entsprechende Datenquelle angebunden werden und Schleifen um sich wiederholende Strukturen gelegt werden müssen.

Wie sieht das z. B. für eine ZUGFeRD-Rechnung aus?

Das Rechnungsformat ZUGFeRD (Zentraler User Guide des Forums elektronische Rechnung Deutschland) enthält eine komplexe XML-Datei, die in ein PDF eingebettet ist. Schon die minimale Version enthält mehrere Namespaces und viele Elemente und Attribute:

<?xml version='1.0' encoding='UTF-8' ?>
<rsm:CrossIndustryInvoice xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100" xmlns:qdt="urn:un:unece:uncefact:data:standard:QualifiedDataType:100" xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100">
  <rsm:ExchangedDocumentContext>
   <ram:GuidelineSpecifiedDocumentContextParameter>
      <ram:ID>urn:factur-x.eu:1p0:minimum</ram:ID>
    </ram:GuidelineSpecifiedDocumentContextParameter>
  </rsm:ExchangedDocumentContext>
  <rsm:ExchangedDocument>
    <ram:ID>471102</ram:ID>
    <ram:TypeCode>380</ram:TypeCode>
    <ram:IssueDateTime>
      <udt:DateTimeString format="102">20200305</udt:DateTimeString>
    </ram:IssueDateTime>
  </rsm:ExchangedDocument>
...

So sieht der von XML2VBA generierte (etwas gekürzte) Code z. B. für eine solche einfache Rechnung aus:

Public Function CreateTest()
' ----------------------------------------------------------------
' Gerüst, um die eingelesene Datei factur-x.xml zu erstellen
' ----------------------------------------------------------------
   Dim oXML As DOMDocument60
   Dim oPI As IXMLDOMProcessingInstruction
   Dim oCrossIndustryInvoice As IXMLDOMNode
   Dim oGuidelineSpecifiedDocumentContextParameter As IXMLDOMNode
   Dim oExchangedDocumentContext As IXMLDOMNode
   Dim oDateTimeString As IXMLDOMNode
' ...
   Set oXML = New DOMDocument60
   fCreatePI oXML, "xml", "version='1.0' encoding='UTF-8'"
   Set oCrossIndustryInvoice = fCreateElement(oXML, "rsm:CrossIndustryInvoice")
   fCreateAttribute oCrossIndustryInvoice, "xmlns:rsm", "urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"
   fCreateAttribute oCrossIndustryInvoice, "xmlns:qdt", "urn:un:unece:uncefact:data:standard:QualifiedDataType:100"
   fCreateAttribute oCrossIndustryInvoice, "xmlns:ram", "urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"
   fCreateAttribute oCrossIndustryInvoice, "xmlns:xs", "http://www.w3.org/2001/XMLSchema"
   fCreateAttribute oCrossIndustryInvoice, "xmlns:udt", "urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100"
   Set oExchangedDocumentContext = fCreateElement(oCrossIndustryInvoice, "rsm:ExchangedDocumentContext")
   Set oGuidelineSpecifiedDocumentContextParameter = fCreateElement(oExchangedDocumentContext, "ram:GuidelineSpecifiedDocumentContextParameter")
   fCreateElement oGuidelineSpecifiedDocumentContextParameter, "ram:ID", "urn:factur-x.eu:1p0:minimum"
   Set oExchangedDocument = fCreateElement(oCrossIndustryInvoice, "rsm:ExchangedDocument")
   fCreateElement oExchangedDocument, "ram:ID", "471102"
   fCreateElement oExchangedDocument, "ram:TypeCode", "380"
   Set oIssueDateTime = fCreateElement(oExchangedDocument, "ram:IssueDateTime")
   Set oDateTimeString = fCreateElement(oIssueDateTime, "udt:DateTimeString", "20200305")
   fCreateAttribute oDateTimeString, "format", "102"
' ...
   oXML.Save CurrentProject.Path & "\factur-x_GEN.xml"
End Function

Es werden 34 Definitionen und 93 Zeilen VBA-Code (ohne die Hilfsfunktionen) erstellt. Nun können die konstanten Werte aus der Musterdatei durch die entsprechenden Datenfelder ersetzt werden. Das anschließende Einbetten der XML-Datei in die PDF-Rechnung ist der einfachste Teil der Aufgabe.

Wie kann ich Ihnen weiterhelfen?

Sie möchten auch eine XML-Datei aus Ihrer bestehenden Anwendung erstellen? Ob ZUGFeRD-PDF für B2B-Rechnungen, XRechnungen an Behörden, TEIS-Dateien für das Gesundheitsamt oder DATEV-Dateien für Ihre Buchhaltung: Ich erstellen Ihnen aus Ihrer Vorlage für (fast) alle XML-Dateien mit meinem Tool XML2VBA das benötigte Funktionsgerüst. Und wenn Sie Hilfe brauchen, um die Struktur mit Ihren Daten zu füllen, unterstütze ich Sie gerne auch dabei. Fragen Sie mich einfach unverbindlich nach einem Angebot.