如何使用 VBA 将多个 XML 文件导入 Excel 而不覆盖已导入的文件

How to Import multiple XML Files into Excel with VBA without overwriting the files that have already been imported

我有一个包含多个 XML-Files 的目录。每天都有新 XML-Files 添加到目录中。

我每天都在尝试将那些 XML-Files 导入一个特定的 Excel Sheet,而不覆盖我 Excel Sheet 中的现有数据。

我已经成功导入 XML-Files。

希望有人能帮我解决这个问题。想了很久的解决办法,自己或网上都找不到答案。

这是我的 XML-Files 的结构:

<?xml version="1.0" encoding="utf-8"?>
<MFK_XML xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Auftrag>
    <WarenkorbReferenz>0</WarenkorbReferenz>
    <JobNr>12345-999</JobNr>
    <KuNr>12345</KuNr>
    <ReNr>7</ReNr>
    <SoA>0</SoA>
    <Termin>2020-03-10</Termin>
    <Versandtermin>2020-03-09</Versandtermin>
    <Gewicht>1.1037620</Gewicht>
    <Datencheck>0</Datencheck>
    <Proof>0</Proof>
    <Kundenhinweis />
    <Auflage>5</Auflage>
    <Versionen>1</Versionen>
    <Gesamtpreis>15.50</Gesamtpreis>
    <Priority>S</Priority>
    <ProduktionsTage>5</ProduktionsTage>
    <Mandant />
    <LNr>151</LNr>
    <IVB>10</IVB>
    <Gratis>0</Gratis>
    <Transfer>2020-03-02</Transfer>
  </Auftrag>
  <Artikel>
    <Artikelbezeichnung>Broschüre mit Metall-Spiralbindung, Endformat DIN A4, 48-seitig</Artikelbezeichnung>
    <ArtikelID>12345</ArtikelID>
    <ArtStr>Flex</ArtStr>
    <ProdKrzl>FlX</ProdKrzl>
    <Sorte>135g Innenteil mit 250g Umschlag (matt, hochwertiger Qualitätsdruck, 4/4-farbig)</Sorte>
    <SortenID>152</SortenID>
    <Seitenzahl>48</Seitenzahl>
    <SeitenZahlMalVersionen>48</SeitenZahlMalVersionen>
    <Seitenzahlgesamt>48</Seitenzahlgesamt>
    <SeitenzahlInhalt />
    <SeitenzahlUmschlag />
    <Farbigkeit>44</Farbigkeit>
    <FarbigkeitInhalt />
    <FarbigkeitUmschlag />
    <PapierInnen>135g Innenteil</PapierInnen>
    <PapierUmschlag>250g Umschlag (matt, hochwertiger Qualitätsdruck, 4/4-farbig)</PapierUmschlag>
    <Endformat_mm_X>210</Endformat_mm_X>
    <Endformat_mm_Y>297</Endformat_mm_Y>
    <Datenformat_mm_X>216</Datenformat_mm_X>
    <Datenformat_mm_y>303</Datenformat_mm_y>
    <FormatUmschlag_x />
    <FormatUmschlag_y />
    <EndFormatUmschlag_x />
    <EndFormatUmschlag_y />
    <Falzart>0</Falzart>
    <Falzlauf />
    <gefendFormat_x />
    <gefendFormat_y />
    <BeschnittI>3</BeschnittI>
    <BeschnittU />
    <Bundstaerke>3</Bundstaerke>
    <vWd>0</vWd>
    <pWd>0</pWd>
    <vUV>0</vUV>
    <pUV>0</pUV>
    <Rillung>0</Rillung>
    <KissCut>0</KissCut>
    <Druckverfahren>Druck</Druckverfahren>
    <dataformat>pdf</dataformat>
    <Zusatzinfo>Schwarz</Zusatzinfo>
  </Artikel>
  <Optionen>
    <Veredelung>0</Veredelung>
    <Falzung>0</Falzung>
    <Ausrichtung>0</Ausrichtung>
    <Heften>0</Heften>
    <Nutung>0</Nutung>
    <Buendelung>0</Buendelung>
    <Leimung>0</Leimung>
    <Perforierung>0</Perforierung>
    <Sonderfarbe>0</Sonderfarbe>
    <Lochbohrungen_Ecken>0</Lochbohrungen_Ecken>
    <Nummerierung>0</Nummerierung>
    <Barcode>0</Barcode>
    <Hologramm>0</Hologramm>
    <Abheftvorrichtung>0</Abheftvorrichtung>
    <Cello>
      <Cellophaniert>0</Cellophaniert>
      <CelloArt>0</CelloArt>
    </Cello>
    <stanze>
      <StanzeForm>keine</StanzeForm>
      <StanzeOffset>0</StanzeOffset>
    </stanze>
    <Einschweissen>0</Einschweissen>
    <Fadenheftung>0</Fadenheftung>
    <Werbefolie>0</Werbefolie>
    <Ecken_abrunden>0</Ecken_abrunden>
    <RAL_Farbe>0</RAL_Farbe>
    <Gummiband_Verschluss>0</Gummiband_Verschluss>
    <HKS_Pantone>0</HKS_Pantone>
    <Lochung>0</Lochung>
    <PP_Deck>0</PP_Deck>
    <DeckBl_V>0</DeckBl_V>
    <DeckBl_V_H>0</DeckBl_V_H>
    <Praegung>0</Praegung>
    <Rubbelfeld>0</Rubbelfeld>
    <Magnetstreifen>0</Magnetstreifen>
    <Unterschriftsfeld>0</Unterschriftsfeld>
    <Magnetpunkt_Verschluss>0</Magnetpunkt_Verschluss>
    <Griffloch>0</Griffloch>
    <Verchromte_Buchecken>0</Verchromte_Buchecken>
    <Rueckentasche>0</Rueckentasche>
    <Visitenkartentasche>0</Visitenkartentasche>
    <Dreieckstasche>0</Dreieckstasche>
    <Kombitasche>0</Kombitasche>
    <CD_Tasche>0</CD_Tasche>
    <Radooesen>0</Radooesen>
    <Postkarten_indiv_personalisieren>0</Postkarten_indiv_personalisieren>
    <LED_Halogenbeleuchtung>0</LED_Halogenbeleuchtung>
    <Klima>1</Klima>
  </Optionen>
  <Zusatzkosten />
  <Dateien>
    <Dateiname>12345-999.pdf</Dateiname>
  </Dateien>
  <WF_Name>
    <WF_Name>12345-999.pdf</WF_Name>
  </WF_Name>
