2. Skript reportu

Top  Previous  Next

Protože chceme naplnit report dynamicky použijeme globální skript reportu OnBeforeReport. V property editoru použijte lookupbox a posuvníkem se přesuňte na poslední položku a vyberte ReportProperty:

Poklepejte na prázdné políčko vpravo od OnBeforeReport, tím vygenerujete událost OnBeforeReport

 

 

a v kódu skriptu se objeví

 

procedure OnBeforeReport(Sender : TReportProperty);

begin

 

end;

 

Tělo této události budeme nyní upravovat, výsledný kód vypadá následovně, je to triviální skript a nemělo by činit potíže jej pochopit:

 

procedure OnBeforeReport(Sender : TReportProperty);

var

 Query : TQuery;

 r : integer;     // řádek listu                        

begin

 Sheet.BeginUpdate;

 Sheet.RowCount:=3;

 Sheet.ColCount:=6;    

 Sheet.FixedRows:=2;

 Sheet.ClearMergeCells;                                    

 

 Query:=TQuery.Create(nil); // vytvoříme Query                  

 with Query do

 try

   DatabaseName :=DefaultDatabaseName;

   SQL.Text:='select mena_id,(select nazev from dba.gstaty where id_stat=(select stat_id from dba.gmeny where mena_id=id_mena)) as nazev '+

             'from dba.gkurzy group by mena_id';

   Open;

 

   r:=3;

   

   while not Query.Eof do // projdeme postupně všechny řádky query

   begin

     while Sheet.RowCount-1<r do Sheet.AddRow; // pokud počet řádků reportu nedostačuje vložíme nový řádek

 

     Sheet.CellProperty[2,r].Tag:=1; // Buňku do které vypíšeme měnu si ještě označíme pomocí Tag=1 ostatní buňky reportu mají default Tag=0, toho využijeme později                                                                      

     Sheet.Cells[2,r]:=Query.FieldByName('mena_id').AsString; // zapíšeme měnu

     Sheet.MergeCells(3,r,4,r);                                   // název státu měny může být delší, slučme tedy 2 buňky dohromady

     Sheet.Cells[3,r]:=Query.FieldByName('nazev').AsString;   // a do takto sloučené buňky zapišme název státu z dotazu výše

     // nyní trochu kosmetiky

 // všimněte si že buňku [4,r] nebarvíme, tato buňka je sloučena do [3,r] a přebírá všechny její vlastnosti

     Sheet.CellProperty[2,r].Background:=$00bd814f;Sheet.CellProperty[2,r].Font.Color:=clWhite;                                          

     Sheet.CellProperty[3,r].Background:=$00bd814f;Sheet.CellProperty[3,r].Font.Color:=clWhite;

 

     // na tomto místě přiřadíme ještě buňce s kódem měny událost buňky OnDblClick s názvem @MenaDblClick, kterou vysvětlíme dále

     Sheet.CellProperty[2,r].OnDblClick:=@MenaDblClick; // <--- OnDblClick

     

     inc(r);     // popojedem na další řádek Query            

     Query.Next;

   end;    

 finally

   Free;

 end;

                   

 Sheet.EndUpdate;                                            

end;

 

Nyní můžete práci uložit a pokud chcete i vyzkoušet: smažte řádek označený // <--- OnDblClick a můžete skript pomocí Ctrl+F9 zkusit přeložit pokud jste uspěli bez chyb, celý report uložte, vypněte design režim. Abyste report mohli vyzkoušet je třeba se přepnout na jiný report a potom zpět na tento aby se uplatnila událost OnBeforeReport. Pokud jste neudělali chybu vidíte seznam kurzů s názvem státu a my můžeme pokračovat.

 

Pokud jste smazali řádek Sheet.CellProperty[2,r].OnDblClick:=@MenaDblClick; // <--- OnDblClick vložte jej zpět

 

Nyní vyrobíme drillovací kouzlo, nejprve napíšeme událost @MenaDblClick - vypadá a je velmi jednoduchá. Zavoláme proceduru DrillMe, předáme si Value což je v našem případě kód měny a Sheet.Row což je aktuální řádek v listu na kterém jsme poklepali, tato procedura se zavolá vždy, když poklepeme na buňku s měnou a buňce jsme tuto událost přiřadili výše (označeno // <--- OnDblClick )

 

procedure MenaDblClick(Sender : TCellProperty);

begin

 DrillMe(Value,Sheet.Row);                                  

end;

 

A nyní DrillMe

 

procedure DrillMe( mena : string; aRow : integer );

var

 Query : TQuery;

 r : integer;

 flgCollapse : boolean;                                                    

begin

 Sheet.BeginUpdate;

 

 //Collapse

 flgCollapse:=false;                                        

 r:=aRow+1;           // nastav pozici na řádek pod měnou na kterou jsme poklepali

                                                                           

 while (Sheet.CellProperty[2,r].Tag=0) and (r<Sheet.RowCount) do // je na této pozici Měna nebo rozbalený detail? Tag=0 nebo 1

 begin

   flgCollapse:=True;                                      

   Sheet.DeleteRow(r); // sbal detail, tedy smaž řádky s historií kurzu

 end;

 if flgCollapse then // sbalili jsme nějaké řádky? Potom je to Collapse a můžeme skončit

 begin

   Sheet.EndUpdate;                                  

   Exit;    

 end;                

 

 // neprovedli jsme collapse je tedy třeba expand                                                  

 Query:=TQuery.Create(nil);                  

 with Query do

 try

   DatabaseName :=DefaultDatabaseName;

   SQL.Text:='select top 5 dne,koef from dba.gkurzy where mena_id=:mena order by dne desc';

   Params.ParamByName('mena').AsString:=mena;                                                            

   Open;

   

     r:=aRow+1;

     while Sheet.ColCount-1<3 do Sheet.InsertCol(Sheet.ColCount-1); // jistota je kulomet co kdyby nám ty sloupečky mezitím někdo smazal, no dobře tento řádek by tu klidně být nemusel                          

     

     while not Query.Eof do // podobně jako výše projedeme Query a nasypeme nové řádky s datumem a kurzem, to už umíme protože jsme to dělali v OnBeforeReport

     begin

       Sheet.InsertRow(r); // vložíme nový řádek detailu                                        

 

       Sheet.Cells[3,r]:=Query.FieldByName('dne').AsString;

       Sheet.Cells[4,r]:=Query.FieldByName('koef').AsString;

 

 

   // no a aby to bylo krásné trochu barvy nezaškodí        

       Sheet.CellProperty[3,r].Background:=clInactiveCaption;        

       Sheet.CellProperty[4,r].Background:=clInactiveCaption;                

       

       inc(r);                  

       Query.Next;

     end;

     

 finally

   Free;

 end;

 Sheet.EndUpdate;    

end;

 

 

Toť vše, jednoduché že? Všímavý čtenář teď možná nechápavě kroutí hlavou proč všechny položky sypeme na listu reportu do Cells a ne do Formulas. Ano, ano, chyba, veliká chyba, správně by to opravdu mělo být do Formulas; po naplnění bychom měli zavolat Eval aby se položky projevily v Cells nebo bychom měli plnit jak Cells, tak Formulas ale tady si to pro zjednodušení můžeme dovolit. Pokud se chcete podívat proč je to špatně, stiskněte si v reportu F9 nebo modifikujte nějakou buňku v reportu .... a ....a za domácí úkol report upravte tak aby i v tomto případě fungoval správně ;-)