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ě ;-)
|