Lazreport

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
Benutzeravatar
BoraBora
Beiträge: 56
Registriert: So 11. Apr 2021, 16:00
OS, Lazarus, FPC: FPC 3..2.2, L 2.2.0 , Linux Mint, WIN 10&11, Android,
CPU-Target: xxBit

Lazreport

Beitrag von BoraBora »

Guten Morgen,

ich habe mir ein Etikettenprogramm (Windows only) geschrieben, das mit meinem Drucker wunderbar funktioniert.
Wenn ich einen anderen Drucker als meinen Standarddrucker auswähle, beginnen sich die Ausdrucke
horizontal zu verschieben.
Meine Idee war nun das der User die Höhe des Detaildata-Bandes zur Laufzeit verändern kann.
Ich habe das Netz durchsucht und diverses probiert- ohne Erfolg.

1. Ist die Idee richtig, die Höhe des Detaildata-Bandes zu verändern, um einen korrekten Ausdruck zu erreichen?
2. Wenn ja, wie bekomme man das zu Laufzeit hin?

Bin für jeden Hinweis dankbar.

Gruss BB

charlytango
Beiträge: 1258
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
CPU-Target: Win 32/64, Linux64
Wohnort: Wien

Re: Lazreport

Beitrag von charlytango »

bevor ich dazu etwas sage zuerst ein Frage, denn "Etikettenprogramm " kann vielfältig interpretiert werden:

Druckt dein Etikettenprogramm auf einen Labeldrucker oder x mal y Etiketten auf A4 oder unterschiedliche Formate?

charlytango
Beiträge: 1258
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
CPU-Target: Win 32/64, Linux64
Wohnort: Wien

Re: Lazreport

Beitrag von charlytango »

Mir wurde selbst mit Lazreport geholfen und habe daraufhin begonnen eine Label-Engine zu bauen, die aber leider noch nicht ganz fertig ist. Damit kann man jedes einzelne Label einstellen und ggfs auch alle Ränder etc definieren. Bzw die Label-Definitionen auch an den jeweiligen Drucker anzupassen und zu speichern.

Die benutzt lrcodereport (\lazarus\components\lazreport\source\addons) und erzeugt sich den Report per Code und nicht im Designer.
Du kannst gerne mal sehen ob es dir irgendwie weiter hilft. Du musst die nötigen Packages installieren, die du alle in diesem Verzeichnis findest (hoffe ich jedenfalls, ist schon länger her)
Dateianhänge
ct_LabelEngine 02.zip
(619.4 KiB) 20-mal heruntergeladen

Joh
Lazarusforum e. V.
Beiträge: 348
Registriert: Sa 26. Mai 2012, 17:31
OS, Lazarus, FPC: Win 10 (L 2.2.6 x64 FPC 3.2.2)
CPU-Target: 64Bit

Re: Lazreport

Beitrag von Joh »

ich habe im letzten Jahr mit Lazreport versucht, Etiketten zu drucken.
A4-Bögen verschiedenster Art.
Druck auf Kyocera Farblaser; das bekommt man kaum hin.

Dann bin ich hingegangen und habe mir mit libjpfpdf eine pdf-Datei erstellt, auf der ich 10-tel mm genau die Daten positioniert habe.
Das funktioniert so leidlich; man darf z.B. keinen Rand um die einzelnen Etiketten legen weil der Drucker das Papier nach Lust und Laune durchzieht.
Wenn man genau hinsieht, bemerkt man auch, das die einzelnen Bögen nicht deckungsgleich gestanzt sind.

Bei Etiketten 30x50mm oder größer mag das ja alles im Toleranzbereich sein, bei meinen 20mm Durchmesser runden Etiketten oder bei den kleinen 17,8 x 10mm ist so ein mm-chen Versatz schon blöd.

Ganz doof ist, das ich die teuren wetterfesten Bögen nur 1x bedrucken kann, weil beim 2. Versuch der Toner nicht mehr haftet...
just my two Beer

Soner
Beiträge: 785
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: Lazreport

Beitrag von Soner »

Ich glaube du kannst mit folgende Funktionen auf "Bands" und andere Objekte zugreifen:
- TFrReport.Pages[n].FindObjectByID(ID: Integer),
- TFrReport.Pages[n].FindObject(const aName: String): TfrObject;

Einer der größten Fehler bei LazReport ist, dass beim erstellen von Report automatisch Standdrucker gewählt wird. Mann muss immer als erster im Menu "Reportoptions" "default printer" wählen. Vielleicht sollte ich mal dafür Patch reichen.

