❤️ Helfen Sie jetzt mit, unser LibreOffice Forum zu erhalten! ❤️
Mit Ihrer Spende sichern Sie den Fortbestand, den Ausbau und die laufenden Kosten dieses Forums. 🌱
🍀 Jeder Beitrag zählt – vielen Dank für Ihre Unterstützung!🍀
>> Dank Ihrer Unterstützung -> Keine Werbung für alle registrierten LibreOffice-Forum User! <<
🤗 Als Dankeschön werden Sie im Forum als LO-SUPPORTER gekennzeichnet. 🤗
Bestimmte Daten aus sehr vielen ODT-Dateien auslesen
Bestimmte Daten aus sehr vielen ODT-Dateien auslesen
Hallo
Vermutlich eine etwas untypische Anfrage:
Ich habe eine grössere Zahl (mehrere Tausend) "gleichförmiger" ODT-Dateien. Namentlich Rechnungen die wir früher mal erstellt haben. Alle basierend auf der selben Vorlage.
In diesen Rechnungen gibt es stets ein Textfeld, indem auf drei (selten vier) Zeilen Name & Adresse des jeweiligen Kunden stehen.
Und an genau diese Daten müssten wir jetzt ran. Ideal wäre Export in ein CSV-File oder ähnliches. Sodass am Ende, wenn man es um Duplikate bereinigt, quasi eine Kundenkartei in einem CSV-File vorhanden ist.
Aufgrund der grossen Zahl an Dateien wäre es natürlich mühsam, das von Hand zu machen. Daher frage ich mich, ob sich das irgendwie automatisieren lässt?
Danke für eure Ideen!
Vermutlich eine etwas untypische Anfrage:
Ich habe eine grössere Zahl (mehrere Tausend) "gleichförmiger" ODT-Dateien. Namentlich Rechnungen die wir früher mal erstellt haben. Alle basierend auf der selben Vorlage.
In diesen Rechnungen gibt es stets ein Textfeld, indem auf drei (selten vier) Zeilen Name & Adresse des jeweiligen Kunden stehen.
Und an genau diese Daten müssten wir jetzt ran. Ideal wäre Export in ein CSV-File oder ähnliches. Sodass am Ende, wenn man es um Duplikate bereinigt, quasi eine Kundenkartei in einem CSV-File vorhanden ist.
Aufgrund der grossen Zahl an Dateien wäre es natürlich mühsam, das von Hand zu machen. Daher frage ich mich, ob sich das irgendwie automatisieren lässt?
Danke für eure Ideen!
-
- Beiträge: 3
- Registriert: Mo 28. Feb 2022, 09:14
Re: Bestimmte Daten aus sehr vielen ODT-Dateien auslesen
moin,
ich kenne mich zwar nicht in Libre Office aus, aber wäre da spontan bei PHP. Was spricht dagegen, die Files einzeln einzulesen, die entsprechenden Daten in ein Array zu schreiben und am Ende in eine CSV ode DB zu speichern.
LG
ich kenne mich zwar nicht in Libre Office aus, aber wäre da spontan bei PHP. Was spricht dagegen, die Files einzeln einzulesen, die entsprechenden Daten in ein Array zu schreiben und am Ende in eine CSV ode DB zu speichern.
LG
Re: Bestimmte Daten aus sehr vielen ODT-Dateien auslesen
Hallo,
kannst du so ein Datei (verfremdet) beispielhaft hier zur Verfügung stellen?
Prinzipiell kann man per Makro an alle dateien 'ran. Das entscheidende ist das Identifizieren des Textfeldes. Als echtes Textfeld hat es einen Namen, über den man da Zugriff erlangen kann.
kannst du so ein Datei (verfremdet) beispielhaft hier zur Verfügung stellen?
Prinzipiell kann man per Makro an alle dateien 'ran. Das entscheidende ist das Identifizieren des Textfeldes. Als echtes Textfeld hat es einen Namen, über den man da Zugriff erlangen kann.
Gruß,
mikele
mikele
Re: Bestimmte Daten aus sehr vielen ODT-Dateien auslesen
Hallo
Also wenn ich die content.xml aus der ODT Datei auslese, dann scheint das Textfeld bei den "neueren" Dateien stets "Form1" zu heissen (draw:name="Form1").
Allerdings ist das nur bei den neuesten ca. 450 Dateien der Fall. Bei den älteren Dateien (und das sind wohl nochmal etwa 2000) fehlt der "name" bei der Form im XML.
Dort steht dann nur sowas:
D.h. der Teil mit dem draw:name="Form1" fehlt bei den "älteren" Dateien.
Woher der Unterschied kommt ist mir übrigens ein Rätsel. Die Dateien entstammen alle der selben Vorlage, welche soweit ich sehe nicht angepasst wurde. Aber vielleicht gab es mal ein LibreOffice Update das beschlossen hat, dass alle Textfelder die noch keinen Namen haben jetzt automatisch einen verpasst bekommen. Wer weiss.
Liesse sich so ein Makro denn "Batch-artig" über viele ODT Datein laufen?
Also wenn ich die content.xml aus der ODT Datei auslese, dann scheint das Textfeld bei den "neueren" Dateien stets "Form1" zu heissen (draw:name="Form1").
Allerdings ist das nur bei den neuesten ca. 450 Dateien der Fall. Bei den älteren Dateien (und das sind wohl nochmal etwa 2000) fehlt der "name" bei der Form im XML.
Dort steht dann nur sowas:
Code: Alles auswählen
<draw:frame text:anchor-type="page" text:anchor-page-number="1" draw:z-index="1" draw:style-name="gr1" draw:text-style-name="P43" svg:width="7.667cm" svg:height="1.4cm" svg:x="3.069cm" svg:y="5.964cm">
Woher der Unterschied kommt ist mir übrigens ein Rätsel. Die Dateien entstammen alle der selben Vorlage, welche soweit ich sehe nicht angepasst wurde. Aber vielleicht gab es mal ein LibreOffice Update das beschlossen hat, dass alle Textfelder die noch keinen Namen haben jetzt automatisch einen verpasst bekommen. Wer weiss.
Liesse sich so ein Makro denn "Batch-artig" über viele ODT Datein laufen?
Re: Bestimmte Daten aus sehr vielen ODT-Dateien auslesen
Hier nochmal das konkrete XML der "neueren" Dateien:
Und der "älteren" Dateien:
Ob die Zahlen "P41", "T41" etc. über viele Dateien konsistent sind, muss ich noch näher anschauen.
Code: Alles auswählen
<draw:frame text:anchor-type="page" text:anchor-page-number="1" draw:z-index="1" draw:name="Form1" draw:style-name="gr3" draw:text-style-name="P43" svg:width="8.067cm" svg:height="2.331cm" svg:x="3.069cm" svg:y="5.964cm">
<draw:text-box>
<text:p>
<text:span text:style-name="T39">Name</text:span>
</text:p>
<text:p>
<text:span text:style-name="T39">Strasse</text:span>
</text:p>
<text:p>
<text:span text:style-name="T39">Ort</text:span>
</text:p>
<text:p>
<text:span text:style-name="T39"/>
</text:p>
</draw:text-box>
</draw:frame>
Code: Alles auswählen
<draw:frame text:anchor-type="page" text:anchor-page-number="1" draw:z-index="1" draw:style-name="gr1" draw:text-style-name="P41" svg:width="7.667cm" svg:height="1.865cm" svg:x="3.069cm" svg:y="5.964cm">
<draw:text-box>
<text:p>
<text:span text:style-name="T41">Name</text:span>
</text:p>
<text:p>
<text:span text:style-name="T41">Strasse</text:span>
</text:p>
<text:p>
<text:span text:style-name="T41">Ort</text:span>
</text:p>
<text:p>
<text:span text:style-name="T41"/>
</text:p>
</draw:text-box>
</draw:frame>
Re: Bestimmte Daten aus sehr vielen ODT-Dateien auslesen
Hallo,
das löst es nur teilweise auf.
Man kann so eine Textbox (sich nenne sie mal so) sehr unterschiedlich erstellen.
Es kann ein Textrahmen sein, ein Textfeld (als grafisches Element) oder als Textfeld (als Kontrollelement). Ich vermute jetzt mal, dass es ein graf. Element ist.
Wenn du in so einem Dokument mal über ->Ansicht->Symbolleisten->Formular-Entwurf aktivierst, bekommst du eine Symbolleiste bei der ein Symbol der so genannte Formular-Navigator ist. Wenn du den mal anklickst und da nichts von Textfeld 1 (oder so) steht, ist davon auszugehen, dass es sich wirklich um ein graf. Element handelt.
Wie das in den anderen Dokumenten aussieht und gelöst wurde müsstest du noch herausbekommen. Schau dir mal dort den Navigator und den Formular-Navigator an.
Gibt es in den Dokumenten noch mehr grafische Elemente? Ist es immer "Form1"?
Die Zahlen "P41", "T41" sind uninteressant, da der Zugriff nicht über die xml-Dateien erfolgen würde.
das löst es nur teilweise auf.
Man kann so eine Textbox (sich nenne sie mal so) sehr unterschiedlich erstellen.
Es kann ein Textrahmen sein, ein Textfeld (als grafisches Element) oder als Textfeld (als Kontrollelement). Ich vermute jetzt mal, dass es ein graf. Element ist.
Wenn du in so einem Dokument mal über ->Ansicht->Symbolleisten->Formular-Entwurf aktivierst, bekommst du eine Symbolleiste bei der ein Symbol der so genannte Formular-Navigator ist. Wenn du den mal anklickst und da nichts von Textfeld 1 (oder so) steht, ist davon auszugehen, dass es sich wirklich um ein graf. Element handelt.
Wie das in den anderen Dokumenten aussieht und gelöst wurde müsstest du noch herausbekommen. Schau dir mal dort den Navigator und den Formular-Navigator an.
Gibt es in den Dokumenten noch mehr grafische Elemente? Ist es immer "Form1"?
Die Zahlen "P41", "T41" sind uninteressant, da der Zugriff nicht über die xml-Dateien erfolgen würde.
Gruß,
mikele
mikele
Re: Bestimmte Daten aus sehr vielen ODT-Dateien auslesen
Im Navigator ist das betreffende Element bei allen Stichproben die ich gemacht habe immer "Form1" (auch bei den älteren Dokumenten, in denen im XML nichts von Form1 steht)
Es läuft im Navigator unter "Zeichnungsobjekte".
Es gibt auch noch andere solche "Zeichnungsobjekte", aber das wofür ich mich interessiere scheint wirklich immer "Form1" zu sein (was eigentlich auch nicht verwunderlich ist, da diese Dokumente wie gesagt alle von der selben "Quelle" ausgehen)
Es läuft im Navigator unter "Zeichnungsobjekte".
Es gibt auch noch andere solche "Zeichnungsobjekte", aber das wofür ich mich interessiere scheint wirklich immer "Form1" zu sein (was eigentlich auch nicht verwunderlich ist, da diese Dokumente wie gesagt alle von der selben "Quelle" ausgehen)
Re: Bestimmte Daten aus sehr vielen ODT-Dateien auslesen
Hallo,
ich habe mal ein bisschen gespielt und ein Makro zusammengebastelt:
In der ersten Codezeile ergänzt du den Pfad zu deinen Dateien. Am besten legst du dir ein Testverzeichnis an, in das du ein paar wenige Dateien kopierst.
Das Makro durchsucht das Verzeichis nach .odt-Dateien, öffnet sie nacheinander im Hintergrund, sucht ein Grafikelement namens "Form1" und liest dessen Text aus. Die Texte werden am Ende in die Spalte A der calc-Datei geschrieben.
Probier' mal, ob es das macht, was du suchst.
ich habe mal ein bisschen gespielt und ein Makro zusammengebastelt:
Code: Alles auswählen
sub test
'das Verzeichnis in dem die Dateien liegen
sVerzeichnis="Pfad zu deinen Dateien"
'Zugriff auf den Ordner und Auslesen aller Dateinamen
oSimpleFileAccess = createUnoService( "com.sun.star.ucb.SimpleFileAccess" )
aDateien = oSimpleFileAccess.getFolderContents(ConvertToUrl(sVerzeichnis),false )
Dim arg(0) as new com.sun.star.beans.PropertyValue
arg(0).Name = "Hidden"
arg(0).Value = true
n=ubound(aDateien)
Dim adressen(n)
'Durchlauf durch alle Dateien
for i=0 to n
adressen(i)=Array("")
if right(aDateien(i),4)=".odt" then
'Datei im Hintergrund öffnen
odoc=StarDesktop.LoadComponentFromURL(adateien(i), "_blank",0,arg())
oForms=odoc.Drawpage
'Durchlauf durch alle graf. Elemente, Form1 auslesen
for k=0 to oForms.count-1
if oforms.getbyindex(k).name="Form1" then
adressen(i)=array(oforms(k).String)
end if
next
'Datei schließen
odoc.close(false)
end if
next
'Texte in Spalte A schreiben
Thiscomponent.Sheets(0).getcellrangebyposition(0,0,0,n).setDataArray(adressen)
end sub
Das Makro durchsucht das Verzeichis nach .odt-Dateien, öffnet sie nacheinander im Hintergrund, sucht ein Grafikelement namens "Form1" und liest dessen Text aus. Die Texte werden am Ende in die Spalte A der calc-Datei geschrieben.
Probier' mal, ob es das macht, was du suchst.
- Dateianhänge
-
- makro odt auslesen.ods
- (9.31 KiB) 204-mal heruntergeladen
Gruß,
mikele
mikele
Re: Bestimmte Daten aus sehr vielen ODT-Dateien auslesen
Vielen Dank, es sieht schonmal ziemlich gut aus!
Das Makro scheint das zu tun, was du beschreibst: Den Inhalt der gewünschten Textfiles in die Spalte A der Tabelle zu schreiben.
Genaugenommen kriege ich sogar 1926 Zeilen in der Tabelle, obwohl ich nur 1888 Dateien reingefüttert hab, wie das kommt sehe ich allerdings momentan noch nicht. Aber das kommt vielleicht noch bei genauerer Betrachtung des Outputs.
Für die weitere Verwendung wäre es nun sehr hilfreich, wenn die Daten nicht alle in Spalte A abgelegt würden. Ideal wäre, wenn die erste Zeile (des Textfelds) in Spalte A käme, die zweite Zeile in Spalte B, die dritte in Spalte C und so weiter.
In der überwiegenden Mehrzahl der Fälle wird es nur drei Zeilen geben (Name, Strasse, Ort), die wenigen restlichen Fälle die vielleicht vier oder fünf Zeilen haben würden sich dann leicht erkennen lassen und könnten gut von Hand nachgearbeitet werden.
Würde sich das ebenfalls über so ein Makro realisieren lassen oder ist das zu komplex?
Übrigens: Die Zeilenumbrüche werden in die Tabellenzelle übernommen, d.h. ggf. ist es einfacher das Resultat des ersten Makros in einem zweiten Durchlauf mit einem weiteren Makro oder einer anderen Methode so zu bearbeiten, dass aus
aaa
bbb
ccc
(eine Zelle)
aaa | bbb | ccc
(drei Zellen in einer Zeile)
wird?
Das Makro scheint das zu tun, was du beschreibst: Den Inhalt der gewünschten Textfiles in die Spalte A der Tabelle zu schreiben.
Genaugenommen kriege ich sogar 1926 Zeilen in der Tabelle, obwohl ich nur 1888 Dateien reingefüttert hab, wie das kommt sehe ich allerdings momentan noch nicht. Aber das kommt vielleicht noch bei genauerer Betrachtung des Outputs.
Für die weitere Verwendung wäre es nun sehr hilfreich, wenn die Daten nicht alle in Spalte A abgelegt würden. Ideal wäre, wenn die erste Zeile (des Textfelds) in Spalte A käme, die zweite Zeile in Spalte B, die dritte in Spalte C und so weiter.
In der überwiegenden Mehrzahl der Fälle wird es nur drei Zeilen geben (Name, Strasse, Ort), die wenigen restlichen Fälle die vielleicht vier oder fünf Zeilen haben würden sich dann leicht erkennen lassen und könnten gut von Hand nachgearbeitet werden.
Würde sich das ebenfalls über so ein Makro realisieren lassen oder ist das zu komplex?
Übrigens: Die Zeilenumbrüche werden in die Tabellenzelle übernommen, d.h. ggf. ist es einfacher das Resultat des ersten Makros in einem zweiten Durchlauf mit einem weiteren Makro oder einer anderen Methode so zu bearbeiten, dass aus
aaa
bbb
ccc
(eine Zelle)
aaa | bbb | ccc
(drei Zellen in einer Zeile)
wird?
Re: Bestimmte Daten aus sehr vielen ODT-Dateien auslesen
Hallo,
so mal auf die Schnelle:
Um maximal 5 Adresszeilen zu erhalten, änderst du
in
und am Ende
in
so mal auf die Schnelle:
Um maximal 5 Adresszeilen zu erhalten, änderst du
Code: Alles auswählen
if oforms.getbyindex(k).name="Form1" then
adressen(i)=array(oforms(k).String)
end if
Code: Alles auswählen
if oforms.getbyindex(k).name="Form1" then
'Zerlegen des String in die einzelnen Absätze, max. 5
atmp=split(oforms(k).String,chr(13),5)
anz=ubound(atmp)
'ggf. auf 5 Teile erhöhen
redim preserve atmp(4)
for l=anz+1 to 4
atmp(l)=""
next
adressen(i)=array(atmp)
end if
Code: Alles auswählen
Thiscomponent.Sheets(0).getcellrangebyposition(0,0,0,n).setDataArray(adressen)
Code: Alles auswählen
Thiscomponent.Sheets(0).getcellrangebyposition(0,0,4,n).setDataArray(adressen)
Gruß,
mikele
mikele
An alle, die das LibreOffice-Forum gern nutzen und unterstützen wollen:
Bitte helfen Sie uns mit 7 Euro pro Monat.
Durch Ihren Beitrag tragen Sie dazu bei, unsere laufenden Kosten für die kommenden Monate zu decken.
Unkompliziert per Kreditkarte oder PayPal.
Als ein kleines Dankeschön werden Sie im LO-Forum als SUPPORTER gekennzeichnet.