Einzelnen Beitrag anzeigen

waldforest

Registriert seit: 8. Mai 2005
366 Beiträge
 
Delphi XE3 Enterprise
 
#1

DBGrid, ausdrucken über mehrere Seitenbreite hinaus

  Alt 30. Sep 2016, 16:50
Hallo,

ich möchte mich etwas intensiver mit dem Drucken, ohne Reportgenerator beschäftigen.

Mit anliegend auf DBGRID angepasstem Code drucke ich ein DBGrid, welche in der Breite über mehrere Blätter geht, aus.

Soweit klappt alles. Mich stört allerdings, dass die Abarbeitung so lange braucht.
Dies liegt sicher einerseits daran, dass jeder Datensatz durchlaufen wird, was ich erst einmal erforderlich ist, anderseits am Erneuten durchlaufen aller Datensätze für das weiter Blatt in der Breite.

Wie könnte man den Code optimieren, z.B. dass nicht für jede neue Seite, welche über die Seitenbreite hinaus erstellt wird, alle Datensätze noch einmal durchlaufen werden müssen.

Delphi-Quellcode:
procedure GridDruckNeu(Grid:tdbgrid; links, oben: Integer; scal:double; DTitle : string; farbig:boolean);
var
  x, y, li, ob, re, un, waag, senk, a, vSpalte, bSpalte, vZeile, bZeile: integer;
  fix, grund, schrift: TColor;
  r: TRect;
  fertig:boolean;
  i,breite,waagseiten:integer;

  function rech(i,j:integer):integer;
  begin
     result:=round(((i*j) / 72) * scal);
  end;