Benutzeravatar
BoraBora
Beiträge: 56
Registriert: So 11. Apr 2021, 16:00
OS, Lazarus, FPC: FPC 3..2.2, L 2.2.0 , Linux Mint, WIN 10&11, Android,
CPU-Target: xxBit

Re: Lazreport

Beitrag von BoraBora »

Vielen Dank für Eure Antworten!

Ich drucke über Laserdrucker auf DIN A4 verschiedenste Etiketten.

Folgender Ansatz führt zum Absturz:

Code: Alles auswählen

var
  Band: TfrBand;
begin
  frReport1.LoadFromFile(
    'c:\Etiketten\Etiketten_Umkartons\84_Etis_MHD.lrf');
  Band := frReport1.FindObject('DetailData1') as TfrBand;
  Band.Height := 50;  
Das Band 'Detaildata1' wird noch gefunden- die Zuweisung Band.Height := 50; führt zum Absturz.

Bin nun etwas ratlos...

Wenn ihr noch Ideen habt, würde ich mich über ein Feedback freuen.

Gruss BB

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 7251
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Lazreport

Beitrag von af0815 »

BoraBora hat geschrieben: Fr 27. Mär 2026, 09:12 Vielen Dank für Eure Antworten!

Ich drucke über Laserdrucker auf DIN A4 verschiedenste Etiketten.

Folgender Ansatz führt zum Absturz:

Code: Alles auswählen

var
  Band: TfrBand;
begin
  frReport1.LoadFromFile(
    'c:\Etiketten\Etiketten_Umkartons\84_Etis_MHD.lrf');
  Band := frReport1.FindObject('DetailData1') as TfrBand;
  Band.Height := 50;  
Das Band 'Detaildata1' wird noch gefunden- die Zuweisung Band.Height := 50; führt zum Absturz.

Bin nun etwas ratlos...

Wenn ihr noch Ideen habt, würde ich mich über ein Feedback freuen.

Gruss BB
Wenn ich über FindObject gehe, so würde ich die Variable Band vor der Verwendung prüfen:
a ) Vorher dezitiert auf nil setzen, nachher prüfen ob die Varible sicher nicht nil ist.
b ) nicht von hause aus sagen, das zurückgegebene Objekt ist vom Typ TfrBand. also den 'harten' Cast einmal weglassen. Nimm eine allgemeine TObject variable
b ) Wenn die gültig ist, einmal mit "is" prüfen ob die wirklich vom Typ TFrBand ist. Dann erst verwenden.

Erfahrungsgemäß kann es recht überraschende Rückgaben von FindObject geben, deswegen einmal alles prüfen. Der Code wird zwar länger, aber dafür robuster. Weil aktuell behandelst du alles was zurückkommt als TfrBand. Auch wenn es kein TfrBand ist, dann kracht es gerne unvermutet.

Edit: Beispiel

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);  
var
  Band: TfrBand;
  obj: TfrObject;
begin
  frReport1.LoadFromFile(
    'c:\Etiketten\Etiketten_Umkartons\84_Etis_MHD.lrf');
  obj:= nil;  
  obj:= frReport1.FindObject('DetailData1');
  if (obj = nil) then
    exit; // ==>  Objekt nicht gefunden
  if not (obj is TfrBand) then
    exit; // ==> Objekt hat falschen Typ
  Band := obj as TfrBand;
  Band.Height := 50;
end;
ALternativ geht das dann auch

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
var
  obj: TfrObject;
begin
  frReport1.LoadFromFile(
    'c:\Etiketten\Etiketten_Umkartons\84_Etis_MHD.lrf');
  obj:= frReport1.FindObject('DetailData1');
  if (obj = nil) then
    exit; // ==> Objekt nicht gefunden
  if not (obj is TfrBand) then
    exit; // ==> Objekt hat falschen Typ
  TfrBand(obj).Height := 50; // Typ passt deswegen können wir hart casten
end;
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Soner
Beiträge: 785
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: Lazreport

Beitrag von Soner »

Mein Beispiel funktioniert:

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
var aBand1: TfrBand;
    aMemo1: TfrMemoView;
begin
  aMemo1:=TfrMemoView(frReport1.FindObject('Memo1'));
  if Assigned(aMemo1) then aMemo1.Memo.Text:=TimeToStr(now);

  aBand1:=TfrBand(frReport1.FindObject('Band1'));
  if Assigned(aBand1) then aBand1.Height:=100
  else if Assigned(aMemo1) then aMemo1.Memo.Add('Band nicht gefunden');
