Umíme to s Delphi, 22. díl – tvorba výstupních sestav

V 17. a v 18. díle seriálu jsme se zabývali databázemi v Delphi. Vysvětlili jsme si všechny podstatné detaily související s jejich teorií, návrhem a způsobem vytváření, nicméně zapomněli jsme na jeden důležitý bod: na tvorbu výstupních sestav z databází. Delphi za tím účelem disponuje výkonnými podpůrnými prostředky (komponentami). První část jejich popisu je náplní tohoto dílu seriálu.
Co jsou výstupní sestavy

Při vytváření databázové aplikace jste si možná správně položili otázku, jak docílit efektivního výstupu informací obsažených v databázi. Jistě – je možné navrhovat všemožné formuláře, které budou zobrazovat údaje tak, jak si zrovna v daném okamžiku uživatel přeje, nicméně asi všichni cítíme, že to není úplně nejvhodnější řešení.

Výstupní sestavy (a jejich generátor) jsou naopak velmi přínosnou pomůckou. Jejich podstata tkví (jak v Delphi také jinak) v komponentách. Komponenty výstupních sestav (nazývaných „rychlé sestavy“, Quick Reports) se nalézají v paletě QReport. V této paletě se nachází celá řada komponent a my si v následujícím textu podrobněji popíšeme ty nejdůležitější. V závěru kapitoly se následně podíváme na několik oblíbených konkrétních postupů – tentokrát samozřejmě souvisejících s vytvářením rychlé sestavy.

Sestava vytvořená v Delphi z komponent popsaných níže je „poskládána“ z tzv. oddílů (Bands). Oddíly je možné přidávat už v době návrhu.

Poznámka: Pokud vás zajímá několik historických souvislostí, které bezprostředně nesouvisí s programováním a s vytvářením sestav, vězte, že 32bitová verze generátoru rychlých sestav Quick Reports se začala poprvé dodávat v rámci Delphi 2.0. V Delphi 3 došlo navíc ke zcela zásadní změně koncepce a k přepracování generátoru Quick Reports. Rychlé sestavy verze 1 (dodávané v Delphi 2.0) nejsou kompatibilní s rychlými sestavami verze 2 (šířené jako součást Delphi 3). Při otevření projektu nebo formuláře vygenerovaného v Delphi 2.0 ovšem dojde k automatické konverzi, po níž by již vše mělo fungovat správně.

Komponenta QuickRep

Tato komponenta je jednoznačně nejdůležitější ze všech komponent rychlých sestav. Pokud ji umístíte na formulář, automaticky se roztáhne na celou stránku.

Vlastnosti komponenty QuickRep

Pomocí vlastností komponenty QuickRep nastavujeme vzhled a parametry sestavy. Na některé vlastnosti se podíváme v následujících odstavcích, další už stručně shrne tabulka.

Bands

Pomocí vlastnosti Bands přidáváme / ubíráme ze sestavy jednotlivé oddíly. Typ vlastnosti Bands je TQuickRepBands a povolovat / zakazovat můžete následující „podvlastnosti“ (viz tab.):

„Podvlastnost“ Význam
HasColumnHeader Záhlaví sloupce: tiskne se nad každým sloupcem, má-li sestava více sloupců.
HasDetail Detail: tiskne se pro každý záznam (řádku) z datové množiny (Dataset, viz níže).
HasPageFooter Zápatí stránky: tiskne se v závěru každé stránky. K vytištění zápatí také na poslední straně sestavy se používá vlastnost Options.LastPageFooter.
HasPageHeader Záhlaví stránky: tiskne se v úvodu každé stránky. K vytištění záhlaví také na první straně sestavy se používá vlastnost Options.FirstPageHeader.
HasSummary Souhrn: tiskne se jednou v závěru sestavy (za všemi oddíly typu Detail). Typicky se používá k vytištění výsledku nebo souhrnné informace zjišťované v průběhu tvorby sestavy.
HasTitle Titulek: tiskne se jednou, a to na začátku sestavy. Chcete-li, aby se na první stránce sestavy vytiskl titulek místo záhlaví stránky, nastavte Options.FirstPageHeader na False.

