XML Dateien in Excel importieren
Hallo zusammen,
ich möchte zwei XML Dateien (bzw. mehrere) nach Excel importieren.
Mit folgendder Sache klappt es auch ansatzweise.
Im Verzeichnis D:\_TEST\
liegen zwei Dateien TEST.xml und TEST1.xml, leider liest er mir nach Excel immer nur die erste Datei ein die zweite nimmt er nicht.
Wo liegt mein Fehler die Struktur der beiden Dokumente ist gleich?
Sub XML_Dateien_Einlesen()
'
Dim Datei$, Pfad$, DateiMatch$
Dim AnfZelle As Range, Wb As Workbook, Ws As Worksheet
On Error Resume Next
Set Wb = ActiveWorkbook
Set Ws = Wb.ActiveSheet
Set AnfZelle = Ws.Range("A1") '<== Anfangszelle im aktiven Arbeitsblatt der aktiven Arb.Mappe
Pfad$ = "D:\_TEST\" '<== Pfad zum Verzeichnis einstellen
DateiMatch$ = "TEST*.xml" '<== Datei-Matching, um gewünschte Dateien zu filtern
Datei$ = Dir(Pfad$ & DateiMatch$, vbNormal)
Do Until Len(Datei$) = 0
Wb.XmlImport URL:=Pfad$ & Datei$, ImportMap:=Nothing, Overwrite:=True, Destination:=AnfZelle
Datei$ = Dir()
Set AnfZelle = AnfZelle.Offset(1)
Loop
End Sub
ich möchte zwei XML Dateien (bzw. mehrere) nach Excel importieren.
Mit folgendder Sache klappt es auch ansatzweise.
Im Verzeichnis D:\_TEST\
liegen zwei Dateien TEST.xml und TEST1.xml, leider liest er mir nach Excel immer nur die erste Datei ein die zweite nimmt er nicht.
Wo liegt mein Fehler die Struktur der beiden Dokumente ist gleich?
Sub XML_Dateien_Einlesen()
'
Dim Datei$, Pfad$, DateiMatch$
Dim AnfZelle As Range, Wb As Workbook, Ws As Worksheet
On Error Resume Next
Set Wb = ActiveWorkbook
Set Ws = Wb.ActiveSheet
Set AnfZelle = Ws.Range("A1") '<== Anfangszelle im aktiven Arbeitsblatt der aktiven Arb.Mappe
Pfad$ = "D:\_TEST\" '<== Pfad zum Verzeichnis einstellen
DateiMatch$ = "TEST*.xml" '<== Datei-Matching, um gewünschte Dateien zu filtern
Datei$ = Dir(Pfad$ & DateiMatch$, vbNormal)
Do Until Len(Datei$) = 0
Wb.XmlImport URL:=Pfad$ & Datei$, ImportMap:=Nothing, Overwrite:=True, Destination:=AnfZelle
Datei$ = Dir()
Set AnfZelle = AnfZelle.Offset(1)
Loop
End Sub
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 222998
Url: https://administrator.de/contentid/222998
Ausgedruckt am: 25.11.2024 um 21:11 Uhr
12 Kommentare
Neuester Kommentar
Hallo a.grothe,
es funktioniert nur der erste Import, weil du beim zweiten Durchlauf der Schleife als "Destination" einen Bereich angibst der nach dem ersten Import bereits der ersten Datenquelle gehört, bzw. in dem bereits die Daten des ersten Imports stehen. Da ein XML-Import immer mit einer Zuordnung zur XML-Datei durchgeführt wird darf kein anderer Import diesen Bereich überschreiben. Du musst also nach dem ersten Import die nächste leere Zelle ermitteln und dann dort hinein importieren.
Beachte dabei das dann in allen Zeilen des Imports in Spalte A ein Wert stehen muss. Wenn du das nicht sicherstellen kannst, musst du die nächste freie Zelle es über die Eigenschaft "ListRows" des ListObjects ermitteln wie hier:
Noch als Tipps zur Hilfe während der Entwicklungsphase:
Damit du solche Fehler in Zukunft gemeldet bekommst musst du das
Grüße Uwe
es funktioniert nur der erste Import, weil du beim zweiten Durchlauf der Schleife als "Destination" einen Bereich angibst der nach dem ersten Import bereits der ersten Datenquelle gehört, bzw. in dem bereits die Daten des ersten Imports stehen. Da ein XML-Import immer mit einer Zuordnung zur XML-Datei durchgeführt wird darf kein anderer Import diesen Bereich überschreiben. Du musst also nach dem ersten Import die nächste leere Zelle ermitteln und dann dort hinein importieren.
Do Until Len(Datei$) = 0
Wb.XmlImport URL:=Pfad$ & Datei$, ImportMap:=Nothing, Overwrite:=True, Destination:=AnfZelle
Datei$ = Dir()
Set anfZelle = anfZelle.End(xlDown).Offset(1, 0)
Loop
counter = 1
Do Until Len(Datei$) = 0
Wb.XmlImport URL:=Pfad$ & Datei$, ImportMap:=Nothing, Overwrite:=True, Destination:=AnfZelle
Datei$ = Dir()
intNextOffset = Ws.ListObjects(counter).ListRows.Count
Set AnfZelle = AnfZelle.Offset(intNextOffset, 0)
counter = counter + 1
Loop
Damit du solche Fehler in Zukunft gemeldet bekommst musst du das
On Error Resume Next
auskommentieren. Außerdem kannst du dann im VBA-Editor mit Breakpoints und dem Einzelschritt-Modus, Zeile für Zeile den Code ausführen, so siehst du schneller wo es hakt...Grüße Uwe
sorry, hatte eine Variable nicht an deine verwendete angepasst:
hier das "Sheet" durch dein "Ws" ersetzen:
das es so aussieht:
und vergessen nicht, wenn du die Sachen erneut importieren willst musst du erst den gesamten Range löschen
und mach das
Grüße Uwe
hier das "Sheet" durch dein "Ws" ersetzen:
intNextOffset = Sheet.ListObjects(counter).ListRows.Count
intNextOffset = Ws.ListObjects(counter).ListRows.Count
und mach das
On Error Reume Next
mal raus damit du eventuelle Fehler siehst !!Grüße Uwe
Das geht nur über einen Umweg:
Grüße Uwe
Sub XML_Dateien_Einlesen()
Dim Datei$, Pfad$, DateiMatch$
Dim AnfZelle As Range, Wb As Workbook, Ws As Worksheet, lo As ListObject, mainLO As ListObject, col As ListRow
On Error Resume Next
Set Wb = ActiveWorkbook
Set Ws = Wb.ActiveSheet
'Range vorher löschen bevor wir importieren
Ws.Range("A:H").Delete
Set AnfZelle = Ws.Range("A1") '<== Anfangszelle im aktiven Arbeitsblatt der aktiven Arb.Mappe
Pfad$ = "D:\_TEST\" '<== Pfad zum Verzeichnis einstellen
DateiMatch$ = "TEST*.xml" '<== Datei-Matching, um gewünschte Dateien zu filtern
Datei$ = Dir(Pfad$ & DateiMatch$, vbNormal)
counter = 1
Do While Datei$ <> ""
Wb.XmlImport URL:=Pfad$ & Datei$, ImportMap:=Nothing, Overwrite:=True, Destination:=AnfZelle
If counter > 1 Then
Set lo = Ws.ListObjects(2)
Set mainLO = Ws.ListObjects(1)
Set col = mainLO.ListRows.Add
lo.DataBodyRange.Copy col.Range
intNextOffset = lo.ListRows.Count
lo.Delete
Else
Set lo = Ws.ListObjects(1)
intNextOffset = lo.ListRows.Count
End If
Set AnfZelle = AnfZelle.Offset(intNextOffset, 0)
Datei$ = Dir()
counter = counter + 1
Loop
End Sub
VBA/VBS/WSH/Office Developer Referenzen
- Visual Basic-Referenz
- Windows Script Host -Referenz
- Office 2010 Developer References
- Office 2013 Developer References
- Bücher zu VBA
Grüße Uwe
Das Script macht folgendes:
Es importiert die erste CSV-Datei normal, beim Import der zweiten wird eine neue Zeile in der ersten Tabelle erstellt und der Inhalt der zweiten Tabelle ans Ende der ersten Tabelle kopiert, danach wird das ListObject in dem die zweite CSV-Datei importiert wurde wieder gelöscht, usw. Übrig bleibt nur noch eine Tabelle mit dem kompletten Inhalt aller XML-Dateien.
Grüße Uwe
Es importiert die erste CSV-Datei normal, beim Import der zweiten wird eine neue Zeile in der ersten Tabelle erstellt und der Inhalt der zweiten Tabelle ans Ende der ersten Tabelle kopiert, danach wird das ListObject in dem die zweite CSV-Datei importiert wurde wieder gelöscht, usw. Übrig bleibt nur noch eine Tabelle mit dem kompletten Inhalt aller XML-Dateien.
Grüße Uwe
Zitat von @a.grothe:
Danke. Es klappt nun wunderbar. Kann man den Pfad noch so anpassen, das er auch Unterverzeichnisse durchsucht?
Kann man, das erfordert aber einen radikalen Umbau. Ich habe die Zeilen mal kommentiert, damit du es hoffentlich besser verstehst:Danke. Es klappt nun wunderbar. Kann man den Pfad noch so anpassen, das er auch Unterverzeichnisse durchsucht?
Dim AnfZelle As Range, TempZelle As Range, fso As Object, Wb As Workbook, Ws As Worksheet, Prefix As String, extension As String, firstImport As Boolean
Sub XML_Dateien_Einlesen()
Set Wb = ActiveWorkbook
Set Ws = Wb.ActiveSheet
'Filesystem Object erstellen
Set fso = CreateObject("Scripting.FileSystemObject")
'Root-Pfad zu den Dateien
Pfad = "D:\_TEST"
'Prefix der zu importierenden Dateien
Prefix = "TEST"
'Extension der Dateien
extension = "xml"
'Import-Bereich löschen damit neu importiert werden kann/ wenn die importierten XML-Dateien mehr Spalten als 8 haben entsprechend anpassen
Ws.Range("A:H").Delete
'Import-Anfangszelle setzen
Set AnfZelle = Ws.Range("A1")
' Temporäre Zelle für den Import von weiteren XML-Dateien
Set TempZelle = Ws.Range("Z1")
firstImport = True
'Ordner mit Funktion rekursiv durchsuchen
parseFolder fso.GetFolder(Pfad), True
'Garbage collection
Set fso = Nothing
Set Wb = Nothing
Set Ws = Nothing
End Sub
'Diese Funktion durchläuft die Unterordner rekursiv
Function parseFolder(strFldr, boolRecursion)
For Each f In strFldr.Files
'Wenn Datei die Extension 'xml' hat und mit 'TEST' beginnt dann...
If LCase(extension) = LCase(fso.GetExtensionName(f.Path)) And Left(fso.GetFilename(f.Path), 4) = Prefix Then
If Not firstImport Then
' Importiere weitere XML-Dateien
Wb.XmlImport URL:=f.Path, ImportMap:=Nothing, Overwrite:=True, Destination:=TempZelle
'ListObject an der temporär importierten Zelle
Set lo = Ws.ListObjects(2)
'Haupt ListObject in das wir den Inhalt des anderen ListObject importieren werden
Set mainLO = Ws.ListObjects(1)
'Eine neue Reihe im Haupt ListObject hinzufügen
Set col = mainLO.ListRows.Add
'Inhalt des temporären ListObject in das Haupt ListObject kopieren
lo.DataBodyRange.Copy col.Range
'temporäres ListObject wieder löschen
lo.Delete
Else
'Importiere erste XML-Datei
Wb.XmlImport URL:=f.Path, ImportMap:=Nothing, Overwrite:=True, Destination:=AnfZelle
' Die erste XML-Datei ist importiert also setze firstImport = False
firstImport = False
End If
End If
Next
'Funktion rekursiv für alle Unterordner ausführen
If boolRecursion Then
For Each subFolder In strFldr.SubFolders
parseFolder subFolder, True
Next
End If
End Function
Dann den Beitrag bitte noch als gelöst markieren. Merci.
Grüße Uwe
Grüße Uwe