end;
Ich denke, dass du irgendetwas falsch machst. Du musst beachten, dass einige Drucker größere Druckränder haben, besonders Etikettendrucker. Vielleicht musst du nur Seitenränder vom Papier ändern.
Dateianhänge
lazrepband.zip
(49.03 KiB) 14-mal heruntergeladen

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 7251
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Lazreport

Beitrag von af0815 »

Ich bin beim FindObject etwas vorsichtig geworden und prüfe immer ob das bekommene Objekt immer vom richtigen Typ ist. Besonders dann wenn die Reports auch geändert werden könnten. Da kann es dann zu komischen Effekten kommen, wenn wer die Namen nicht beachtet und die die "Memo1" und "Band1" vertauscht werden. Genau wegen sowas aus der leidvollen Erfahrung zwingen mich zu einer Prüfung als stabilste Lösung.

@Soner, tausch einfach die beiden Namen testweise einmal aus im Report.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Soner
Beiträge: 785
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: Lazreport

Beitrag von Soner »

af0815 hat geschrieben: Fr 27. Mär 2026, 23:03 Ich bin beim FindObject etwas vorsichtig geworden und prüfe immer ob das bekommene Objekt immer vom richtigen Typ ist. Besonders dann wenn die Reports auch geändert werden könnten. Da kann es dann zu komischen Effekten kommen, wenn wer die Namen nicht beachtet und die die "Memo1" und "Band1" vertauscht werden. Genau wegen sowas aus der leidvollen Erfahrung zwingen mich zu einer Prüfung als stabilste Lösung.

@Soner, tausch einfach die beiden Namen testweise einmal aus im Report.
Du hast schon mit vielem recht, aber:

1. Man kann in Dokumentation schreiben, dass das Object von diesem Typ sein muss und diesen Namen haben muss. Mann muss nur bessere Objektnamen benutzen und nicht Band1, Memo1... Wenn trotzdem irgendjemand versucht mit Hammer Schrauben zu drehen und mit Schraubenzieher Nageln zu hammern, dann ist diesem nicht mehr zu helfen.

2. Man kann es auch so lösen:

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
var aBand1: TfrBand;
    aMemo1,aMemo2, aMemo3: TfrMemoView;
begin
  aMemo1:=TfrMemoView(frReport1.FindObject('Memo1'));
  if Assigned(aMemo1) then aMemo1.Memo.Text:=TimeToStr(now);

  aBand1:=TfrBand(frReport1.FindObject('Band1'));
  if Assigned(aBand1) then aBand1.Height:=100
  else if Assigned(aMemo1) then aMemo1.Memo.Text:=aMemo1.Memo.Text+'Band nicht gefunden 1';

  // Simulieren von falschem Objecttyp (es tut was es tun soll)
  aMemo2:=TfrMemoView(frReport1.FindObject('Band1'));
  if Assigned(aMemo2) and (aMemo2 is TfrMemoView) then aMemo2.Memo.Text:=TimeToStr(now)+' Memo2'
  else begin
    aMemo2:=nil;
    if Assigned(aMemo1) then aMemo1.Memo.Text:=aMemo1.Memo.Text+'  Band nicht gefunden 2';
  end;
  if Assigned(aMemo2) then begin
    //mach was damit
  end;

  //Simulieren von nicht existentem Objeckt(Memo3 gibt es nicht)
  aMemo3:=TfrMemoView(frReport1.FindObject('Memo3'));
  if Assigned(aMemo3) then aMemo3.Memo.Text:=TimeToStr(now)
  else if Assigned(aMemo1) then aMemo1.Memo.Text:=aMemo1.Memo.Text+' Memo3 gibt es nicht';
end;
Dateianhänge
lazrepband2.zip
(49.2 KiB) 11-mal heruntergeladen

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 7251
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Lazreport

Beitrag von af0815 »

Soner hat geschrieben: Sa 28. Mär 2026, 09:25 Du hast schon mit vielem recht, aber:

1. Man kann in Dokumentation schreiben, dass das Object von diesem Typ sein muss und diesen Namen haben muss. Mann muss nur bessere Objektnamen benutzen und nicht Band1, Memo1...
Jaja, das mit dem RTFM :-) BTW: Aussage eines Firmenbesitzers - "Ich zahle die (Werktätigen) nicht zum Denken, sondern zum Arbeiten - pass deine Programme daran an".

Ich schau mit das Beispiel mit dem eingebetteten Report dann an.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Antworten