Přidávání jednotlivých oddílů se v návrhové fázi provádí v Object Inspectoru. Po kliknutí na značku plus u vlastnosti Bands komponenty QuickRep se rozbalí seznam s oddíly. U oddílů, které chcete mít ve své sestavě, nastavte hodnotu True. Následující obrázek ukazuje vzhled Object Inspectoru, ve kterém jsme nastavili přítomnost titulku a souhrnu:

Klepněte pro větší obrázek

Všimněte si, že pokud umístíte na formulář komponentu QuickRep a začnete v Object Inspectoru přidávat jednotlivé oddíly, přidáváte vlastně do aplikace další komponenty. Například po přidání titulku (HasTitle = True) můžete v rozbalovacím seznamu v horní části Object Inspectoru najít komponentu (objekt) TitleBand1 typu TQRBand (viz níže).

Dataset

Datová množina. Nastavením této vlastnosti vlastně „propojujeme“ sestavu s komponentou typu Dataset (tedy s komponentou Query, Table, RemoteDataset nebo s jiným potomkem třídy TCustomDataset). Pokud vytváříme „obyčejnou“ sestavu (vzhledově podobnou seznamu), bude ve vlastnosti Dataset jediná použitá datová množina. V případě sestavy typu Master/Detail (pro jejíž popis bohužel nemáme dost prostoru) bude obsahem této vlastnosti hlavní datová množina (Master).

Description

Ve vlastnosti Description (která je typu TStrings) můžete uchovávat popis sestavy nebo libovolnou jinou informaci či komentář o sestavě. Tato vlastnost není používána vlastní komponentou QuickRep, nicméně s výhodou ji můžete používat v aplikaci k vypsání obsažených informací uživateli, který se hodlá na sestavu podívat.

Frame

Vlastnost Frame je použita k uchování informací o rámech, které chceme mít okolo oddílu nebo sestavy. Má následující „podvlastnosti“:

„Podvlastnost“ Význam
Color Barva rámu
DrawBottom Rám na spodní hraně sestavy
DrawLeft Rám na levé hraně sestavy
DrawRight Rám na pravé hraně sestavy
DrawTop Rám na horní hraně sestavy
Style Styl pera, přednastavená hodnota je psSolid, tedy plná čára.
Width Šířka rámu v pixelech

Function

Vlastnost Function slouží k uložení uživatelsky definovaných funkcí, proměnných a konstant.

Options

Vlastnost Options obsahuje několik „podvlastností“, příznaků, které umožní nastavit detaily vzhledu a „chování“ sestavy, viz následující tabulka:

„Podvlastnost“ Význam
FirstPageHeader Při hodnotě True se záhlaví stránky bude tisknout i na první stránce sestavy.
LastPageFooter Při hodnotě True se zápatí stránky bude tisknout i na poslední stránce sestavy.
Compression Při hodnotě True se sestava uloží v komprimovaném formátu, takže zabírá menší paměťový prostor, ale na druhou stranu její vytvoření trvá déle. Je tedy nutné zvolit větší velikost nebo pomalejší rychlost.

Další vlastnosti komponenty QuickRep

Další vlastnosti popíšeme již stručně v následující tabulce:

Vlastnost Význam
Page Slouží k uchování informací o vzhledu stránky sestavy, tedy údajů o velikosti papíru, okrajích, orientací stránky, počtu sloupců, apod.
PrinterSettings Uchovává několik parametrů specifických pro aktuální tiskárnu (např. počet tisknutých kopií, nastavení oboustranného tisku, apod.).
PrintIfEmpty Slouží k nastavení způsobu chování sestavy v případě, že zdrojová datová množina (Dataset) neobsahuje žádná data. Pokud je PrintIfEmpty = True, bude i v takovém případě vygenerována a vytištěna stránka (obsahující např. titulek, záhlaví, zápatí apod.). V opačném případě (PrintIfEmpty = False) nebude vůbec stránka generována.
ReportTitle Nastavení titulku sestavy. Tento titulek bude použit např. komponentou TQRSysData.
ShowProgress Zapíná / vypíná zobrazení dialogu ukazujícího průběh vytváření (tištění) sestavy.
Units Umožní nastavit délkové jednotky používané při práci se sestavou. Přednastavenou jednotkou jsou milimetry (MM).

