GELÖST Serienbrief nach Beispieldatenbank

Datenbanklösungen mit AOO/LO

Moderator: Moderatoren

WSO
*****
Beiträge: 233
Registriert: Di, 22.04.2014 13:03

GELÖST Serienbrief nach Beispieldatenbank

Beitrag von WSO »

Hallo (Robert?),
ich versuche ein Beispiel der Sedrienbriefdatenbank zu adaptieren und beisse mir die Zaehne an der Tabulatorsteuerung aus.
Ich vermute die Replaceanweisungen in Original dienen nicht nur der Formatierung, sondern haben auch etwas mit der Tabulatorsteuerung zu tun, ...?
Hier die wesentliche Stelle des adaptierten Beispiels:

Code: Alles auswählen

	oVerbindung = oDatenquelle.ActiveConnection()
	oSQL_Anweisung = oVerbindung.createStatement()
	
	stSql = "SELECT ""RecID"" || CHAR( 13 ) || ""gel_rec_yyyymm"" || CHAR( 7 ) || ""lei_text"" || CHAR( 30 ) ||"
	stSql = stSql + "  REPLACE( ""OffenMitFaktor"" || ' €', '.', ',' ) || CHAR( 9 )"
	stSql = stSql + " FROM ""abfRecSaldoMitAuftragKleinerNullSQL"""
	stSQl = stSql + "  WHERE ""RecKudID"" = "+Kunde_ID+""	
	
'   Original:
'	stSql = "SELECT ""Verkauf"".""Anzahl"" || CHAR( 9 ) || ""Waren"".""Ware"""
'	stSql = stSql + " || CHAR( 9 ) || REPLACE( ""Waren"".""Preis"" || ' €', '.', ',' ) || CHAR( 9 ) || "
'	stSql = stSql + " REPLACE( ""Verkauf"".""Anzahl"" * ""Preis"" || ' €', '.', ',' ) ||CHAR( 10 ) FROM "
'	stSql = stSql + """Verkauf"", ""Waren"" WHERE ""Verkauf"".""Waren_ID"" = ""Waren"".""ID"" AND ""Verkauf"".""Rechnung_ID"" = "+Kunde_ID+""
	
	oAbfrageergebnis = oSQL_Anweisung.executeQuery(stSql)' Ergebnis auswerten
	WHILE oAbfrageergebnis.next
		stText = stText + oAbfrageergebnis.getString(1)
		msgbox(stText)
	WEND ' nächster Datensatz
	stSql = "DELETE FROM ""tMahnungsinhalt"" WHERE ""mah_id"" = "+Kunde_ID+""	
	oSQL_Anweisung.executeUpdate(stSql)
	stSql = "INSERT INTO ""tMahnungsinhalt"" (""mah_id"",""mah_inhalt"") VALUES ("+Kunde_ID+", '"+stText+"')"
	oSQL_Anweisung.executeUpdate(stSql)
Das Ergebnis sieht dann leider so aus:

Code: Alles auswählen

	
Beleg	Zeitraum	Leistung	Preis		
33 2014-05Wartung37,45 €	
Die veranderte odt ist im Angang.
Was mache ich da falsch?
Gruss,
WSO
Dateianhänge
Beispiel_Rechnung.odt
(21.63 KiB) 99-mal heruntergeladen
Zuletzt geändert von WSO am Mo, 14.07.2014 23:30, insgesamt 1-mal geändert.
RobertG
********
Beiträge: 2067
Registriert: Fr, 13.04.2012 19:28
Kontaktdaten:

Re: Serienbrief nach Beispieldatenbank

Beitrag von RobertG »

Hallo WSO,

in der Originalabfrage steht mehrmals CHAR(9) drin. Das ist das zeichen, das einen tabulatorsprung im Textdokument erzeugt. Dann schließt die Zeile ab mit CHAR(10). Das ist ein Zeilenumbruch (nicht ein Absatzumbruch). Damit beginnt die nächste Zeile. Die Zeile, in der bei Dir mah_inhalt steht, muss entsprechend so mit Tabulatoren vordefiniert sein, dass die Spalten passen.

Du erzeugst in Deiner Abfrage hingegen zum Zeilenende einen Tabulator.

Zu den Steuerzeichen siehe auch hier: http://de.wikipedia.org/wiki/Steuerzeichen bzw. im Anhang des aktuellen Base-Handbuches S. 358.

Gruß

Robert
WSO
*****
Beiträge: 233
Registriert: Di, 22.04.2014 13:03

Re: Serienbrief nach Beispieldatenbank

Beitrag von WSO »

Hallo Robert,
Danke für den Hinweis, ich hatte mich schon "totgesucht".
Hatte hinter "CHAR" eine String-Selektion wie bei MySQL vermutet ....
Dann ist alles klar. :D
Mein Mailling Modul tut inzwischen recht gut.
Die Serienbriefe werden mit MailMerge generiert und als pdf gespeichert.
Das Mailling dann per "com.sun.star.system.SimpleCommandMail" mit Steuetung der Inhalte über Formularfelder.
Der Mailclient ist Thunderbird.
Gruss,
Wolfram
RobertG
********
Beiträge: 2067
Registriert: Fr, 13.04.2012 19:28
Kontaktdaten:

Re: Serienbrief nach Beispieldatenbank

Beitrag von RobertG »

Hallo Wolfram,

nur kurz zum Mailingmodul:
Vielleicht ein paar Zeilen Code? Du generierst das Ganze als als Datei. Soweit klar. Was gibst Du jetzt entsprechend weiter an Thunderbird?

Gruß

Robert
WSO
*****
Beiträge: 233
Registriert: Di, 22.04.2014 13:03

Re: Serienbrief nach Beispieldatenbank

