Makro: PDF export - Dateiname aus Listenfeld

Hallo Community,

ich soll diverse Protokolle für meine Kollegen zur Abnahme unserer Maschinen erstellen.
Das hat auch wunderbar geklappt und die generierten PDFs werden sauber ausgefüllt.

Leider klappt es bei zwei Dingen noch nicht so gut:

  1. Abspeichern im einheitlichen Namensformat
  2. Aktualisieren aller generierten PDFs bei Änderungen im Protokoll.

Leider bin ich in der Makroprogrammierung absoluter Beginner.
Ich würde gerne per Makro (für das aktuelle Dokument oder vllt sogar für alle Dokumente in dem Ordner)
den PDF Export anstoßen.
Ist das Listenfeld “device” vorhanden, soll für alle Listeneinträge ein separates PDF erstellt werden.
Ist das Listenfeld nicht vorhanden, soll “nur” ein PDF erstellt werden.
Dateiname soll mit dem Namen des Writerdokuments beginnen.

Für den Start:
Wie bekomme ich das aktuelle Dokument als Referenz im Makro?
Wie bekomme ich eine Liste aller Steuerelemente?
Wie kann ich auf die möglichen Listeneinträge zugreifen?

Die drei Codeschnipsel würden mir schon mega weiterhelfen.
Der Rest sollte dann schon irgendwie klappen :slight_smile:

Leider hab ich kein Beispiel bisher gefunden, dass ich wirklich durchstiegen hätte :cry:

Gruß
Houns

oDoc = ThisComponent - das aktuelle Dokument. Das kannst Du nur bei geöffnetem Writer-Dokument ausführen. Wenn Du das im Makroeditor machst, dann erwischt Du das Makrofenster.
oDoc.Location - der Pfad zu dem entsprechenden Dokument zusammen mit der Bezeichnung des Dokumentes.
stDir = Left(oDoc.Location,Len(oDoc.Location)-Len(oDoc.Title)) - Der Pfad ohne die Bezeichnung des Dokumentes. Wenn Du da nicht trennst, dann hast Du nachher ein pdf-Dokument, in dem der Name des *.odt-Dokumentes mit Endung enthalten ist.

Was Du mit “Steuerelemente” an dieser Stelle meinst ist mir unklar.

PDF-Druck habe ich im Handbuch für Base beschrieben - passt natürlich bloß teilweise hier, weil Du das Ganze direkt mit Writer-Dateien machen willst.

@RobertG ,

Was Du mit “Steuerelemente” an dieser Stelle meinst ist mir unklar.

Eventuell das hier: Formular-Steuerelemente einfügen

1 Like

Ich habe @Houns so verstanden:
Er möchte PDF-Formulare erzeugen, dabei einen einheitlichen Namen vergeben.
Ein besonderer Fall ist, das er in einem seiner .odt Dateien ein Listenfeld mit dem Namen “device” hat, mit dem er die zu behandelnde Maschine auswählen kann. Nun möchte er aber für jeden Listeneintrag ein separates .PDF Formular erzeugen, das auch entsprechend benannt ist. Dazu möchte er die Listeneinträge verwenden. D.h. nach meiner Einschätzung benötigt er das Listenfeld in dem exportierten .PDF nicht mehr.
Ich habe nun folgenden Lösungsansatz vorzuschlagen: Das Listenfeld wird grundsätzlich auf “Druckbar = nein” umgestellt. Dann erscheint es im PDF Export nicht. Ein zusätzliches Textfeld z.B. “Textfeld_Maschine” wird beim Durchlaufen der Listenfeldeinträge mit dem Text der aktuellen Zeile des Listenfeldes gefüllt. Dann wird das .PDF exportiert
Meine Makros sehen dazu so aus:

Sub Export_PDF_Listbox_Entries
     oDoc = ThisComponent
     sDir = Left(oDoc.Location,Len(oDoc.Location)-Len(oDoc.Title))
     sTitle = replace(oDoc.Title,".odt","")
     oForm = ThisComponent.Drawpage.Forms.getbyName("Formular")
     oListenfeld_Maschinen = oForm.getByName("device")
     oTextfeld_Maschine = oForm.getByName("Textfeld_Maschine")
     aStringItemList = oListenfeld_Maschinen.StringItemList
     for i = 0 to ubound(aStringItemList) 'Listeneinträge in einem ungebundenen Listenfeld
         sMachineName = aStringItemList(i)
         oTextfeld_Maschine.Text = sMachineName
         url_pdf = sDir & sTitle & "_" & sMachineName & ".pdf" 'Dateipfad zusammenbauen
         Export_pdf(oDoc,url_pdf)
     next i
    msgbox ("erledigt",64,"PDF Formulare exportieren")     
End Sub

sub Export_pdf (document,url_pdf)
    Dim myProps(0) as New com.sun.star.beans.PropertyValue
    myProps(0).Name="FilterName"
    myProps(0).Value = "writer_pdf_Export"
    document.storetoUrl(url_pdf,myProps()) 'Speichern
end sub

Der Name des Formulares “Formular” muss naürlich passen.
Hier noch mein Beispieldokument, das fünf PDF Formulare in den Ordner, in dem das Writer Dokument liegt, speichert.
PDF_FORMULARE_EXPORTIEREN.odt (12.7 KB)