Všechny zmíněné vlastnosti lze samozřejmě nastavovat v Object Inspectoru, nicméně některé můžete modifikovat také v dialogu Report Settings, který se otevře např. po poklepání na sestavu na formuláři. Zmíněný dialog je na následujícím obrázku:

Klepněte pro větší obrázek

Události komponenty QuickRep

Komponenta QuickRep nemá příliš mnoho událostí, ty přítomné jsou však poměrně zajímavé, viz následující tabulka:

Událost Význam
AfterPreview Vzniká, uzavře-li uživatel formulář s náhledem sestavy.
AfterPrint Vzniká po skončení tisku sestavy.
BeforePrint Vzniká předtím, než je sestava generována, takže je volána před operacemi tisku i náhledu (Preview). Tato metoda má výstupní parametr PrintReport typu Boolean, jehož zakázáním (PrintReport := False) lze zakázat generování sestavy.
OnEndPage Je vyvolána v okamžiku, kdy je aktuální stránka hotová, těsně předtím, než sestava přejde na novou stránku.
OnNeedData Událost vzniká v případě, že generujete sestavu z datové množiny (Dataset) jiného původu než z BDE. V takovém případě totiž musíme sami zajistit vyplnění textových hodnot komponent TQRLabel (viz níže) v sestavě.
OnStartPage Je vyvolána v okamžiku, kdy je generována nová stránka.

Metody komponenty QuickRep

Po popisu vlastností a událostí musí logicky následovat seznam nejdůležitějších metod komponenty QuickRep. Většinu metod se ovšem nedoporučuje volat (jde o interní procedury komponenty QuickRep a navíc činnosti těchto interních metod jdou vždy provést jiným způsobem, např. nastavením určité vlastnosti apod.). Proto se v následující tabulce zaměříme jen na několik málo metod, které jsou určeny pro „volné použití“:

Metoda Význam
Cancel Může být generována v průběhu generování sestavy. Generování bude zastaveno (stornováno), jak nejdříve to bude možné, a hodnota vlastnosti Cancelled bude nastavena na True.
Prepare Používá se v případě, že chcete vytvořit (generovat) sestavu bez následného tisknutí nebo prohlížení náhledu. Sestava je vytvořena a uložena v objektu QRPrinter a může být např. uložena na disk. Pokud takto vytvoříte sestavu, jste zodpovědní za uvolnění objektu QRPrinter z paměti, viz příklad pod tabulkou.
Preview Metoda způsobí vytvoření sestavy a zobrazení jejího náhledu. Z okna s náhledem je možné sestavu také vytisknout.
PreviewModal Náhled bude vytvořen bez použití vlákna běžícího na pozadí. U některých typů databázových ovladačů nemusí být použití vláken příliš bezpečné, může zapříčinit nepředvídatelné chování nebo chyby. V takovém případě je vhodnější použít metodu PreviewModal. Provádění programu pokračuje po uzavření okna s náhledem.
PreviewModeless Provádění programu pokračuje bezprostředně po zavolání metody, sestava je generována ve vlákně na pozadí a v průběhu jejího generování pokračuje běh programu.
Print Vytiskne sestavu na tiskárnu definovanou v poli PrinterSetup.PrinterIndex (nebo na „default“ tiskárnu, pokud PrinterSetup.PrinterIndex = -1).
PrinterSetup Zobrazí dialog pro nastavení vlastností tisku.
ResetPageFooterSize Tato metoda by měla být volána, pokud změníte výšku zápatí stránky v průběhu vytváření sestavy.

Příklad – metoda Prepare: begin
  MyReport.Prepare;
  try
      MyReport.QRPrinter.Save(`MyReport.qrp`);
  finally
      MyReport.QRPrinter.Free;
  end;
  MyReport.QRPrinter := nil;
end;

Jak jsme si řekli, komponenta QuickRep je sice nejdůležitější komponentou rychlých výstupních sestav, ovšem (možná trochu paradoxně) sama o sobě nám k vytvoření sestavy rozhodně nepostačí. Nyní se pojďme podívat na další komponenty, které spolupracují s komponentou QuickRep.

Komponenta QRBand