Beitrag von WSO »

Hallo Robert,
bin zurück aus dem Urlaub und sehe deine Frage erst jetzt:

Hier der Code zum Mailling-Modul:
Thunderbird ist als Standard-Mail-Client registriert.

Code: Alles auswählen

Function MahnungErstellen  (Kunde AS LONG, Kundenname AS STRING, Vorlage AS STRING)
	REM Dieses Makro wird aus dem Formular einer Datenbank heraus gestartet.	
	
	DIM oForm AS OBJECT
	DIM oDoc AS OBJECT
	DIM oFeld AS OBJECT
	DIM oDB AS OBJECT
	DIM stDir AS STRING
	DIM loFeldID AS LONG
	DIM loID AS LONG	' Der Datenbankwertebereich für "Integer" entspricht dem StarBasic-Wertebereich für "Long"
	DIM arProps()
	DIM stURL AS STRING
	
	DIM stName AS STRING
	DIM stNow as STRING
	DIM KundenID AS STRING
	
	KundenID = Kunde	
	stNow = getTimestampString	
	stName=KundenID + "_M_" + stNow	
    loID = Kunde    	' loID enthält jetzt den aktuellen Primärschlüsselwert
    
    Call Mahnungsinhalt_zusammenstellen(Kunde)	
    
	MailMerge = createunoservice("com.sun.star.text.MailMerge")	
	
	oDB = ThisComponent.Parent	' Der Zugriff auf die URL ist nicht vom Formular aus direkt möglich. Es muss auf den darüberliegenden Frame der Datenbank Bezug genommen werden.
	stDir = Left(oDB.Location,Len(oDB.Location)-Len(oDB.Title))	' Der Titel der Datenbank wird von der URL abgetrennt.

	WITH MailMerge
		.DataSourceName = glbDatenbankname	' Die Datenbank muss eingebunden sein.		
'		.DocumentURL = stDir + "Serienbriefe/Vorlage_Mahnung.odt"
		stURL = convertToUrl(Vorlage) 'Auswahl durch Benutzer im Formular
		.DocumentURL = stURL		
		.SaveAsSingleFile = 1	' 0 = nein, 1 = ja
		.CommandType = 1	' 0 = Tabelle, 1 = Abfrage, 2 = SQL-Code
		.Command = "abfMahnung_einzeilig"	' abhängig von dem Typen entweder die Bezeichnung der Tabelle der Abfrage oder der komplette SQL-Code
		.Filter = "mah_id ="+Kunde	' Der Primärschlüssel wird an den Serienbrief übergeben
		.SaveAsSingleFile = true	' Einzeldokument soll erstellt werden, nicht mehrere Briefe in einem Dokument
		.FileNameFromColumn = false	' Hier wird angegeben, dass der Bezeichner für den Brief aus einem Tabellenfeld erstellt werden soll
		.FileNamePrefix = stName 
		.OutputType = 2 ' Printer = 1, File = 2, Mail = 3
		.OutputUrl = stDir + glbMahnungen	' Hier könnte der Pfad im Verhältnis zur Datenbank festgelegt werden		
    	.SaveFilter = "writer_pdf_Export"
    END WITH    
    MailMerge.execute(arProps())
    MahnungErstellen = stDir + glbMahnungen + stName + "0" + ".pdf"       ' MailMerge haengt eine Null an den Deteinamen an !!!
END FUNCTION


SUB Mahnungsinhalt_zusammenstellen(Kunde_ID AS LONG)
	' Die HSQLDB bietet keine Funktion wie GroupConcat (MySQL) oder List (Firebird). 
    ' Inhalte von gleichen Feldern in unterschiedlichen Datensätzen können deshalb am besten mit einem Makro in einer Zeile zusammengeführt werden.
    
    DIM oDatenquelle AS OBJECT
    DIM oVerbindung AS OBJECT
    DIM oSQL_Anweisung AS OBJECT
    DIM oAbfrageergebnis AS OBJECT
    DIM stSql AS STRING
	DIM stText AS STRING
	stText = ""	
	oDatenquelle = ThisComponent.Parent.CurrentController
	If NOT (oDatenquelle.isConnected()) THEN
		oDatenquelle.connect()
	END IF
	oVerbindung = oDatenquelle.ActiveConnection()
	oSQL_Anweisung = oVerbindung.createStatement()
	
	' CHAR(9)=Tabulatorsprung, CHAR(10)=Zeilenumbruch 
	stSql = "SELECT ""RecID"" || CHAR( 9 ) || ""gel_rec_druckdatum"" || CHAR( 9 ) || ""lei_text"" || CHAR( 9 ) ||"
	stSql = stSql + "  REPLACE( ""OffenMitFaktor"" || ' €', '.', ',' ) || CHAR( 10 )"
	stSql = stSql + " FROM ""abfRecSaldoMitAuftragKleinerNullSQL"""
	stSQl = stSql + "  WHERE ""RecKudID"" = "+Kunde_ID+""
	
	oAbfrageergebnis = oSQL_Anweisung.executeQuery(stSql)' Ergebnis auswerten
	WHILE oAbfrageergebnis.next
		stText = stText + oAbfrageergebnis.getString(1)
	WEND ' nächster Datensatz
	stSql = "DELETE FROM ""tMahnungsinhalt"" WHERE ""mah_id"" = "+Kunde_ID+""	
	oSQL_Anweisung.executeUpdate(stSql)
	stSql = "INSERT INTO ""tMahnungsinhalt"" (""mah_id"",""mah_inhalt"") VALUES ("+Kunde_ID+", '"+stText+"')"
	oSQL_Anweisung.executeUpdate(stSql)
	
END SUB

Gruss,
Wolfram
Antworten