❤️ 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!🍀

❤️ DANKE >> << DANKE ❤️

>> 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

WRITER hat alles, was Sie von einer modernen, voll ausgestatteten Textverarbeitung erwarten.
peon
Beiträge: 8
Registriert: Mo 28. Feb 2022, 22:43

Bestimmte Daten aus sehr vielen ODT-Dateien auslesen

Beitrag von peon » Mo 28. Feb 2022, 23:04

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!

schwimmakademie
Beiträge: 3
Registriert: Mo 28. Feb 2022, 09:14

Re: Bestimmte Daten aus sehr vielen ODT-Dateien auslesen

Beitrag von schwimmakademie » Di 1. Mär 2022, 08:34

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

mikele
* LO-Experte *
Beiträge: 1932
Registriert: Mo 1. Aug 2011, 20:51

Re: Bestimmte Daten aus sehr vielen ODT-Dateien auslesen

Beitrag von mikele » Di 1. Mär 2022, 10:50

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.
Gruß,
mikele

peon
Beiträge: 8
Registriert: Mo 28. Feb 2022, 22:43

Re: Bestimmte Daten aus sehr vielen ODT-Dateien auslesen

Beitrag von peon » Di 1. Mär 2022, 15:55

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:

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">
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?

peon
Beiträge: 8
Registriert: Mo 28. Feb 2022, 22:43

Re: Bestimmte Daten aus sehr vielen ODT-Dateien auslesen

Beitrag von peon » Di 1. Mär 2022, 16:00

Hier nochmal das konkrete XML der "neueren" Dateien:

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>
Und der "älteren" Dateien:

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>
Ob die Zahlen "P41", "T41" etc. über viele Dateien konsistent sind, muss ich noch näher anschauen.

mikele
* LO-Experte *
Beiträge: 1932
Registriert: Mo 1. Aug 2011, 20:51

Re: Bestimmte Daten aus sehr vielen ODT-Dateien auslesen

Beitrag von mikele » Di 1. Mär 2022, 17:19

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.
Gruß,
mikele

peon
Beiträge: 8
Registriert: Mo 28. Feb 2022, 22:43

Re: Bestimmte Daten aus sehr vielen ODT-Dateien auslesen

Beitrag von peon » Di 1. Mär 2022, 17:45

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)

mikele
* LO-Experte *
Beiträge: 1932
Registriert: Mo 1. Aug 2011, 20:51

Re: Bestimmte Daten aus sehr vielen ODT-Dateien auslesen

Beitrag von mikele » Di 1. Mär 2022, 20:33

Hallo,
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
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.
Dateianhänge
makro odt auslesen.ods
(9.31 KiB) 204-mal heruntergeladen
Gruß,
mikele

peon
Beiträge: 8
Registriert: Mo 28. Feb 2022, 22:43

Re: Bestimmte Daten aus sehr vielen ODT-Dateien auslesen

Beitrag von peon » Di 1. Mär 2022, 22:19

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?

mikele
* LO-Experte *
Beiträge: 1932
Registriert: Mo 1. Aug 2011, 20:51

Re: Bestimmte Daten aus sehr vielen ODT-Dateien auslesen

Beitrag von mikele » Mi 2. Mär 2022, 08:55

Hallo,
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
in

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
und am Ende

Code: Alles auswählen

Thiscomponent.Sheets(0).getcellrangebyposition(0,0,0,n).setDataArray(adressen)
in

Code: Alles auswählen

Thiscomponent.Sheets(0).getcellrangebyposition(0,0,4,n).setDataArray(adressen)
Gruß,
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.



Antworten