@Junix - FAQ Beitrag StringGrid mit QuickRep drucken



  • Hi@all

    Nach langem hin- und hergesuche und hier und da einigen Hinweisen gefunden habe ich micht jetzt mal daran gemacht ein StringGrid mittels QuickReport zu drucken .
    Für alle die auch auf verzweifelter Suche danach sind möchte ich dieses als FAQ - Beitrag bereitstellen .

    Besondere Dank an Bc.Jaroslav Blazek und sein TListView - QuickReport .

    Code StringGrid Spaltenauswahl

    // © 2003 concept´s multimedia
    // Mario Bothge
    //
    // StringGrid drucken mit QuickReport
    //---------------------------------------------------------------------------
    // StringGrid - Formular
    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    
    #include "tabelle.h"
    #include "qreport.h"
    
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    int colwidth[100]; // Spaltenbreite
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {
    }
    
    //---------------------------------------------------------------------------
    // StrinGrid anlegen
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormShow(TObject *Sender)
    {
    // Beispieldaten für StringGrid
    StringGrid1->Cells[0][0]="Vorname";
    StringGrid1->Cells[1][0]="Nachname";
    StringGrid1->Cells[2][0]="Strasse";
    StringGrid1->Cells[3][0]="Ort";
    StringGrid1->Cells[4][0]="Beruf";
    
    StringGrid1->Cells[0][1]="Alfred";
    StringGrid1->Cells[1][1]="Müller";
    StringGrid1->Cells[2][1]="Hauptstrasse ";
    StringGrid1->Cells[3][1]="Lauchhammer";
    StringGrid1->Cells[4][1]="Bäcker";
    
    StringGrid1->Cells[0][2]="Fritz";
    StringGrid1->Cells[1][2]="Maier";
    StringGrid1->Cells[2][2]="Waldweg";
    StringGrid1->Cells[3][2]="Potsdam";
    StringGrid1->Cells[4][2]="Taxifahrer";
    
    // Spaltenbreite merken
    for (int spalte=0; spalte < StringGrid1->ColCount; spalte++)
    colwidth[spalte]= StringGrid1->ColWidths[spalte];
    }
    
    //---------------------------------------------------------------------------
    // Spaltenbreite an Text anpassen
    //---------------------------------------------------------------------------
    void __fastcall TForm1::StringGrid1DrawCell(TObject *Sender, int ACol,
          int ARow, TRect &Rect, TGridDrawState State)
    {
     int textlength=0;
     textlength=Canvas->TextWidth(StringGrid1->Cells[ACol][ARow]);
     if (StringGrid1->ColWidths[ACol] < textlength) StringGrid1->ColWidths[ACol]=textlength+50;
    }
    
    //---------------------------------------------------------------------------
    // Spaltenauswahl zum drucken
    //---------------------------------------------------------------------------
    void __fastcall TForm1::CheckBox1Click(TObject *Sender)
    {
    // CheckBoxen müssen mit TAG-ID versehen werden um die Zuordnung zur Spalte zu gewährleisten
    // Spalte 0 = CheckBox1 TAG-ID=0 usw.
    
    TCheckBox *CB = dynamic_cast<TCheckBox*>(Sender);
     if (CB)
     {
      if (!CB->Checked) // Spaltenbreite auf 0 setzen
      {
       StringGrid1->ColWidths[CB->Tag]=0;
      }
      else // Spaltenbreite zurücksetzen
      {
      StringGrid1->ColWidths[CB->Tag]=colwidth[CB->Tag];
      }
     }
    }
    
    //---------------------------------------------------------------------------
    // QR Preview aufrufen
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
     ReportForm->QRLabel1->Caption = "Überschrift";
     // Vor dem Aufruf der Preview Funktion müssen die Tabellenwerte in QReport geschrieben werden
     ReportForm->SetView();
     ReportForm->Report->Preview();
    }
    
    //---------------------------------------------------------------------------
    // Programm beenden
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Button2Click(TObject *Sender)
    {
    Close();
    }
    //---------------------------------------------------------------------------
    

    Header Datei StringGrid - Spaltenauswahl

    //---------------------------------------------------------------------------
    
    #ifndef tabelleH
    #define tabelleH
    //---------------------------------------------------------------------------
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>
    #include <ComCtrls.hpp>
    #include <Grids.hpp>
    //---------------------------------------------------------------------------
    class TForm1 : public TForm
    {
    __published:    // IDE-managed Components
            TButton *Button1;
            TButton *Button2;
            TStringGrid *StringGrid1;
       TCheckBox *CheckBox1;
       TCheckBox *CheckBox2;
       TCheckBox *CheckBox3;
       TCheckBox *CheckBox4;
       TCheckBox *CheckBox5;
       TStatusBar *StatusBar1;
    
            void __fastcall Button1Click(TObject *Sender);
       void __fastcall Button2Click(TObject *Sender);
       void __fastcall FormShow(TObject *Sender);
       void __fastcall CheckBox1Click(TObject *Sender);
      void __fastcall StringGrid1DrawCell(TObject *Sender, int ACol, int ARow,
              TRect &Rect, TGridDrawState State);
    private:    // User declarations
    public:     // User declarations
            __fastcall TForm1(TComponent* Owner);
    };
    //---------------------------------------------------------------------------
    extern PACKAGE TForm1 *Form1;
    //---------------------------------------------------------------------------
    #endif
    

    Code QuickReport

    // © 2003 concept´s multimedia
    // Mario Bothge
    //
    // StringGrid drucken mit QuickReport
    //---------------------------------------------------------------------------
    // QuickReport Formular
    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    
    #include "qreport.h"
    #include <QRCTRLS.hpp>
    #include "tabelle.h"
    
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TReportForm *ReportForm;
    //---------------------------------------------------------------------------
    __fastcall TReportForm::TReportForm(TComponent* Owner)
            : TForm(Owner)
    {
    }
    
    //---------------------------------------------------------------------------
    // Bänder anlegen
    //---------------------------------------------------------------------------
    void __fastcall TReportForm::FormCreate(TObject *Sender)
    {
     FOListColumnBand = new TObjectList(true);
     FOListDetailBand = new TObjectList(true);
    }
    
    //---------------------------------------------------------------------------
    // Darstellungsoptionen setzen
    //---------------------------------------------------------------------------
       void __fastcall TReportForm::SetView()
    {
     FOListColumnBand->Clear();
     FOListDetailBand->Clear();
    
     if ( Form1->StringGrid1->ColCount >0) // wenn mind. eine Spalte vorhanden
     {
      int Breite = GetSize(); // Breite gemäß Tabellenbreite
      if (Breite > QRTableHeader->Width) Report->Page->Orientation = poLandscape; // Querformat
      else Report->Page->Orientation = poPortrait; // Standard Hochformat
    
      if (Form1->StringGrid1->FixedRows)
       // wenn Tabelle Überschriftzeile hat  - Header bilden
       CreateQRLabels(QRTableHeader);
    
       // ansonsten Details bilden
       CreateQRLabels(QRTableDetail);
     }
    }
    
    //---------------------------------------------------------------------------
    // Darstellungsgröße ermitteln
    //---------------------------------------------------------------------------
    int __fastcall TReportForm::GetSize()
    {
     // Anzeigebreite gemäß Tabellengesamtbreite ermitteln
     int Breite = 0;
     for (int spalte = 0; spalte < Form1->StringGrid1->ColCount; spalte++)
     Breite += Form1->StringGrid1->ColWidths[spalte];
     return Breite;
    }
    
    //---------------------------------------------------------------------------
    // Temporäre QRLabels erstellen
    //---------------------------------------------------------------------------
    void __fastcall TReportForm::CreateQRLabels(TQRBand *ABand)
    {
     TObjectList *TmpOList;
     TQRCustomBand *TmpBand;
     switch (ABand->BandType)// Entweder Überschrift oder Detail
      {
       case rbColumnHeader :
                    TmpOList = FOListColumnBand;
                    TmpBand = Report->Bands->ColumnHeaderBand;
                    break;
       case rbDetail       :
                    TmpOList = FOListDetailBand;
                    TmpBand = Report->Bands->DetailBand;
                    break;
      }
     TQRLabel *TmpQRLabel;
     int PosLeft = 0; //Ausrichtung links gleich null
    
     // Anzahl der Spalten ermitteln
     for (int spalte = 0; spalte < Form1->StringGrid1->ColCount; spalte++)
      {
       // Temporäre Labels hinzufügen
       TmpOList->Add((TObject *)TmpBand->AddPrintable(__classid(TQRLabel)));
       TmpQRLabel = (TQRLabel *)TmpOList->Items[TmpOList->Count-1];
       // Erscheinungsbild des Labels konfigurieren
       if ( Form1->StringGrid1->ColWidths[spalte]>0) // nur wenn Spaltenbreite größer null
       {
        TmpQRLabel->Alignment = taLeftJustify; // Ausrichtung
        TmpQRLabel->AutoSize = false;
        TmpQRLabel->Font->Name = "Verdana" ;//Schriftart
        TmpQRLabel->Font->Size = 8 ;//Schriftgröße
        TmpQRLabel->Font->Style = TFontStyles();//Schriftstil normal
        TmpQRLabel->Font->Color = clBlack; // Schriftfarbe
        TmpQRLabel->Top = 0; //Position oben
        TmpQRLabel->Left = PosLeft-1; // Position Links abzüglich Linienstärke
        TmpQRLabel->Height = TmpBand->Height; // Höhe
        TmpQRLabel->Width = Form1->StringGrid1->ColWidths[spalte];// Breite
        TmpQRLabel->Frame->DrawLeft = true; // Linie links
        TmpQRLabel->Frame->DrawRight = true; // Linie rechts
        // wenn Überschrift
        if (ABand->BandType == rbColumnHeader)
         {
          TmpQRLabel->Frame->DrawBottom = true; // Linie untern
          TmpQRLabel->Frame->DrawTop = true; // Linie oben
          TmpQRLabel->Font->Style = TFontStyles()<< fsBold; // Schriftstil fett
          TmpQRLabel->Font->Color = clNavy; // Schriftfarbe
          TmpQRLabel->Color = clInfoBk; // Hintergrund
          TmpQRLabel = (TQRLabel *)FOListColumnBand->Items[spalte]; // Temporäres Label gemäß Spalte
          TmpQRLabel->Caption = " " + Form1->StringGrid1->Cells[spalte][0]; // Text gemäß Spalte
         }
        PosLeft += TmpQRLabel->Width-1; // Position links um Breite des vorherigen verschieben
       }
      }
    }
    
    //---------------------------------------------------------------------------
    // Auslesen der Daten aus dem StringGrid und schreiben in die TempLabel
    //---------------------------------------------------------------------------
    void __fastcall TReportForm::ReportNeedData(TObject *Sender, bool &MoreData)
    {
    static int zeile = 0;
    MoreData = ++zeile < Form1->StringGrid1->RowCount;
    if (MoreData)
     {
      TQRLabel *TmpQRLabel;
      for (int spalte = 0; spalte < Form1->StringGrid1->ColCount; spalte++)
      {
       if ( Form1->StringGrid1->ColWidths[spalte]>0)
       {
        TmpQRLabel = (TQRLabel *)FOListDetailBand->Items[spalte];
        if (Form1->StringGrid1->FixedRows==0)
        TmpQRLabel->Caption = " " + Form1->StringGrid1->Cells[spalte][zeile-1];
        else
        TmpQRLabel->Caption = " " + Form1->StringGrid1->Cells[spalte][zeile];
       }
      }
     }
     else
     zeile = 0;
    }
    
    //---------------------------------------------------------------------------
    // QR Preview beenden
    //---------------------------------------------------------------------------
    void __fastcall TReportForm::FormDestroy(TObject *Sender)
    {
     delete FOListColumnBand;
     delete FOListDetailBand;
    }
    //---------------------------------------------------------------------------
    

    Header Datei QuickReport

    //---------------------------------------------------------------------------
    
    #ifndef qreportH
    #define qreportH
    //---------------------------------------------------------------------------
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>
    #include <ExtCtrls.hpp>
    #include <QuickRpt.hpp>
    #include <Qrctrls.hpp>
    //---------------------------------------------------------------------------
    class TReportForm : public TForm
    {
    __published:    // IDE-managed Components
       TQuickRep *Report;
       TQRBand *QRPageHeader;
       TQRBand *QRTableHeader;
       TQRBand *QRTableDetail;
       TQRLabel *QRLabel1;
       TQRBand *QRPageFooter;
       TQRSysData *QRSysData1;
       void __fastcall FormCreate(TObject *Sender);
       void __fastcall FormDestroy(TObject *Sender);
       void __fastcall ReportNeedData(TObject *Sender, bool &MoreData);
       void __fastcall SetView();
    
    private:
       TObjectList *FOListColumnBand;
       TObjectList *FOListDetailBand;
       void __fastcall CreateQRLabels(TQRBand *ABand);
       int __fastcall GetSize();
    
    public:     // User declarations
        __fastcall TReportForm(TComponent* Owner);
    
    };
    //---------------------------------------------------------------------------
    extern PACKAGE TReportForm *ReportForm;
    //---------------------------------------------------------------------------
    #endif
    

    Verbesserungsvorschläge und Erweiterungshinweise gern gesehen .
    Z.Bsp. Druckvorschau standardmäßig ZoomToFit .

    Naja viel Spaß erst mal
    und
    THX@all



  • Ist es dir nicht ein wenig peinlich, Copyrights zu beanspruchen, wenn 90% des Codes automatisch erzeugt wurden, aus einfachen Stringzuweisungen bestehen oder direkt von anderen Beiträgen "inspiriert" wurden? 😉

    Ausprobiert habe ich es nicht, deshalb nur ein formaler Kritikpunkt: bei if-Abfragen gehört das Ergebnis nicht in dieselbe Zeile wie die Bedingung. Nur weil man es machen kann heisst das noch lange nicht, dass man es auch machen muss. Es sei denn, man möchte seinen Code mit aller Macht so gestalten, dass er möglichst unübersichtlich und schwer zu debuggen ist. 😉



  • Hi@Jansen

    Asche auf´s Haupt !!! 😮

    Das mit dem © ist nicht beabsichtigt um hier den ... raushängen zu lassen .
    Es ist einfach nur so, das dieser Programm-Code ein Teil meines eigentlichen Programms ist .
    Und da habe ich eben diesen © Vermerk mit drin .

    Also wenn denkst, das es hier nicht hingehört - ich hab´s editiert !

    Bei den if... gebe ich dir natürlich recht .
    Der Übersicht halber ist es natürlich besser den Anweisungscode in die Folgezeile zus schreiben .
    Kann dir jetzt nicht sagen warum es hier einigemale anders ist .
    W*****einlich stammt das noch vom hin- und her probieren .

    By



  • Hi@Jansen

    Sorry ich wollt´s editieren .
    Keine Rechte !

    Na gut - Wenn du denkst, das es hier nicht hingehört - würdest du es bitte für mich editieren .

    Danke


Anmelden zum Antworten