Každá vytvářená sestava obsahuje alespoň jednu komponentu QRBand (typu TQRBand). Tyto komponenty totiž představují oddíly tak, jak jsme si je rozdělili a popsali v předchozí podkapitole. Jak již bylo řečeno, přidáním oddílu do komponenty QuickRep dojde vlastně k přidání komponenty QRBand. Oddíl jako takový sám o sobě ještě nic nezobrazuje (žádná data)! Abychom na sestavě měli nějaké údaje, musíme na ni vložit ještě další komponenty. Tyto komponenty však umísťujeme na jednotlivé oddíly a tím vlastně definujeme, kde, kdy a kolikrát chceme data (zobrazená v těchto ostatních komponentách, nikoliv ve vlastních oddílech) tisknout.

Vlastnosti komponenty QRBand

BandType

Nejdůležitější vlastnosti komponenty QRBand je BandType, tedy typ oddílu zastupovaného komponentou QRBand. Možné typy oddílu shrne následující tabulka (všimněte si částečné podobnosti s tabulkou popisující možné hodnoty vlastnosti Bands komponenty QuickRep, proto v následující tabulce popíšeme jen rozdíly):

Hodnota Význam
rbChild Oddíl typu Child je „propojen“ s jiným oddílem. Tento typ by však neměl být ručně nastavován.
rbColumnHeader Záhlaví sloupce
rbDetail Detail
rbGroupFooter Zápatí skupiny: v sestavách typu Master / Detail se tiskne vždy po vytištění celé skupiny (posledního ze seskupených údajů).
rbGroupHeader Záhlavní skupiny: v sestavách typu Master / Detail se tiskne vždy před vytištěním celé skupiny (prvního ze seskupených údajů).
rbOverlay Je přítomen jen kvůli zpětné kompatibilitě, nepoužívejte jej.
rbPageFooter Zápatí stránky
rbPageHeader Záhlaví stránky
rbSubDetail Část detailů v sestavě Master / Detail. Tento typ by však neměl být ručně nastavován.
rbSummary Souhrn
rbTitle Titulek

ForceNewColumn

Nastavení této vlastnosti na True znamená, že před vytištěním tohoto oddílu bude vytvořen nový sloupec, tedy že tento oddíl bude vždy začínat na počátku nového sloupce.

ForceNewPage

Nastavení této vlastnosti na True znamená, že před vytištěním tohoto oddílu bude vytvořena nová stránka, tedy že tento oddíl bude vždy začínat na počátku nové stránky).

LinkBand

Do této vlastnosti můžete zadat oddíl, který chcete vždy a za všech okolností tisknout společně s aktuálním oddílem (tj. s oddílem, jehož vlastnost LinkBand právě nastavujete). Toto nastavení může být i „řetězové“ – tedy oddíl 1 bude svázán s oddílem 2, ten s oddílem 3 apod.

Pokud se všechny svázané oddíly na stránku nevejdou, dojde k přechodu na novou stránku a tisk bude pokračovat tam.

Události komponenty QRBand

Oddíl má pouze dvě události: BeforePrint a AfterPrint. První jmenovaná je vyvolána před tím, než se oddíl bude tisknout. V obsluze této události samozřejmě můžeme tisku zabránit, a to nastavením výstupního parametru PrintBand na False.

Komponenta QRLabel

Komponenta QRLabel (typu TQRLabel) je velmi podobná komponentě Label (tedy „obyčejnému“ nápisu). Slouží k zobrazení statického textu v sestavě. Tento text je uchováván ve vlastnosti Caption. Statickým textem se zde myslí text, který nevychází z žádného datového pole v databázi. Zmíněný statický text je samozřejmě možné za běhu programu měnit a komponenta QRLabel disponuje událostí OnPrint, která je generována těsně před případným tiskem údaje obsaženého ve vlastnosti Caption. V obsluze této události je možné změnit tištěný text (nastavením výstupního parametru Value). Tato změna se projeví při tisku, ale neprojeví se v hodnotě vlastnosti Caption, které zůstane její původní hodnota.

Komponenta QRDBText

Komponenta QRDBText je již sofistikovanější komponenta sloužící k zobrazení informací, které vycházejí z některého databázového datového pole. Slouží k zobrazení jakýchkoliv textových polí s výjimkou polí formátovaných jako Rich Text Format.

V komponentě QRDBText tedy můžeme zobrazovat alfanumerická pole, pole s čísly v plovoucí řádové čárce, pole obsahující datum a čas (a samozřejmě pole obsahující čistý text).

