1. Design reportu

Top  Previous  Next

Vytvoříme nový report. Vložíme sloupce A..O a řádky 1..18, a vložíme datový zdroj

Nyní vytvoříme novou událost OnBeforeReport.

Přepneme ná záložku Kód a v ComboBoxu komponent reportu vybereme ReportProperty (je to většinou poslední položka seznamu komponent)

Vytvoříme událost OnBeforeReport poklepáním na vlastnost-událost OnBeforeReport v property editoru.

 

V události naplníme data z dotazu od buňky B5:

 

 BDEQuery1.Query.Open;

 Sheet['B5'].QueryToCells :=  BDEQuery1.Query ;    

 

Výhody i nevýhody jsou zřejmé. Abychom tedy mohli určit do kterých sloupečků se jednotlivé hodnoty vloží naplníme report pomocí cyklu while:

 

begin

 BDEQuery1.Query.Close;

 BDEQuery1.Query.Open;

 while not BDEQuery1.Query.Eof do

 begin

   // Naplneni dat do bunek

 

   BDEQuery1.Query.Next;                          

 end;            

end;

 

Na začátku průchodu ještě Query obnovíme pomocí  Close a Open;

Nyní vložíme data do buněk:

   Sheet[['B',r]].Cells:=<Query1."rok">;

   Sheet[['C',r]].Cells:=<Query1."mesic">;    

   Sheet[['D',r]].Cells:=<Query1."fakturace">;    

   Sheet[['E',r]].Cells:=<Query1."prijempenez">;    

   Sheet[['F',r]].Cells:=<Query1."vydejpenez">;    

   Sheet[['G',r]].Cells:=<Query1."jednicmat">;  

   Sheet[['H',r]].Cells:=<Query1."objednavky">;    

   Sheet[['I',r]].Cells:=<Query1."zakazky">;

 

Deklarujeme proměnnou r, na začátku nastavíme na r:=5; před Next proměnou inkrementujeme o 1:

procedure OnBeforeReport( Sender : TReportProperty );

var

 r : integer;                                  

begin

 r:=5;          

 while not BDEQuery1.Query.Eof do

 begin

   Sheet[['B',r]].Cells:=<Query1."rok">;

   Sheet[['C',r]].Cells:=<Query1."mesic">;    

   Sheet[['D',r]].Cells:=<Query1."fakturace">;    

   Sheet[['E',r]].Cells:=<Query1."prijempenez">;    

   Sheet[['F',r]].Cells:=<Query1."vydejpenez">;    

   Sheet[['G',r]].Cells:=<Query1."jednicmat">;  

   Sheet[['H',r]].Cells:=<Query1."objednavky">;    

   Sheet[['I',r]].Cells:=<Query1."zakazky">;  

 

   inc(r);                          

   BDEQuery1.Query.Next;                          

 end;            

end;

 

Zkompilujeme skript a vyzkoušíme, výsledek je stejný jako u QueryToCells s tím, že nyní si již můžeme vybrat kam se data vloží. Toho nyní využijeme a vložíme prázdné sloupce za každý sloupeček s daty. Sloupečky samozřejmě nebudeme vkládat, ale při plnění reportu kumulační sloupce vynecháme. Posuňme tedy vybrané sloupečky:

   Sheet[['B',r]].Cells:=<Query1."rok">;  

   Sheet[['C',r]].Cells:=<Query1."mesic">;  

   Sheet[['D',r]].Cells:=<Query1."fakturace">;                                            

   Sheet[['F',r]].Cells:=<Query1."prijempenez">;      

   Sheet[['H',r]].Cells:=<Query1."vydejpenez">;      

   Sheet[['J',r]].Cells:=<Query1."jednicmat">;      

   Sheet[['L',r]].Cells:=<Query1."objednavky">;      

   Sheet[['N',r]].Cells:=<Query1."zakazky">;      

 

Znovu zkompilujeme a vyzkoušíme …. a vidíme, že data nejsou zcela vpořádku, protože některé námi zamýšlené sloupečky nejsou prázdé ale obsahují původní data. To je vpořádku protože jsme posunuli jen plnění sloupečků ale původní obsah nemažeme. Proto tedy vybereme celý rozsah reportu a klávesou Del obsah smažeme a celý report restartujeme.  Nyní už jsou data vpořádku.

