OBS/Makros und Scripting/Anwendungsbereiche/Drucke: Unterschied zwischen den Versionen
Nimz (Diskussion | Beiträge) (Die Seite wurde neu angelegt: „{{Makros und Scripting}} Drucke sind eine spezielle Form der Makros im OBS, da sie zusätzlich über Funktionalitäten für den Export in bestimmte Dateiformat…“) |
|||
(20 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
{{Makros und Scripting}} | {{Makros und Scripting}} | ||
Drucke sind eine spezielle Form der Makros im OBS, da sie zusätzlich über Funktionalitäten für den Export in bestimmte Dateiformate (z. B. PDF) oder Ausdruck verfügen. Sie sind an der Endung '''.pax''' zu erkennen und befinden sich in der Verzeichnisstruktur vom OBS unter ''..\data\druck'' und ''..\data\druck\user''. Der Unterschied zwischen den beiden Verzeichnissen ist klein, aber mit großer Wirkung. Alle Druck-Dateien, die standardmäßig im OBS enthalten sind, befinden sich im Verzeichnis ''..\data\druck'' und werden dort auch bei jedem Update ersetzt. Wer vom Standard abweichen möchte, muss die "pax"-Datei im Verzeichnis ''..\data\druck\user'' hinterlegen. | Drucke sind eine spezielle Form der Makros im OBS, da sie zusätzlich über Funktionalitäten für den Export in bestimmte Dateiformate (z. B. PDF) oder Ausdruck verfügen. Sie sind an der Endung '''.pax''' zu erkennen und befinden sich in der Verzeichnisstruktur vom OBS unter ''..\data\druck'' und ''..\data\druck\user''. Der Unterschied zwischen den beiden Verzeichnissen ist klein, aber mit großer Wirkung. Alle Druck-Dateien, die standardmäßig im OBS enthalten sind, befinden sich im Verzeichnis ''..\data\druck'' und werden dort auch bei jedem Update ersetzt. Wer vom Standard abweichen möchte, muss die "pax"-Datei im Verzeichnis ''..\data\druck\user'' hinterlegen. | ||
=Besonderheiten= | =Besonderheiten= | ||
== | |||
== | ==Vorgangsdrucke mit Methoden-Zeigern (Method Pointer)== | ||
== | |||
= | ''Falscher (alter) Weg: Den Druck in den user-Ordner kopieren und in der Datei die entsprechenden Änderungen einbauen. | ||
Warum: Wenn Änderungen an den Standarddrucken durchgeführt werden (z.B. neue gesetzliche Vorgaben) wird der user-Druck nicht mit angepasst.'' | |||
'''Richtiger Weg (ab Version 004097, 14.09.2022):''' | |||
user-Druck anlegen in folgendem Stil (Beispiel rechnung.pax): | |||
<span style="color: darkgreen">// Verlinkung des Standard-Drucks</span> | |||
{$I .\data\druck\rechnung.pax} | |||
//Briefkopfabfrage aktivieren | |||
{BriefkopfAbfrage} | |||
<span style="color: darkgreen">// Kopie der StartProc die dann die Standard-StartProc aufruft</span> | |||
function <span style="color: blue">StartProcCustom</span>(cRechNr: String; nParCnt: Integer; lPrintModusi: Boolean; obj: TObject): Boolean; | |||
begin | |||
result := StartProc(cRechNr, nParCnt, lPrintModusi, obj); | |||
end; | |||
Damit wird erstmal der Standard-Rechnungsdruck 1:1 ausgeführt. | |||
Jetzt kann ich über Custom-Methoden den Druck verändern. | |||
{{Hinweis|Damit in einem Custom-Methoden Druck die Abfrage nach dem Briefkopf kommt (Pmode:0539) muss folgender Teil enthalten sein : | |||
{BriefkopfAbfrage} | |||
}} | |||
===Beispiel 1: Nutzung eines vorhandenen Methoden-Zeigers=== | |||
Anforderung: Leerzeilen sollen immer zwei statt einer Zeile hoch sein. | |||
Dafür existiert bereits ein Methoden-Zeiger den ich nutzen kann: | |||
{$I .\data\druck\rechnung.pax} | |||
//Briefkopfabfrage aktivieren | |||
{BriefkopfAbfrage} | |||
<span style="color: darkgreen">// neue Custom-Methode</span> | |||
procedure LeerzeilePosCustom(); | |||
begin | |||
y := y + 2; | |||
end; | |||
function StartProcCustom(cRechNr: String; nParCnt: Integer; lPrintModusi: Boolean; obj: TObject): Boolean; | |||
begin | |||
<span style="color: darkgreen">// Grund-Initialisierung der Zeiger, '''MUSS''' als erstes ausgeführt werden weil die Zeiger sonst während des Drucks neu gesetzt werden</span> | |||
InitMethodPointers(true); | |||
<span style="color: darkgreen">// Zuweisung meiner Custom-Methode auf dem Methoden-Zeiger für den Leerzeilendruck</span> | |||
<span style="color: blue">oMethodPointer.pLeerzeile := LeerzeilePosCustom;</span> | |||
result := StartProc(cRechNr, nParCnt, lPrintModusi, obj); | |||
end; | |||
Beispiel eines angepassten Angebot-Drucks mit diversen Anpassungen: | |||
<source lang="delphi"> | |||
//------------------------------------------------------------------------------ | |||
// Unit Name: Angebot | |||
// History: 2023-09-13 - Umstellung auf Method Pointer | |||
//------------------------------------------------------------------------------ | |||
{$I .\data\druck\angebot.pax} | |||
{$I .\data\druck\user\user.inx } | |||
//------------------------------------------------------------------------------ | |||
// Procedure: CustomRabattSpalten | |||
// Author: Schinke | |||
// Date: 2023-09-13 | |||
// Comment: Zusätzliche Spalte für RabattEinzellpreis | |||
//------------------------------------------------------------------------------ | |||
procedure CustomRabattSpalten(); | |||
begin | |||
if (A_Query.A2C('a_rabposjn') = 'J') then begin | |||
qRep_SAddGruppe(EZ, 'aBody', 'Rabatt' , 6 , tajRightJustify, 'N'); | |||
qRep_SAddGruppe(EZ, 'aBody', 'RabattEPreis', 10, tajRightJustify, 'N'); | |||
end; | |||
end; | |||
//------------------------------------------------------------------------------ | |||
// Procedure: PosHeaderZusatz | |||
// Author: Schinke | |||
// Date: 2023-09-13 | |||
// Comment: Überschrift für Rabatt Einzelpreis Spalte | |||
//------------------------------------------------------------------------------ | |||
procedure PosHeaderZusatz(); | |||
begin | |||
qRep_SText(EZ, 'RabattEPreis' , 'Rab E-Preis', qRep_YPos(EZ, y)); | |||
end; | |||
//------------------------------------------------------------------------------ | |||
// Procedure: CustomPosRabatt | |||
// Author: Schinke | |||
// Date: 2023-09-13 | |||
// Comment: Wert für Rabatt Einzelpreis | |||
//------------------------------------------------------------------------------ | |||
procedure CustomPosRabatt(); | |||
begin | |||
if (Alltrim(TStr(Roundy(AZ_Query.A2F('az_rabatt'), 2), 12, 2)) <> '0,00') then begin | |||
if (AZ_Query.A2C('az_posart') < '6') then begin | |||
qRep_SText(EZ, 'rabatt' , TStr(Roundy(AZ_Query.A2F('az_rabatt'), 2), 12, 2) , qRep_YPos(EZ, y)); | |||
qRep_SText(EZ, 'rabattEPreis', TStr(Roundy(AZ_Query.A2F('az_epreis')/100*AZ_Query.A2F('az_rabatt'), 2), 12, 2), qRep_YPos(EZ,y)); | |||
end; | |||
end; | |||
end; | |||
//------------------------------------------------------------------------------ | |||
// Procedure: CustomAngebotKopfZusatzinfo | |||
// Author: Schinke | |||
// Date: 2023-09-13 | |||
// Comment: Ansprechpartner/Projekt im Kopf | |||
//------------------------------------------------------------------------------ | |||
procedure CustomAngebotKopfZusatzinfo(); | |||
begin | |||
UserAnsprechpartner(1); | |||
end; | |||
//------------------------------------------------------------------------------ | |||
// Procedure: CustomKopfFolgeSeite | |||
// Author: Schinke | |||
// Date: 2023-09-13 | |||
// Comment: Angepasster Folgeseiten Kopf ohne Adresse | |||
//------------------------------------------------------------------------------ | |||
procedure CustomKopfFolgeSeite(); | |||
begin | |||
y := 1; | |||
if (not empty(cLogo2)) then begin | |||
BriefbogenStd(cLogo2); | |||
end; | |||
//AdressKopf(KopffreieZeilen); | |||
y := KopffreieZeilen - 10; | |||
qRep_SText(EZ,'1', cKopf1,qRep_YPos(EZ, y+2)); | |||
qRep_SText(EZ,'2', cKopf8+A_Query.A2C('a_nr'),qRep_YPos(EZ, y+2)); | |||
qRep_SText(EZ,'3', cKopf9, qRep_YPos(EZ, y)); | |||
qRep_SText(EZ,'3', cKopf5, qRep_YPos(EZ, y+1)); | |||
qRep_SText(EZ,'3', cAllg8, qRep_YPos(EZ, y+2)); | |||
qRep_SText(EZ,'4', ': '+A_Query.A2C('a_datum') , qRep_YPos(EZ, y)); | |||
qRep_SText(EZ,'4', ': '+A_Query.A2C('a_knr') , qRep_YPos(EZ, y+1)); | |||
qRep_SText(EZ,'4', ': '+IntToStr(nEZ_CurPage) , qRep_YPos(EZ, y+2)); | |||
y := y + 3.5; | |||
end; | |||
//------------------------------------------------------------------------------ | |||
// Procedure: StartProcCustom | |||
// Author: Schinke | |||
// Date: 2023-09-13 | |||
//------------------------------------------------------------------------------ | |||
function StartProcCustom(cVar, cAngNr: String; nParCnt: Integer; lPrintModusi: Boolean; obj: TObject): Boolean; | |||
begin | |||
// Grund-Initialisierung der Zeiger, MUSS als erstes ausgeführt werden weil die Zeiger sonst während des Drucks neu gesetzt werden | |||
InitMethodPointers(true); | |||
InitPosGlobalPointers(); | |||
oMethodPointer.pRabattSpalten := CustomRabattSpalten; //Steuert die Spalten, wenn ein PosRbatt vorhanden ist. Standard: Eine Spalte | |||
oMethodPointer.pPosHeaderZusatz := PosHeaderZusatz; //Wird nach den Überschriften der PosSpalten ausgeführt | |||
oMethodPointer.pPosRabatt := CustomPosRabatt; //Ausgabe des Rabatts in der Posline | |||
oPrinterPrintPage.pBeforePrint := BriefbogenMehrseitig; //Ausgelagerte Funktion in User.inx um den Briefbogen zu drucken. | |||
oPrinterPrintPage.pAngebotKopfZusatzinfo := CustomAngebotKopfZusatzinfo; | |||
result := StartProc(cVar, cAngNr, nParCnt, lPrintModusi, obj); | |||
end; | |||
</source> | |||
Dazugehörige User.inx: | |||
<source lang="delphi"> | |||
//------------------------------------------------------------------ | |||
//Ausgabe Ansprechpartner/Projekt im Kopf | |||
//------------------------------------------------------------------ | |||
procedure UserAnsprechpartner(yKorrektur:Double); | |||
var cBuffer : String; | |||
begin | |||
//Sachbearbeiter Kunde (Ansprechpartner) | |||
cBuffer := DB_ReadSQLValue(oDB,'perssta','ps_verkauf','ps_nr=' + DB_SQLVal(A_Query.A2C('a_knr'),'C')); | |||
if not(empty(cBuffer)) then begin | |||
//Sachbearbeiter Kunde Name | |||
cBuffer := 'Ansprechpartner: ' + DB_ReadSQLValue(oDB,'S_VERK', 'v_name', 'v_nr=' + DB_SQLVal(cBuffer, 'C')); | |||
end; | |||
//Projekt | |||
if not(empty(A_Query.A2C('a_projnr'))) then begin | |||
if not(empty(cBuffer)) then begin | |||
cBuffer := cBuffer + ' / '; | |||
end; | |||
cBuffer := cBuffer + 'Projekt: '+ A_Query.A2C('a_projnr'); | |||
end; | |||
qRep_Text3(EZ, iLinkerRand, qRep_YPos(EZ, y-yKorrektur), cBuffer); | |||
y := y + 1; | |||
end; | |||
//------------------------------------------------------------------ | |||
//Briefbogen ab Seite 2 ohne Kopf | |||
//Es muss im User, der dies verwendet eine CustomKopfFolgeSeite() | |||
//Procedure vorhanden sein. | |||
//------------------------------------------------------------------ | |||
procedure BriefbogenMehrseitig(); | |||
begin | |||
oPrinterPrintPage.pKopfFolgeSeite := CustomKopfFolgeSeite; | |||
if nEZ_CurPage = 1 then begin | |||
qRep_PictPrint(EZ,GL_EXEPath+'data\druck\user\Briefbogen.png',-100,800,1150,-220); | |||
end else begin | |||
qRep_PictPrint(EZ,GL_EXEPath+'data\druck\user\briefbogen_FolgeSeite.png',-100,800,1150,-220); | |||
end; | |||
end; | |||
//------------------------------------------------------------------ | |||
//Briefbogen Folgeseiten | |||
//------------------------------------------------------------------ | |||
procedure Briefbogen(); | |||
begin | |||
qRep_PictPrint(EZ,GL_EXEPath+'data\druck\user\Briefbogen.png',-100,800,1150,-220); | |||
end; | |||
</source> | |||
===Beispiel 2: Einrichtung eines neuen Methoden-Zeigers=== | |||
{{Hinweis|Neue Methoden-Zeiger können nur duch den OBS-Support angelegt werden! Bitte wenden Sie sich im Bedarfsfall an den Support.}} | |||
Anforderung: Positionsmenge sollen im Druck nicht mit ausgegeben werden. Das ist kein sinnvolles Szenario und dient lediglich als Beispiel. | |||
Dafür gibt es noch keinen Methoden-Zeiger, wir brauchen einen Neuen. Wie gehe ich vor: | |||
'''1. Die Stelle im Code identifizieren die geändert werden soll''' | |||
In unserem Beispiel die Prozedur PosLineMengeEinheit() in PosReportFunktionen.inx | |||
[...] | |||
if ((not lEmpty) and (not lLiefNach) and (not lMultiSteuerPos)) then begin | |||
<span style="color: blue">qRep_SText(EZ,'menge' ,TStr(AZ_Query.A2F('az_menge'),12,StrToIntDef(PMode_Var(457),2)),qRep_YPos(EZ,y));</span> | |||
qRep_SText(EZ,'einheit',GetEinheit_Lan(oDB,cLanguage,AZ_Query.A2C('az_einheit'),'se_name'),qRep_YPos(EZ,y)); | |||
end else if (lLiefNach and lDruckNachgeliefert) then begin | |||
WirdNachgeliefert(); | |||
end; | |||
[...] | |||
'''2. Für die Ausgabe der Menge lege ich nun einen neuen Methoden-Zeiger an''' | |||
Datei: '''PosReportPositionen.inx''' | |||
TPosMethodPointer = record | |||
public | |||
pPosHeader : TPosMethod; | |||
[...] | |||
<span style="color: blue">pPosLineMenge : TPosMethod;</span> <span style="color: darkgreen">// <-- neuer Zeiger</span> | |||
end; | |||
'''3. Statt der Ausführung des Codes setzte ich nun den Methoden-Zeiger ein''' | |||
Datei: '''Ort der Druckänderung''' (im Beispiel PosReportFunktionen.inx) | |||
[...] | |||
if ((not lEmpty) and (not lLiefNach) and (not lMultiSteuerPos)) then begin | |||
<span style="color: blue">oMethodPointer.pPosLineMenge();</span> <span style="color: darkgreen">// <-- Methoden-Aufruf</span> | |||
qRep_SText(EZ,'einheit',GetEinheit_Lan(oDB,cLanguage,AZ_Query.A2C('az_einheit'),'se_name'),qRep_YPos(EZ,y)); | |||
end else if (lLiefNach and lDruckNachgeliefert) then begin | |||
WirdNachgeliefert(); | |||
end; | |||
[...] | |||
'''4. Für den Standard baue ich eine neue Prozedur''' | |||
Datei: '''Ort der Druckänderung''' (im Beispiel PosReportFunktionen.inx) | |||
procedure PosLineMengeDefault(); | |||
begin | |||
qRep_SText(EZ,'menge' ,TStr(AZ_Query.A2F('az_menge'),12,StrToIntDef(PMode_Var(457),2)),qRep_YPos(EZ,y)); | |||
end; | |||
'''5. Ich ergänze die Initialisierung der Methoden-Zeiger''' | |||
Datei: '''PosReportPositionen.inx''' | |||
procedure InitMethodPointers(lPrintPreise : Boolean = true); | |||
begin | |||
oMethodPointer.pPosHeader := PosHeader; | |||
[...] | |||
<span style="color: blue">oMethodPointer.pPosLineMenge := PosLineMengeDefault;</span> <span style="color: darkgreen">// <-- das hier ist die neue Zeile</span> | |||
InitPosParams(lPrintPreise); | |||
end; | |||
'''6. Jetzt kann ich in meinem user-Druck den Zeiger benutzen''' | |||
Datei '''User-Druck''' (im Beispiel user\rechnung.pax) | |||
procedure PosLineMengeCustom(); | |||
begin | |||
<span style="color: darkgreen">// keine Menge ausgeben</span> | |||
end; | |||
function StartProcCustom(cRechNr: String; nParCnt: Integer; lPrintModusi: Boolean; obj: TObject): Boolean; | |||
begin | |||
<span style="color: darkgreen">// Grund-Initialisierung der Zeiger, '''MUSS''' als erstes ausgeführt werden weil die Zeiger sonst während des Drucks neu gesetzt werden</span> | |||
InitMethodPointers(true); | |||
<span style="color: darkgreen">// Setzten der neue Methode</span> | |||
<span style="color: blue">oMethodPointer.pPosLineMenge := PosLineMengeCustom;</span> | |||
result := StartProc(cRechNr, nParCnt, lPrintModusi, obj); | |||
end; | |||
== Übersteuern von Textbausteinen == | |||
Mit der Variable cDBNamePDF im Druck können Textbausteine übersteuert werden. | |||
aktuell verwendet in: | |||
RUECKSENDEAUFTRAG.PAX | |||
ABHOLSCHEIN.PAX | |||
Benutzt in i_Uti.pas function PDFMail_Ext | |||
cDBName := 'AUFTRAG'; | |||
cDBNamePDF := 'ABHOLSCHEIN'; | |||
=== Script_Lib Funktion === | |||
Neue Script_Lib Funktion | |||
Name : PDFMail | |||
Methode : PDFParameter | |||
Parameter: | |||
Hier kann alles übersteuert werden (Mailtexte usw) | |||
Alle Änderungen gehen auch zurück | |||
oParameter ist vom Typ TOBSParameter (Script) | |||
oParameter.V13 ist der Mail Text | |||
<source lang="delphi"> | |||
Script_Lib_RunNamePara(oDB, | |||
'PDFMail_Ext', | |||
'PDFParameter', | |||
[ | |||
TObject(oParameter), | |||
cDB, | |||
cDB_PDF, | |||
cPsNr | |||
]); | |||
oParameter.Obj := oDB; | |||
oParameter.V1 := cVonEmailAdr; | |||
oParameter.V2 := cEmailAdr; | |||
oParameter.V3 := lSofortSenden; | |||
oParameter.V4 := cPDFFile; | |||
oParameter.V5 := lAnzeige; | |||
oParameter.V6 := cFileExt; | |||
oParameter.V7 := cAddAttach; | |||
oParameter.V8 := cCC; | |||
oParameter.V9 := cBCC; | |||
oParameter.V10 := lLeseBestaetigung; | |||
oParameter.V11 := cMyBetreff; | |||
oParameter.V12 := cMyMailText; | |||
oParameter.V13 := cBuffer; | |||
oParameter.V14 := cTB; | |||
</source> | |||
== Initialisierungen von Pointern vor der Start Proc == | |||
Vor der StartProcCustom wird zuerst die Funktion ''InitUserLib'', dann ''RunUserLib'' und erst danach ''StartProcCustom''. | |||
Wenn im User-Ordner eine UserLib.inx liegt, wird diese in der Standard.Inx IMMER mit eingebunden. | |||
Ein Beispiel, bei dem sicher gestellt wird, dass immer wenn in irgendeinem Druck als Papierforma ''Endlospapier'' gewählt wurde, bestimmte Ränder gesetzt werden: | |||
<source lang="delphi"> | |||
// ----------------------------------------------------------------------------- | |||
// Procedure: EndloMargins | |||
// ----------------------------------------------------------------------------- | |||
procedure EndloMargins(); | |||
begin | |||
if lower(cPapierformat) = 'Endlospapier' then begin | |||
ez.Units := MM; | |||
ez.Page.TopMargin := 35; | |||
ez.Page.BottomMargin := 65; | |||
ez.Units := Pixels; | |||
end; | |||
end; | |||
// ----------------------------------------------------------------------------- | |||
// Procedure: RunUserLib | |||
// ----------------------------------------------------------------------------- | |||
procedure RunUserLib(); | |||
begin | |||
oStandardPointer.pBeforeStartPrinter := EndloMargins; | |||
oStandardPointer.pBeforeStartPrinterStd := EndloMargins; | |||
end; | |||
// ----------------------------------------------------------------------------- | |||
</source> |
Aktuelle Version vom 16. Februar 2024, 10:43 Uhr
Drucke sind eine spezielle Form der Makros im OBS, da sie zusätzlich über Funktionalitäten für den Export in bestimmte Dateiformate (z. B. PDF) oder Ausdruck verfügen. Sie sind an der Endung .pax zu erkennen und befinden sich in der Verzeichnisstruktur vom OBS unter ..\data\druck und ..\data\druck\user. Der Unterschied zwischen den beiden Verzeichnissen ist klein, aber mit großer Wirkung. Alle Druck-Dateien, die standardmäßig im OBS enthalten sind, befinden sich im Verzeichnis ..\data\druck und werden dort auch bei jedem Update ersetzt. Wer vom Standard abweichen möchte, muss die "pax"-Datei im Verzeichnis ..\data\druck\user hinterlegen.
Besonderheiten
Vorgangsdrucke mit Methoden-Zeigern (Method Pointer)
Falscher (alter) Weg: Den Druck in den user-Ordner kopieren und in der Datei die entsprechenden Änderungen einbauen. Warum: Wenn Änderungen an den Standarddrucken durchgeführt werden (z.B. neue gesetzliche Vorgaben) wird der user-Druck nicht mit angepasst.
Richtiger Weg (ab Version 004097, 14.09.2022):
user-Druck anlegen in folgendem Stil (Beispiel rechnung.pax):
// Verlinkung des Standard-Drucks {$I .\data\druck\rechnung.pax} //Briefkopfabfrage aktivieren {BriefkopfAbfrage} // Kopie der StartProc die dann die Standard-StartProc aufruft function StartProcCustom(cRechNr: String; nParCnt: Integer; lPrintModusi: Boolean; obj: TObject): Boolean; begin result := StartProc(cRechNr, nParCnt, lPrintModusi, obj); end;
Damit wird erstmal der Standard-Rechnungsdruck 1:1 ausgeführt. Jetzt kann ich über Custom-Methoden den Druck verändern.
{BriefkopfAbfrage}
Beispiel 1: Nutzung eines vorhandenen Methoden-Zeigers
Anforderung: Leerzeilen sollen immer zwei statt einer Zeile hoch sein.
Dafür existiert bereits ein Methoden-Zeiger den ich nutzen kann:
{$I .\data\druck\rechnung.pax} //Briefkopfabfrage aktivieren {BriefkopfAbfrage}
// neue Custom-Methode procedure LeerzeilePosCustom(); begin y := y + 2; end; function StartProcCustom(cRechNr: String; nParCnt: Integer; lPrintModusi: Boolean; obj: TObject): Boolean; begin // Grund-Initialisierung der Zeiger, MUSS als erstes ausgeführt werden weil die Zeiger sonst während des Drucks neu gesetzt werden InitMethodPointers(true); // Zuweisung meiner Custom-Methode auf dem Methoden-Zeiger für den Leerzeilendruck oMethodPointer.pLeerzeile := LeerzeilePosCustom; result := StartProc(cRechNr, nParCnt, lPrintModusi, obj); end;
Beispiel eines angepassten Angebot-Drucks mit diversen Anpassungen:
//------------------------------------------------------------------------------
// Unit Name: Angebot
// History: 2023-09-13 - Umstellung auf Method Pointer
//------------------------------------------------------------------------------
{$I .\data\druck\angebot.pax}
{$I .\data\druck\user\user.inx }
//------------------------------------------------------------------------------
// Procedure: CustomRabattSpalten
// Author: Schinke
// Date: 2023-09-13
// Comment: Zusätzliche Spalte für RabattEinzellpreis
//------------------------------------------------------------------------------
procedure CustomRabattSpalten();
begin
if (A_Query.A2C('a_rabposjn') = 'J') then begin
qRep_SAddGruppe(EZ, 'aBody', 'Rabatt' , 6 , tajRightJustify, 'N');
qRep_SAddGruppe(EZ, 'aBody', 'RabattEPreis', 10, tajRightJustify, 'N');
end;
end;
//------------------------------------------------------------------------------
// Procedure: PosHeaderZusatz
// Author: Schinke
// Date: 2023-09-13
// Comment: Überschrift für Rabatt Einzelpreis Spalte
//------------------------------------------------------------------------------
procedure PosHeaderZusatz();
begin
qRep_SText(EZ, 'RabattEPreis' , 'Rab E-Preis', qRep_YPos(EZ, y));
end;
//------------------------------------------------------------------------------
// Procedure: CustomPosRabatt
// Author: Schinke
// Date: 2023-09-13
// Comment: Wert für Rabatt Einzelpreis
//------------------------------------------------------------------------------
procedure CustomPosRabatt();
begin
if (Alltrim(TStr(Roundy(AZ_Query.A2F('az_rabatt'), 2), 12, 2)) <> '0,00') then begin
if (AZ_Query.A2C('az_posart') < '6') then begin
qRep_SText(EZ, 'rabatt' , TStr(Roundy(AZ_Query.A2F('az_rabatt'), 2), 12, 2) , qRep_YPos(EZ, y));
qRep_SText(EZ, 'rabattEPreis', TStr(Roundy(AZ_Query.A2F('az_epreis')/100*AZ_Query.A2F('az_rabatt'), 2), 12, 2), qRep_YPos(EZ,y));
end;
end;
end;
//------------------------------------------------------------------------------
// Procedure: CustomAngebotKopfZusatzinfo
// Author: Schinke
// Date: 2023-09-13
// Comment: Ansprechpartner/Projekt im Kopf
//------------------------------------------------------------------------------
procedure CustomAngebotKopfZusatzinfo();
begin
UserAnsprechpartner(1);
end;
//------------------------------------------------------------------------------
// Procedure: CustomKopfFolgeSeite
// Author: Schinke
// Date: 2023-09-13
// Comment: Angepasster Folgeseiten Kopf ohne Adresse
//------------------------------------------------------------------------------
procedure CustomKopfFolgeSeite();
begin
y := 1;
if (not empty(cLogo2)) then begin
BriefbogenStd(cLogo2);
end;
//AdressKopf(KopffreieZeilen);
y := KopffreieZeilen - 10;
qRep_SText(EZ,'1', cKopf1,qRep_YPos(EZ, y+2));
qRep_SText(EZ,'2', cKopf8+A_Query.A2C('a_nr'),qRep_YPos(EZ, y+2));
qRep_SText(EZ,'3', cKopf9, qRep_YPos(EZ, y));
qRep_SText(EZ,'3', cKopf5, qRep_YPos(EZ, y+1));
qRep_SText(EZ,'3', cAllg8, qRep_YPos(EZ, y+2));
qRep_SText(EZ,'4', ': '+A_Query.A2C('a_datum') , qRep_YPos(EZ, y));
qRep_SText(EZ,'4', ': '+A_Query.A2C('a_knr') , qRep_YPos(EZ, y+1));
qRep_SText(EZ,'4', ': '+IntToStr(nEZ_CurPage) , qRep_YPos(EZ, y+2));
y := y + 3.5;
end;
//------------------------------------------------------------------------------
// Procedure: StartProcCustom
// Author: Schinke
// Date: 2023-09-13
//------------------------------------------------------------------------------
function StartProcCustom(cVar, cAngNr: String; nParCnt: Integer; lPrintModusi: Boolean; obj: TObject): Boolean;
begin
// Grund-Initialisierung der Zeiger, MUSS als erstes ausgeführt werden weil die Zeiger sonst während des Drucks neu gesetzt werden
InitMethodPointers(true);
InitPosGlobalPointers();
oMethodPointer.pRabattSpalten := CustomRabattSpalten; //Steuert die Spalten, wenn ein PosRbatt vorhanden ist. Standard: Eine Spalte
oMethodPointer.pPosHeaderZusatz := PosHeaderZusatz; //Wird nach den Überschriften der PosSpalten ausgeführt
oMethodPointer.pPosRabatt := CustomPosRabatt; //Ausgabe des Rabatts in der Posline
oPrinterPrintPage.pBeforePrint := BriefbogenMehrseitig; //Ausgelagerte Funktion in User.inx um den Briefbogen zu drucken.
oPrinterPrintPage.pAngebotKopfZusatzinfo := CustomAngebotKopfZusatzinfo;
result := StartProc(cVar, cAngNr, nParCnt, lPrintModusi, obj);
end;
Dazugehörige User.inx:
//------------------------------------------------------------------
//Ausgabe Ansprechpartner/Projekt im Kopf
//------------------------------------------------------------------
procedure UserAnsprechpartner(yKorrektur:Double);
var cBuffer : String;
begin
//Sachbearbeiter Kunde (Ansprechpartner)
cBuffer := DB_ReadSQLValue(oDB,'perssta','ps_verkauf','ps_nr=' + DB_SQLVal(A_Query.A2C('a_knr'),'C'));
if not(empty(cBuffer)) then begin
//Sachbearbeiter Kunde Name
cBuffer := 'Ansprechpartner: ' + DB_ReadSQLValue(oDB,'S_VERK', 'v_name', 'v_nr=' + DB_SQLVal(cBuffer, 'C'));
end;
//Projekt
if not(empty(A_Query.A2C('a_projnr'))) then begin
if not(empty(cBuffer)) then begin
cBuffer := cBuffer + ' / ';
end;
cBuffer := cBuffer + 'Projekt: '+ A_Query.A2C('a_projnr');
end;
qRep_Text3(EZ, iLinkerRand, qRep_YPos(EZ, y-yKorrektur), cBuffer);
y := y + 1;
end;
//------------------------------------------------------------------
//Briefbogen ab Seite 2 ohne Kopf
//Es muss im User, der dies verwendet eine CustomKopfFolgeSeite()
//Procedure vorhanden sein.
//------------------------------------------------------------------
procedure BriefbogenMehrseitig();
begin
oPrinterPrintPage.pKopfFolgeSeite := CustomKopfFolgeSeite;
if nEZ_CurPage = 1 then begin
qRep_PictPrint(EZ,GL_EXEPath+'data\druck\user\Briefbogen.png',-100,800,1150,-220);
end else begin
qRep_PictPrint(EZ,GL_EXEPath+'data\druck\user\briefbogen_FolgeSeite.png',-100,800,1150,-220);
end;
end;
//------------------------------------------------------------------
//Briefbogen Folgeseiten
//------------------------------------------------------------------
procedure Briefbogen();
begin
qRep_PictPrint(EZ,GL_EXEPath+'data\druck\user\Briefbogen.png',-100,800,1150,-220);
end;
Beispiel 2: Einrichtung eines neuen Methoden-Zeigers
Anforderung: Positionsmenge sollen im Druck nicht mit ausgegeben werden. Das ist kein sinnvolles Szenario und dient lediglich als Beispiel.
Dafür gibt es noch keinen Methoden-Zeiger, wir brauchen einen Neuen. Wie gehe ich vor:
1. Die Stelle im Code identifizieren die geändert werden soll
In unserem Beispiel die Prozedur PosLineMengeEinheit() in PosReportFunktionen.inx
[...]
if ((not lEmpty) and (not lLiefNach) and (not lMultiSteuerPos)) then begin
qRep_SText(EZ,'menge' ,TStr(AZ_Query.A2F('az_menge'),12,StrToIntDef(PMode_Var(457),2)),qRep_YPos(EZ,y));
qRep_SText(EZ,'einheit',GetEinheit_Lan(oDB,cLanguage,AZ_Query.A2C('az_einheit'),'se_name'),qRep_YPos(EZ,y));
end else if (lLiefNach and lDruckNachgeliefert) then begin
WirdNachgeliefert();
end;
[...]
2. Für die Ausgabe der Menge lege ich nun einen neuen Methoden-Zeiger an
Datei: PosReportPositionen.inx
TPosMethodPointer = record public pPosHeader : TPosMethod; [...] pPosLineMenge : TPosMethod; // <-- neuer Zeiger end;
3. Statt der Ausführung des Codes setzte ich nun den Methoden-Zeiger ein
Datei: Ort der Druckänderung (im Beispiel PosReportFunktionen.inx)
[...] if ((not lEmpty) and (not lLiefNach) and (not lMultiSteuerPos)) then begin oMethodPointer.pPosLineMenge(); // <-- Methoden-Aufruf qRep_SText(EZ,'einheit',GetEinheit_Lan(oDB,cLanguage,AZ_Query.A2C('az_einheit'),'se_name'),qRep_YPos(EZ,y)); end else if (lLiefNach and lDruckNachgeliefert) then begin WirdNachgeliefert(); end; [...]
4. Für den Standard baue ich eine neue Prozedur
Datei: Ort der Druckänderung (im Beispiel PosReportFunktionen.inx)
procedure PosLineMengeDefault(); begin qRep_SText(EZ,'menge' ,TStr(AZ_Query.A2F('az_menge'),12,StrToIntDef(PMode_Var(457),2)),qRep_YPos(EZ,y)); end;
5. Ich ergänze die Initialisierung der Methoden-Zeiger
Datei: PosReportPositionen.inx
procedure InitMethodPointers(lPrintPreise : Boolean = true); begin oMethodPointer.pPosHeader := PosHeader; [...] oMethodPointer.pPosLineMenge := PosLineMengeDefault; // <-- das hier ist die neue Zeile InitPosParams(lPrintPreise); end;
6. Jetzt kann ich in meinem user-Druck den Zeiger benutzen
Datei User-Druck (im Beispiel user\rechnung.pax)
procedure PosLineMengeCustom(); begin // keine Menge ausgeben end; function StartProcCustom(cRechNr: String; nParCnt: Integer; lPrintModusi: Boolean; obj: TObject): Boolean; begin // Grund-Initialisierung der Zeiger, MUSS als erstes ausgeführt werden weil die Zeiger sonst während des Drucks neu gesetzt werden InitMethodPointers(true); // Setzten der neue Methode oMethodPointer.pPosLineMenge := PosLineMengeCustom; result := StartProc(cRechNr, nParCnt, lPrintModusi, obj); end;
Übersteuern von Textbausteinen
Mit der Variable cDBNamePDF im Druck können Textbausteine übersteuert werden.
aktuell verwendet in:
RUECKSENDEAUFTRAG.PAX
ABHOLSCHEIN.PAX
Benutzt in i_Uti.pas function PDFMail_Ext
cDBName := 'AUFTRAG'; cDBNamePDF := 'ABHOLSCHEIN';
Script_Lib Funktion
Neue Script_Lib Funktion
Name : PDFMail
Methode : PDFParameter
Parameter:
Hier kann alles übersteuert werden (Mailtexte usw)
Alle Änderungen gehen auch zurück
oParameter ist vom Typ TOBSParameter (Script)
oParameter.V13 ist der Mail Text
Script_Lib_RunNamePara(oDB,
'PDFMail_Ext',
'PDFParameter',
[
TObject(oParameter),
cDB,
cDB_PDF,
cPsNr
]);
oParameter.Obj := oDB;
oParameter.V1 := cVonEmailAdr;
oParameter.V2 := cEmailAdr;
oParameter.V3 := lSofortSenden;
oParameter.V4 := cPDFFile;
oParameter.V5 := lAnzeige;
oParameter.V6 := cFileExt;
oParameter.V7 := cAddAttach;
oParameter.V8 := cCC;
oParameter.V9 := cBCC;
oParameter.V10 := lLeseBestaetigung;
oParameter.V11 := cMyBetreff;
oParameter.V12 := cMyMailText;
oParameter.V13 := cBuffer;
oParameter.V14 := cTB;
Initialisierungen von Pointern vor der Start Proc
Vor der StartProcCustom wird zuerst die Funktion InitUserLib, dann RunUserLib und erst danach StartProcCustom.
Wenn im User-Ordner eine UserLib.inx liegt, wird diese in der Standard.Inx IMMER mit eingebunden.
Ein Beispiel, bei dem sicher gestellt wird, dass immer wenn in irgendeinem Druck als Papierforma Endlospapier gewählt wurde, bestimmte Ränder gesetzt werden:
// -----------------------------------------------------------------------------
// Procedure: EndloMargins
// -----------------------------------------------------------------------------
procedure EndloMargins();
begin
if lower(cPapierformat) = 'Endlospapier' then begin
ez.Units := MM;
ez.Page.TopMargin := 35;
ez.Page.BottomMargin := 65;
ez.Units := Pixels;
end;
end;
// -----------------------------------------------------------------------------
// Procedure: RunUserLib
// -----------------------------------------------------------------------------
procedure RunUserLib();
begin
oStandardPointer.pBeforeStartPrinter := EndloMargins;
oStandardPointer.pBeforeStartPrinterStd := EndloMargins;
end;
// -----------------------------------------------------------------------------