</MFK_XML> 

这是 VBA 的代码:

Sub From_XML_To_XL()
    Dim xWb As Workbook
    Dim xSWb As Workbook
    Dim xStrPath As String
    Dim xFileDialog As FileDialog
    Dim xFile As String
    Dim xCount As Long

    On Error GoTo ErrHandler

    Set xFileDialog = Application.FileDialog(msoFileDialogFolderPicker)
    xFileDialog.AllowMultiSelect = False
    xFileDialog.Title = "Select a folder"
    If xFileDialog.Show = -1 Then
        xStrPath = xFileDialog.SelectedItems(1)
    End If
    If xStrPath = "" Then Exit Sub
    Application.ScreenUpdating = False
    Set xSWb = ThisWorkbook
    xCount = 1
    xFile = Dir(xStrPath & "\*.xml")
    Do While xFile <> ""
        Set xWb = Workbooks.OpenXML(xStrPath & "\" & xFile)
        xWb.Sheets(1).UsedRange.Copy xSWb.Sheets(1).Cells(xCount, 1)
        xWb.Close False
        xCount = xSWb.Sheets(1).UsedRange.Rows.Count + 2
        xFile = Dir()
    Loop
    Application.ScreenUpdating = True
    xSWb.Save
    Exit Sub

ErrHandler:
    MsgBox "no files xml"
End Sub

考虑 XSLT, the special-purpose language to transform XML files, which you can use its document() function to combine all XMLs in the directory. Then, import the resulting transformed file as one document into Excel. Office VBA can run XSLT 1.0 with the MSXML 图书馆。

以下假设所有 XML 文件(无论重复元素如何)都保留了准确的结构,其中每个文档都映射到根级别 <MFK_XML>。为每个文档添加以下 <xsl:copy-of ...> 行。如果您有数百个,请考虑使用 VBA、Python 等在循环中构建 XSLT 文档。如果发布的文件相对较小,XSLT 是一个可行的解决方案,但确实有内存限制。

XSLT (另存为.xsl,一个特殊的.xml文件)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes" encoding="UTF-8"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="/MFK_XML">
    <MFK_XML>
        <xsl:copy-of select="document('First.xml')/MFK_XML/*" />
        <xsl:copy-of select="document('Second.xml')/MFK_XML/*" />
        <xsl:copy-of select="document('Third.xml')/MFK_XML/*" />
        <!-- ADD: <xsl:copy-of select="document('XXXX.xml')/MFK_XML/*" /> -->
    </MFK_XML>
  </xsl:template>

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>    

</xsl:stylesheet>

VBA (不需要循环)

Sub XSLTransform()
On Error GoTo ErrHandle
    ' ENABLE Microsoft XML, v#.# IN REFERENCES
    Dim xmldoc As New MSXML2.DOMDocument60, xslDoc As New MSXML2.DOMDocument60
    Dim newDoc As New MSXML2.DOMDocument60
    Dim xWb As Workbook

    ' LOAD XML AND XSL FILES
    xmldoc.async = False
    xmldoc.Load "C:\Path\To\Any.xml"

    xslDoc.async = False
    xslDoc.Load "C:\Path\To\Script.xsl"
    xslDoc.setProperty "AllowDocumentFunction", True

    ' TRANSFORM XML
    xmldoc.transformNodeToObject xslDoc, newDoc
    newDoc.Save "C:\Path\To\Transformed.xml"

    Set xWb = Workbooks.OpenXML("C:\Path\To\Transformed.xml")
    xWb.SaveAs "C:\Path\To\Final.xlsx"
    xWb.Close False

ExitHandle:
    Set xmldoc = Nothing: Set xslDoc = Nothing: Set newDoc = Nothing
    Set xWb = Nothing
    Exit Sub

ErrHandle:
    MsgBox Err.Number & " - " & Err.Description, vbCritical
    Resume ExitHandle
End Sub