Nyní již můžeme vyrobit a vyplnit záhlaví sloupců a tabulku nějak vhodně obarvit a nastavit šířku sloupců. Naformátovat číselné údaje.

Nyní naplníme kumulační sloupečky:

Vyrobíme procedure:

 procedure CreateKumulace(chCol : char; rr : integer);

 begin

   if rr=5 then

   Sheet[[chCol,rr]].formulas:='='+Chr(ord(chCol)-1)+inttostr(rr)

    else

   Sheet[[chCol,rr]].formulas:='='+Chr(ord(chCol))+inttostr(rr-1)+'+'+Chr(ord(chCol)-1)+inttostr(rr)                            

 end;

 

a modifikujeme naplnění reportu s použitím nové procedury

   Sheet[['B',r]].Cells:=<Query1."rok">;  

   Sheet[['C',r]].Cells:=<Query1."mesic">;  

   Sheet[['D',r]].Cells:=<Query1."fakturace">;  

   CreateKumulace('E',r);                                        

   Sheet[['F',r]].Cells:=<Query1."prijempenez">;  

   CreateKumulace('G',r);      

   Sheet[['H',r]].Cells:=<Query1."vydejpenez">;  

   CreateKumulace('I',r);      

   Sheet[['J',r]].Cells:=<Query1."jednicmat">;  

   CreateKumulace('K',r);      

   Sheet[['L',r]].Cells:=<Query1."objednavky">;  

   CreateKumulace('M',r);      

   Sheet[['N',r]].Cells:=<Query1."zakazky">;        

   CreateKumulace('O',r);

 

Tím je kompletní report hotov a můžeme přistoupit k vytvoření filtru. Nejprve si vytvoříme ComboBox s výběrem roku.  Z postranního panelu komponent vybereme ComboBoxEx a kliknutím vložíme do buňky C2. Sloučíme buňky C2 a  D2.

 

Nyní přepneme na záložku Data a změníme SQL dotaz tak aby očekával parametr  :rok. Poklepem na ikonku Query1 můžeme změnit SQL dotaz:

z where rok=2012 na where rok=:rok

 

 

ještě musíme Query sdělit odkud má parametr rok vzít. Upravený dotaz tedy uložíme a vyvoláme editor parametrů dotazu . U rok změníme typ parametru na string a zadáme TComboBoxEx(Sheet['C2'].CellComponent).Text.

Tím dotazu říkáme, že chceme parametr rok naplnit hodnotou z comboboxu, který je v buňce C2.  Pokud nyní vybereme rok, report uložíme a restartujeme projeví se již filtrace na zobrazených datech.

Takto vytvořený filtr ovšem na výběr roku reaguje pouze po spuštění reportu. Zmodifikujme jej tak, aby reagoval na změnu v comboboxu ihned.

Potřebujeme tedy aby při změně hodnoty comboboxu ze zavolal kód, který je nyní v události OnBefore report. Změňme skript tak, že událost OnBeforeReport změníme na proceduru například s názvem Fill a tuto proceduru zavoláme jako jedinný kód v události OnBeforeReport, tím jsme zachovali původní funkčnost, teď ještě musíme zavolat FillData při změně comboboxu pro výběr roku.

Napíšeme proceduru která s zavolá při změně comboboxu:

procedure List1_C2ComboBoxExOnChange;

begin

 FillData;                              

end;          

Ta je samozřejmě triviální, protože chceme pouze zavolat FillData. A nakonec ještě přiřadíme tuto procedure události OnChange komponenty combobox. Nejvhodnějším mistem pro toto přiřazení je událost onPrepareScript:

procedure OnPrepareScript( Sender : TReportProperty );

begin

 TComboBoxEx(Sheet['C2'].CellComponent).OnChange:=@List1_C2ComboBoxExOnChange;    

end;

 