1 Like

Was Du höchstwahrscheinlich möchtest ist ein Serienbrief mit PDF-Ausgabe. Funktioniert ganz ohne Makros.

Hallo zusammen,

entschuldigt bitte die späte Antwort, aber sind letzte und diese Woche auf Messe und da war alles ein wenig durcheinander :wink:

“F3KTotal” hat es ganz richtig verstanden.
Vielen Dank für deinen Vorschlag!

Meine momentane Lösung sieht so aus und funktioniert auch:

REM  *****  BASIC  *****

Sub ExportProtAsPDF

	Dim oDoc as Object
	
	'Object: document
	'Attention: Returned object depends on execution environment
	'In this case it only works when it is called/started within a writer document!
	oDoc = ThisComponent
	
	'Path
	'Attention: Attribute 'Location' is URL encoded. 'Title' is not.
	'Replace URL specific characters before string operations.
	stDir = Replace(oDoc.Location, "%20", " ")
	stDir = Replace(stDir,oDoc.Title, "")
	'msgbox(stDir)
	
	stDocname = Replace(oDoc.Title, ".fodt", "")
	stDocname = Replace(stDocname, ".odt", "")
	'msgbox(stDocname)
	
	'Forms
	Dim oDp As Object  : oDp = oDoc.DrawPage	 				'Contains controls (of form)
	Dim cControl As Object										'Control object itself
	Dim bDevices As Boolean : bDevices = 0						'Tag controls whether PDFs with extensions or with title will be exported
	Dim storeArgs(0) As New com.sun.star.beans.PropertyValue	'Arguments for PDF export
	Dim stPdf As String											'File path and name for export
	
	'Iterate of all controls
	For i=0 To oDp.Count - 1
		cControl = oDp.getByIndex(i)
		
		'search for control that contains possible suffixes
		'[req]device is listbox
		if cControl.Name = "[req]device" Then
			bDevices = 1
			
			'Get suffix from available listbox items
			For j=0 To cControl.Control.ItemCount - 1
				stSuffix = cControl.Control.StringItemList(j)
				'msgbox(stSuffix)
				
				'String "--" is the default value -> no suffix
				If stSuffix = "--" Then
					'Nothing to do	
					
				Else
					stPdf = stDir + stDocname + "_" + stSuffix + ".pdf"
					storeArgs(0).Name  = "FilterName"
					storeArgs(0).Value = "writer_pdf_Export"
					oDoc.storeToURL(stPdf, storeArgs())
				
					msgbox("Exported: " + stPdf)
				End if
				
			Next
		End if
	Next
	
	'Export PDF with document name, if no device list is provided
	If bDevices = 0 Then
		stPdf = stDir + stDocname + ".pdf"
		storeArgs(0).Name  = "FilterName"
		storeArgs(0).Value = "writer_pdf_Export"
		oDoc.storeToURL(stPdf, storeArgs())
		
		'msgbox("Exported: " + stPdf)
	End if

	'Nothing more to do.
	msgbox("PDF Export finished.")
End Sub

Eine Frage hätte ich noch:
Gibt es eine Möglichkeit diesen Export für mehrere ODT Dokumente aus einer “Template” Datei zu starten?

-Template.odt
|— Prot1.odt (für device “test1”, “test2”)
|— Prot2.odt (für device “probe1”, “probe2”)

=> Ergebnis:
Prot1_test1.pdf
Prot1_test2.pdf
Prot2_probe1.pdf
Prot2_probe2.pdf

Wie gesagt aus dem ODT direkt funktioniert es.
i-Tüpfelchen wäre jetzt noch, wenn meine Kollegen nicht alle einzelnen ODTs durchgehen müssten, wenn die PDFs erstellt werden sollen…

Hallo Houns,
das ist ein sehr ähnliches Problem, wie ich es auch habe. Ich habe einen Serienbrief und möchte das ODT mit dem aktuellen Datensatz als PDF speichern. Ich habe über die Makro-Aufzeichnen-Funktion die Funktion “Direkt als PDF exportieren” weggeschrieben. Das sieht dann so aus:

sub ExportPDF
rem ----------------------------------------------------------------------
rem define variables
dim document as object
dim dispatcher as object
rem ----------------------------------------------------------------------
rem get access to the document
document = ThisComponent.CurrentController.Frame
dispatcher = createUnoService(“com.sun.star.frame.DispatchHelper”)

rem ----------------------------------------------------------------------
dim args1(1) as new com.sun.star.beans.PropertyValue
args1(0).Name = “URL”
args1(0).Value = “file://dateiname.pdf”
args1(1).Name = “FilterName”
args1(1).Value = “writer_pdf_Export”

dispatcher.executeDispatch(document, “.uno:ExportDirectToPDF”, “”, 0, args1())
end sub

Das Problem hierbei ist, dass in diesem Fall immer ein Standardname (nämlich der Name der ODT-Datei) für die PDF genommen wird. Wie schaffe ich es, hier den Dateinamen dynamisch zu setzen auf Basis des Wert aus einer Spalte der zugrundeliegenden Datenbank (das Feld heißt “filename”). Hast Du da eine Idee? Ich bin mit mit LO-Makros der totale Anfänger :frowning:

Danke und Gruß,
Stefan