Aby komponenta zobrazovala údaje, které chceme, jednoduše nastavíme její vlastnosti DataSet (datová množina) a DataField (datové pole).

Vlastnosti komponenty QRDBText

AutoSize

Vlastnost Autosize udává, bude-li se komponenta horizontálně „rozšiřovat“ podle délky zobrazovaného textu. Pokud bude zobrazovaným polem poznámka (Memo), která bude obsahovat více řádků, dojde k rozšíření podle nejdelší přítomné řádky.

AutoStretch

AutoStretch udává, jak se bude komponenta chovat v případě, že zobrazovaný text se nevejde do vertikálního rozměru komponenty. Pokud je AutoStretch povolena (True), roztáhne se komponenta QRDBText ve svislém směru, aby se do ní vešel celý zobrazovaný text.

Pokud zobrazujeme jediný řádek textu a hodnota předchozí vlastnosti (AutoSize) = True, nebude řádka nikdy vertikálně rozšířena, ani přes nastavení AutoStretch = True.

Konkrétní rozměr (délka) rozšíření závisí také na nastavení vlastnosti WordWrap.

Komponenta QRExpr

Komponenta QRExpr (typu TQRExpr) slouží k vyhodnocování výrazů v průběhu vytváření sestavy. Výraz, který chceme vyhodnotit (výpočet, který chceme provést), zapíšeme do vlastnosti Expression. Klepneme-li v Object Inspectoru na tlačítko se třemi tečkami vedle vlastnosti Expression, otevře se dialog Expression Wizard, který vidíte na následujícím obrázku a který vám pomůže s vytvořením výrazu:

Klepněte pro větší obrázek

Další komponenty pro tvorbu sestav

V žádném případě jsme zatím nepopsali všechny myslitelné komponenty pro tvorbu rychlých výstupních sestav. Myslím ale, že to není již nezbytně nutné; s mnohými dalšími komponentami se pracuje analogicky jako s těmi zmíněnými a některé další jsou zbytečně komplikované a přesahují rámec tohoto seriálu.

Proto si několik dalších komponent pouze stručně představíme. Komponenta QRSysData slouží k zobrazení informací o sestavě a dalších systémových informací při tisku sestavy. Komponenta QRMemo zobrazuje víceřádkové údaje (svázané s některým datovým polem). Komponenta QRRichText dělá totéž, ale s daty ve formátu RTF (Rich Text Format). Tato komponenta není nijak svázána s datovými položkami, na rozdíl od komponenty QRDBRichText. Pomocí komponenty QRShape je možné vykreslit jednoduchý útvar (kružnici, obdélník, apod.). Potřebujeme-li zobrazit v sestavě obrázek, použijeme nejsnáze komponentu QRImage, pokud navíc tyto obrázky chceme brát z databáze, poslouží QRDBImage. Nakonec komponenta QRPreview: slouží k vytvoření uživatelsky definované obrazovky náhledu.

Příště pokračujeme

Zdá-li se vám, že v dnešním díle nebyly žádné praktické příkládky, že šlo jen o suché teoretické člení, máte svým způsobem pravdu. Protože ale ukázky, příklady a postupy, jak dosáhnout toho či onoho, jsou podle vašich ohlasů poměrně oblíbené, jistě bych si je bez uzardění netroufl jen tak opominout. Můžete se tedy těšit na příští týden, protože následující díl seriálu bude naplněn pouze a jen praktickými radami, jak výstupní sestavu v Delphi vytvořit. Seznámíme se s třemi postupy vedoucími k vytvoření sestavy – pomocí šablony, průvodce a „ručně“.
Diskuze (3) Další článek: PC kdekoli: podesáté

Témata článku: Software, Programování, Sestavy, Podobný dialog, Předchozí odstavec, RBC, RBD, TV +, Tvorba, Komponenta, Pole, Význam, Cancel, Přednastavená hodnota, Statický text, Paměťový prostor, Tvor, Výstup, Textové pole, Nepředvídatelné chování, Nová metoda, Quick, SES, DEL, Zobrazená data


Určitě si přečtěte


Aktuální číslo časopisu Computer

Megatest: nejlepší notebooky do 20 000 Kč

Test 8 levných IP kamer

Jak vybrat bezdrátová sluchátka

Testujeme Android 11