begin
  if dlgPnt1.Execute then
  begin
    Printer.Copies := dlgPnt1.Copies;
    Printer.Orientation := poLandscape;
    vZeile := 0;
    vSpalte := 0;
    bZeile := Grid.DataSource.DataSet.RecordCount;
    bSpalte := grid.Columns.Count;
    waag := GetDeviceCaps(Printer.Handle, LogPixelSX);
    senk := GetDeviceCaps(Printer.Handle, LogPixelSY);
    SetWindowOrgEx(printer.Handle, 0, 0, nil);

    breite:=0; // breite des Ausdrucks, wird gebraucht um ggfs. viewport zu verschieben
    for i := vSpalte to bSpalte-1 do
       if (Grid.Columns.Items[i].Visible) then
         breite:=breite + rech(Grid.Columns[i].Width+1, waag);

    waagseiten:=0;

    if (scal > 0) and
       (vZeile < Grid.DataSource.DataSet.RecordCount) and
       (vSpalte < grid.Columns.Count) then
    begin
       if farbig then
       begin
          fix := grid.fixedcolor;
          grund := grid.color;
          schrift := grid.font.color;
       end
       else
       begin
          fix := clsilver;
          grund := clwhite;
          schrift := clblack;
       end;
       links := rech(links, waag);
       oben := rech(oben, senk);
       li := GetDeviceCaps(Printer.Handle, PhysicalOffsetX) + 1 + links;
       a := rech(3, waag);
       with Printer do
       begin

          Title := DTitle;
          BeginDoc;
           Canvas.Pen.Style := psClear;
          Canvas.Font := Grid.Font;
          Canvas.Font.Color := Schrift;
          Canvas.Font.Size := round((Grid.Font.Size / 0.72) * scal);

          fertig:=false;
          while (not fertig) and (not Printer.Aborted) and Printer.Printing do begin
            ob := GetDeviceCaps(Printer.Handle, PhysicalOffsetY) + 1 + oben;
            un := ob + round(Printer.Canvas.TextHeight('A')*scal)+15;
            for x := 0 to Grid.Columns.Count - 1 do
            begin
              if (Grid.Columns.Items[x].Visible) then
              begin
                re := li + rech(Grid.Columns[x].Width + 4, waag);
              // Canvas.Rectangle(li, ob, re + 2, un + 2); // zeichnet grauen Rahmen um das Grid
                r := rect(li + a, ob + 1, re - a, un - 2);
                DrawText(Canvas.Handle, pchar( Grid.Columns.Items[x].Title.Caption), Length(Grid.Columns.Items[x].Title.Caption), r, DT_SINGLELINE or DT_VCENTER);
                li := re;
              end;
            end;
            li := GetDeviceCaps(Printer.Handle, PhysicalOffsetX) + 1 + links;
            ob := un;

            Grid.DataSource.DataSet.first;
            while (not Printer.Aborted) and (not Grid.DataSource.DataSet.Eof) and Printer.Printing do
            begin
                un := ob + round(Printer.Canvas.TextHeight('A')*scal)+15; // aufaddieren des Unterrandes
               //neue Seite + Kopf
               if (un > Printer.PageHeight) and
                  (Printing) then
               begin
                  printer.NewPage;
                  SetWindowOrgEx(printer.Handle,printer.pageWidth*waagseiten, 0, nil);
                  ob := GetDeviceCaps(Printer.Handle, PhysicalOffsetY) + 1 + oben;
                  un := ob + round(Printer.Canvas.TextHeight('A')*scal)+15;
                  for x := 0 to Grid.Columns.Count - 1 do
                  begin
                    if (Grid.Columns.Items[x].Visible) then
                    begin
                      re := li + rech(Grid.Columns[x].Width + 4, waag);
                    // Canvas.Rectangle(li, ob, re + 2, un + 2); // zeichnet grauen Rahmen um das Grid
                      r := rect(li + a, ob + 1, re - a, un - 2);
                     DrawText(Canvas.Handle, pchar( Grid.Columns.Items[x].Title.Caption), Length(Grid.Columns.Items[x].Title.Caption), r, DT_SINGLELINE or DT_VCENTER);
                     li := re;
                    end;
                  end;
                  ob := un;
                  li := GetDeviceCaps(Printer.Handle, PhysicalOffsetX) + 1 + links;
               end;
               un := ob + round(Printer.Canvas.TextHeight('A')*scal)+15;
               for x := 0 to Grid.Columns.Count - 1 do
               begin
                  if (Grid.Columns.Items[x].Visible) then
                  begin
                    re := li + rech(Grid.Columns[x].Width + 4, waag);
                  // Canvas.Rectangle(li, ob, re + 2, un + 2); // zeichnet grauen Rahmen um das Grid
                    r := rect(li + a, ob + 1, re - a, un - 2);
                    IF Grid.Columns[x].Alignment = taRightJustify then
                       DrawText(Canvas.Handle, PWChar( Grid.Columns.Items[x].Field.AsString), Length(Grid.Columns.Items[x].Field.AsString), r, DT_SINGLELINE or DT_RIGHT)
                    else if Grid.Columns[x].Alignment = taLeftJustify then
                       DrawText(Canvas.Handle, PWChar( Grid.Columns.Items[x].Field.AsString), Length(Grid.Columns.Items[x].Field.AsString), r, DT_SINGLELINE or DT_LEFT)
                    else
                       DrawText(Canvas.Handle, PWChar( Grid.Columns.Items[x].Field.AsString), Length(Grid.Columns.Items[x].Field.AsString), r, DT_SINGLELINE or DT_VCENTER);

// DrawText(Canvas.Handle, PWChar( Grid.Columns.Items[x].Field.AsString), Length(Grid.Columns.Items[x].Field.AsString), r, DT_SINGLELINE or DT_VCENTER);

                    li := re;
                  end;
                end;
                ob := un;
                li := GetDeviceCaps(Printer.Handle, PhysicalOffsetX) + 1 + links;
                Grid.DataSource.DataSet.Next;
            end;
            // jetzt Prüfung, ob der Ausdruck zu breit ist und ggfs, neue Serie mit verschobenem Viewport
            inc(waagseiten); // anzahl der waagerechten nebeneinanderliegen seiten, die ausgedruckt wurden
            if (breite > (Printer.PageWidth*waagseiten)) then fertig:=false else fertig:=true;
            if not fertig then begin
              printer.NewPage;
              SetWindowOrgEx(printer.Handle,printer.pageWidth*waagseiten, 0, nil); // viewport um Seitengröße verschieben
            end;
          end; // von while not fertig...
          if Printing then EndDoc;
       end; // von WITH PRINTER
    end;
  end;
end; //GridDruckNeu
Ist es vielleicht sinnvoller im DBGRID angezeigten Daten einfacher auszudrucken, wenn ja, wie bekomme ich diese schnell in ein Stringlist ?
mfg wf
  Mit Zitat antworten Zitat