Skript překompilujeme a report vyzkoušíme. Pokud budete sledovat report pozorně pravděpodobně uvidíte, jak se report naplnil a potom se aplikují zobrazovací formáty. Předejít a zrychlit plnění reportu lze uzamčením zobrazení reportu mezi BeginUpate a EndUpdate

Report je hotový. Je možné přidat další kosmetické úpravy například seskupovaní kumulačních sloupců.

 

Graf

Nastavte výšku řádku na 400px. Slučte buňky B18..O18. Vložte komponentu TDbChart.

Upravit vložený graf lze tak že vybere buňku B18 a poté vyvoláte pravým tlačítkem myši kontextovou nabídku a poté vyberte Upravit Graf

Nastavte:

General – Panel – white

3D off

A můžete si i zkušebně vytvořit pár series a function series ...

 

Nyní vytvoříme series kódem

Var

 ser : TBarSeries;

 // graph                

 Chart:=TDbChart(Sheet['B18'].CellComponent);

 Chart.FreeAllSeries;

 for i:=0 to length(serNames)-1 do

 begin            

   ser := TBarSeries(Chart.AddSeries(TBarSeries.Create(Chart)));

   with ser do

   begin              

     Title:=serNames[i];

     Marks.Visible := False;

     MultiBar:=1;

     BarPen.Visible:=False;

     SeriesColor:=ExcelPalette[i];

   

     DataSource:=Query1.Query;

     XLabelsSource:=Query1.Query.Fields[1].FieldName;

     YValues.ValueSource:=Query1.Query.Fields[i+2].FieldName;                            

   end;

 end;      

 

přidáme checkboxy jako záhlaví sloupců a zapojíme funkčnost:

před vytvořením series otestujeme zda je checknutý příslušný checkbox:

 if TCheckBox(Sheet[[(i+2)*2,4]].CellComponent).Checked then

 

a v onPrepareScript doplnime

 TCheckBox(Sheet['D4'].CellComponent).OnClick:=@FillGraph;

 TCheckBox(Sheet['F4'].CellComponent).OnClick:=@FillGraph;

 TCheckBox(Sheet['H4'].CellComponent).OnClick:=@FillGraph;

 TCheckBox(Sheet['J4'].CellComponent).OnClick:=@FillGraph;

 TCheckBox(Sheet['L4'].CellComponent).OnClick:=@FillGraph;

 TCheckBox(Sheet['N4'].CellComponent).OnClick:=@FillGraph;

 

 

 

Přidáme ještě combo na výbě typu series

 

Vložte ComboBoxEx na F2 : a naplňte itemsEx:

Bar

Line

Point

Area

 

nyní zmodifikujeme script na vytvoření series :

 

procedure FillGraph( Sender : TObject );

var

 i : integer;

 Chart : TDbChart;

 ser : TChartSeries;

begin          

// graph                

 Chart:=TDbChart(Sheet['B18'].CellComponent);

 Chart.FreeAllSeries;

 for i:=0 to length(serNames)-1 do

 if TCheckBox(Sheet[[(i+2)*2,4]].CellComponent).Checked then                                                                                        

 begin

   case TComboBoxEx(Sheet['F2'].CellComponent).ItemIndex of                      

   0 : ser:=Chart.AddSeries( TBarSeries.Create(Chart) );      

   1 : ser:=Chart.AddSeries( TFastLineSeries.Create(Chart) );

   2 : ser:=Chart.AddSeries( TPointSeries.Create(Chart) );

   3 : ser:=Chart.AddSeries( TAreaSeries.Create(Chart) );      

   end;          

 

   with TCustomBarSeries(ser) do

   begin              

     Title:=serNames[i];

     Marks.Visible := False;

     If TComboBoxEx(Sheet['F2'].CellComponent).ItemIndex=0 then

     begin              

       TCustomBarSeries(ser).MultiBar:=1;  

       TCustomBarSeries(ser).BarPen.Visible:=False;                  

     end;

     SeriesColor:=ExcelPalette[i];    

     DataSource:=Query1.Query;

     XLabelsSource:=Query1.Query.Fields[1].FieldName;

     YValues.ValueSource:=Query1.Query.Fields[i+2].FieldName;                            

   end;

 end;

end;