ďťż
WAĹťNE INFORMACJE
Wprowadzenie do Rave Reports

I) Rave Reports - raporty na bazie kodu

Autor - Leonel Togniolli

Rave Reports stały się w Delphi 7 domyślnym rozwiązaniem raportowania, zastępując Quick Reports. Ponieważ ich sposób pracy jest całkowicie odmienny, wielu użytkowników czuło się zagubionych w nowym środowisku. Niniejsze opracowanie stanowi wprowadzenie dla użytkowników, którzy nie mieli jeszcze do czynienia z Rave Reports, a chcieliby zacząć ich używać.

Raporty Rave można tworzyć na dwa różne sposoby: wprost z kodu (Code Based) lub za pomocą narzędzia Visual Designer. Niniejszy dokument opisuje obydwa sposoby pracy zarówno: bazując na kodzie oraz korzystając z Visual Designer'a'.

Raporty na bazie kodu

Pracując z modułem Code Based, tworzysz raporty z wykorzystaniem czystego kodu Delphi. Zapewnia to bardzo elastyczny sposób prezentacji wszelkiego rodzaju danych, umożliwiając jednocześnie zastosowanie dowolnego rodzaju złożonego układu (layout). Aby utworzyć raport na bazie kodu, po prostu upuść komponent TRvSystem na formularz i napisz raport za pomocą programu obsługi zdarzeń OnPrint. Parametr Sender wskazuje na raport, który właśnie tworzysz; może być użyty jako obiekt klasy TBaseReport. Zawiera on wszystkie metody, których możesz potrzebować, by przesłać informacje do tego konkretnego raportu.

Poniżej przykład prostego raportu z użyciem mechanizmu bazującego na kodzie:

 procedure  TFormMain.RvSystemPrint(Sender: TObject);
 begin 
   with  Sender  as  TBaseReport  do 
  begin
    SetFont('Arial', 15);
    GotoXY(1,1);
    Print('Welcome to Code Based Reporting in Rave');
   end; 
 end; 
				

Aby wygenerować tak zdefiniowany raport, należy wywołać metodę RvSystem Execute. Zobaczmy, jakie działania są efektem działania tego prostego kodu. Po pierwsze, polecenie SetFont określa typ i wielkość czcionki, jaka będzie stosowana od tej chwili w wydrukach. Następnie, kursor jest umieszczany w punkcie o współrzędnych (1,1). Współrzędne te wyrażone są w jednostkach określonych we właściwościach SystemPrinter.Units obiektu RvSystem, zaś domyślną jednostką są cale. W unUser można określić jednostkę, zaś w SystemPrinter.UnitsFactor można wprowadzić odpowiednie wartości wyrażone w calach. Dla przykładu, gdy wartość UnitsFactor była ustawiona na 0,5, wówczas 1 jednostka odpowiada 0,5 cala. Na koniec, kod określa, że postacią wyjściową tekstu będzie wydruk.

Oto wynik:

Tabularyczne raporty na bazie kodu. Poniżej inny przykład: Efektem działania kodu jest lista folderów w katalogu głównym bieżącego napędu, w kolejności malejącej, wraz z informacją o całkowitej wielkości plików zawartych w każdym folderze.

 procedure  TFormMain.PrintTabularReport(Report: TBaseReport); 

 var 
  FolderList : TStringList;
  i          : Integer;
  NumFiles   : Cardinal;
  NumFolders : Cardinal;
  SizeFiles  : Cardinal;
  Root       :  string ;
 begin 
   with  Report  do 
   begin 
    SetFont('Arial', 15);
    NewLine;
    PrintCenter('List of Folders in the Drive Root', 4);
    NewLine;
    NewLine;
    ClearTabs;
    SetTab(0.2, pjLeft, 1.7, 0, 0, 0);
    SetTab(1.7, pjRight, 3.1, 0, 0, 0);
    SetTab(3.1, pjRight, 3.5, 0, 0, 0);
    SetTab(3.5, pjRight, 4.5, 0, 0, 0);
    SetFont('Arial', 10);
    Bold := True;
    PrintTab('Folder Name');
    PrintTab('Number of Files');
    PrintTab('Number of Folders');
    PrintTab('Size of Files');
    Bold := False;
    NewLine;
    FolderList := TStringList.Create;
     try 
      Root := IncludeTrailingPathDelimiter(ExtractFileDrive(ParamStr(0)));
      EnumFolders(FolderList, Root);
       for  i := 0 to FolderList.Count - 1  do 
       begin 
        PrintTab(FolderList[i]);
        GetFolderInfo(IncludeTrailingPathDelimiter(Root+FolderList[i]),
          NumFiles, NumFolders, SizeFiles);
        PrintTab(Format('%u',[NumFiles]));
        PrintTab(Format('%u',[NumFolders]));
        PrintTab(Format('%u bytes',[SizeFiles]));
        NewLine;
       end ;
     finally 
      FolderList.Free;
     end ;
   end ;
 end ;
				

Zauważ, że zastosowano inne podejście: zamiast specyfikować koordynaty każdego elementu wydruku, posłużono się liniami i kolumnami jako wielkościami odniesienia. Wysokość linii zależy od wielkości użytej czcionki: każda jednostka to 1/72 cala, a więc linia drukowana czcionką o rozmiarze 10 będzie miała wysokość około 0,138 cala. Przeskok do kolejnej linii następuje po komendzie PrintLn lub NewLine. Kolumny są zdefiniowane przez odwołania do metody SetTabs, a metoda PrintTab powoduje drukowanie tekstu w bieżącej kolumnie z przeskokiem do następnej. Oto wynik:

Pełen kod źródłowy, wraz z wdrożeniem EnumFolders i GetFolderInfo, możesz znaleźć w CodeCentral (ID: 20535, Rave Reports Code Based Examples). Graficzne raporty na bazie kodu

W graficznych raportach na bazie kodu można umieszczać oprócz tekstu również grafiki i obrazki. Ilustruje to poniższy przykład:

 procedure  TFormMain.PrintGraphicsReport(Report: TBaseReport); 

 var 
  Bitmap : TBitmap;
 begin 
   with  Report  do 
   begin 
    Canvas.Brush.Color := clGray;
    Rectangle(0.3, 0.3, 4.7, 3.3);
    SetFont('Arial', 15);
    FontColor := clRed;
    PrintXY(0.5,0.5, 'Just look at all the graphics!');
    Bitmap := TBitmap.Create;
     try 
      Bitmap.LoadFromFile('delphi.bmp');
      PrintBitmap(3.5,0.3,1,1, Bitmap);
      PrintBitmap(1,2,3,3, Bitmap);
      Canvas.Pen.Color := clBlue;
      Canvas.Brush.Bitmap := Bitmap;
      Ellipse(5,0.3,6,3.3);
      Ellipse(2,1,4,1.9);
     finally 
      Bitmap.Free;
     end ;
    Canvas.Pen.Color := clBlack;
    Canvas.Brush.Style := bsSolid;
    Canvas.Brush.Color := clYellow;
    Pie(0.7,0.7,1.7,1.7,1,1,1,2);
    Canvas.Brush.Color := clGreen;
    Pie(0.7,0.7,1.7,1.7,1,2,1,1);
   end ;
 end ;
				

W tym przykładzie posłużono się metodami Rectangle, Ellipse oraz Pie, by wstawić rysunki o różnych wypełnieniach. Rysunki rastrowe uzyskano za pomocą PrintBitmap, jako wypełnienie elips. Oto wynik:

Prosta aplikacja, zawierająca pełen kod źródłowy dla tych trzech przykładów, jest do pobrania w CodeCentral (ID: 20535, Rave Reports Code Based Examples).

Podsumowanie

Jak widać, raporty bazujące na kodzie oferują dużą elastyczność i możliwość kontrolowania ich formy graficznej, lecz wymagają pewnego nakładu pracy. W części II powiemy, jak wykorzystać narzędzie Visual Designer do tworzenia efektownych raportów w bardzo prosty sposób.

II) Rave Reports - Projektant raportów

Visual Designer

Jeżeli używałeś wcześniej Quick Reports, domyślnego narzędzia raportowania wcześniejszych wersji Delphi, tworzyłeś raporty z wykorzystaniem własnego kreatora formularzy Delphi. Raporty były zapisywane w DFM, stanowiąc zasoby plików wykonywalnych. Sposób działania Rave Reports jest w tym względzie nieco inny. Dysponują one własnym kreatorem raportów i zapisują je z wykorzystaniem własnego formatu plików. Ma to pewne zalety. Raporty są "autonomiczne", to znaczy, że mogą być wykorzystywane lub uaktualniane niezależnie od aplikacji, a nawet mogą być udostępniane w intranecie lub Internecie za pomocą Nevrona Rave Report Server. Oczywiście, nadal można je zapisać w DFM formularza.

Aby rozpocząć pracę z Rave Visual Designer, upuść TRvProject na formularz. W ten sposób utworzysz łącze (link) między aplikacją a raportami, które opracowujesz. Jeżeli chcesz, możesz dodać TRvSystem i łącze między nim a RvProject, posługując się właściwościami Engine.

RvSystem to obiekt odpowiedzialny za ogólną konfigurację raportów - decyduje, która drukarka ma być użyta, określa marginesy, liczbę stron i tak dalej. Aby rozpocząć nowy projekt, kliknij podwójnie RvProject dodany wcześniej do formularza, lub zaznacz "Rave Visual Designer" w jego menu kontekstowym. Poniżej widok interfejsu, w którym będziesz kontynuować pracę:

Interfejs jest nieskomplikowany, a niektóre jego elementy mogą być ci znane ze zintegrowanego środowiska programowania Delphi. U góry widzisz menu, pasek narzędzi i paletę składników (Component Pallete), która zawiera komponenty stosowane w raportach. Po lewej stronie znajduje się inspektor obiektów (Object Inspector), który służy do uzgodnienia właściwości komponentów raportu. Pośrodku znajduje się Page Designer modułu Event Editor, a po lewej stronie jest bardzo przydatny widok drzewa projektu (Project Treeview). Szybki przegląd komponentów palety uzyskasz przechodząc na stronę Nevrona Nevrona Home Page - Visual Designer.

Plik Rave Project File może zawierać jeden lub więcej raportów. W ten sposób ich wspólne elementy mogą znajdować się w jednej lokalizacji, nazywanej Global Pages. Gdy rozwiniesz węzeł Report Library widoku drzewa projektu, zobaczysz, że aktualnie pracujesz nad raportem nr 1 (Report1). Klikając jego ikonę, spowodujesz wyświetlenie właściwości w oknie inspektora obiektów. Zmień jego nazwę na SimpleReport. Następnie przejdź na kartę Standard palety składników, wybierz składnik Text i dodaj go do strony. Zmień właściwości tekstu i dostosuj rozmiar oraz położenie. Może to wyglądać na przykład tak:

Jak na pewno zauważysz, zmienione właściwości, inne niż domyślne, wyróżnione są pogrubioną czcionką. W tym przypadku zostały zmienione właściwości czcionki, tekstu i zaokrąglania. Domyślnie nie są wyświetlane zmiany właściwości Name, Pos i Size. Jeśli jednak chciałbyś je widzieć, kliknij prawym klawiszem myszy inspektora obiektów i odznacz pole "Exclude Name, Size and Pos changes" w menu kontekstowym.

Być może zauważyłeś również, że Rave nie ma właściwości "auto size". Możesz skorzystać z właściwości zaokrąglania (Truncate), by uzyskać ten efekt - gdy wartość Truncate jest false, tekst zostanie wydrukowany w całości niezależnie od szerokości (Width) ustawionej w czasie projektowania.

Możesz obejrzeć ten prosty raport bezpośrednio w module Designer - naciśnij klawisz F9 lub skorzystaj z menu File/Execute Report . Teraz zróbmy to w naszej aplikacji. Zapisz projekt i powróć do Delphi. Przejdź do właściwości ProjectFile projektu RvProjekt, by odnaleźć właśnie zapisany plik. Aby uruchomić raport, dodaj wywołanie do Execute method obiektu RvProject, na przykład klikając przycisk.

RvProject Execute zadziała w tej chwili tylko dlatego, że mamy tylko jeden raport w tym projekcie. Gdyby raportów było więcej, należałoby najpierw wywołać SelectReport, aby wybrać raport przed uruchomieniem Execute, lub wywołać ExecuteReport bezpośrednio w odniesieniu do konkretnego raportu. Oto wynik:

Wskazówka: jeżeli zamkniesz i otworzysz (Close/Open) projekt przed jego uruchomieniem, nie będziesz musiał rekompilować lub ponownie uruchamiać aplikacji, by przejrzeć wprowadzone zmiany.

Interakcja z projektem

Jeżeli wcześniej pracowałeś z Quick Reports, możesz być przyzwyczajony do manipulowania obiektami w czasie rzeczywistym - zmiana pozycji, tekstu i widoczności (Position, Text i Visibility). W końcu, były to po prostu TObjects! Jest to możliwe również w Rave Reports i omówię ten problem w jednym z przyszłych artykułów. Niemniej, jest to trochę trudniejsze, niż w przypadku Quick Reports. Nie ma jednak powodów do niepokoju - Rave dostarcza innego rozwiązania tego problemu.

Parametry

W swoich raportach możesz korzystać z parametrów. Możesz je zdefiniować korzystając z właściwości parametrów projektu, raportu lub strony. Parametry można zdefiniować w dowolnie wybranym z tych miejsc; jest ich więcej po prostu dla łatwiejszego dostępu.

Projekt i raport możesz wybrać jedynie posługując się widokiem drzewa projektu. Natomiast stronę możesz wybrać albo z widoku drzewa projektu, albo klikając jej tytuł nad kreatorem strony.

Jedną z możliwości wykorzystania parametrów jest ich wydruk. I tak na przykład, jeżeli tytuł raportu ma być zdefiniowany przez użytkownika, możesz przenieść go z aplikacji do raportu jako parametr.

Dodajmy nowy raport do projektu, by zobaczyć, jak działają parametry. Aby to zrobić, kliknij czwarty przycisk na pasku narzędzi lub posłuż się menu File/New Report. Nazwij go ParametrizedReport, zmieniając nazwę za pomocą inspektora obiektów. Ten raport będzie bardzo podobny do pierwszego, z wyjątkiem tego, że tekst będzie zdefiniowany przez użytkownika.

Teraz trzeba zdefiniować parametry, które będą drukowane. Aby to zrobić, wciąż mając raport jako wybrany obiekt, otwórz edytor właściwości i przejdź do właściwości Parameters. Powinieneś zobaczyć listę wszystkich parametrów raportu (jeszcze żadnego nie ma, więc lista jest pusta), każdy w oddzielnym wierszu. Dodaj parametr o nazwie Name, jak poniżej:

Parametry można wydrukować za pomocą komponentu DataText, dostępnego na karcie Report palety składników. Dodaj DataText do strony i w edytorze właściwości przejdź do właściwości DataField. Możesz tam zdecydować, które pole ma być drukowane podczas pracy z raportami DataAware (co zostanie omówione w trzeciej części niniejszego cyklu). Możesz tam również wybrać Project Variables, Parameters i Post-Initialize Variables (zmienne projektu, parametry i zmienne po inicjalizacji).

Tak więc wybierz parametr dodany wcześniej z listy rozwijanej Parameters i kliknij przycisk Insert Parameter. Nazwa parametru ma teraz postać Param.Name (zmienimy ją nieco później). Kliknij OK i spróbuj wykonać raport, jak poprzednio. Nic się nie wydrukowało, ponieważ nie został określony parametr.

Trzeba go określić przed drukowaniem. Nie zapomnij zapisać zmian i powróć do Delphi, dodając wywołanie SelectReport przed Execute, by można było zobaczyć właściwy raport. Przed wykonaniem trzeba jednak ustawić wybrany parametr. Służy do tego metoda SetParam modułu RvProject. A tak wygląda odpowiedni kod:

 procedure  TFormMain.btnExecuteClick(Sender: TObject);
 begin 
  RvProject.Open;
  RvProject.SelectReport('ParametrizedReport',False);
  RvProject.SetParam('Name','Leonel');
  RvProject.Execute;
  RvProject.Close;
 end ;
				

Obecnie w trakcie wykonywania raportu można zobaczyć utworzony ciąg (string) jako drukowany parametr.

Wskazówka: możesz posłużyć się poleceniem RvProject.GetReportList, by uzyskać listę dostępnych projektów i dodać ją na przykład do ComboBox lub RadioGroup. Ułatwia to wybór raportów.

Ale to zbyt proste. Zmieńmy wyrażenie, które ma być drukowane. Wróć do Rave Designer i w edytorze właściwości przejdź do właściwości dodanego wcześniej DataText. Możesz dodać dowolny tekst według swobodnego wyboru, łącząc tekst, pola, parametry i zmienne. Zmieńmy to tak:

Oto wynik:

Zmienne po inicjalizacji (Post-Initialize Variables)

Zmienne po inicjalizacji, lub krótko PI Vars, to zmienne, których wartość staje się znana dopiero po wydrukowaniu raportu. Może to zabrzmieć dziwnie, ale pomyśl choćby o liczbie stron raportu - na przykład. Poznasz ją dopiero, gdy wydrukujesz raport. W rzeczywistości TotalPages to zmienna raportu, która zachowuje się jak PI var i może być bez problemu drukowana za pomocą DataTexts, podobnie jak to robiliśmy w przypadku Parameters.

Global Pages

Gdy pewne części raportów są wspólne dla dwóch lub więcej raportów, możesz je umieścić w "global pages". Wyobraźmy sobie, że mamy nagłówek raportu z nazwą firmy, datą i godziną wydruku raportu, numerem bieżącej strony i liczbą stron raportu ogółem. Chcielibyśmy, aby nagłówek znalazł się w każdym raporcie. Jak to zrobić?

Po pierwsze, dodaj do projektu "global page", posługując się menu File/New Global Page, lub skrótem na pasku zadań. Na tej stronie dodaj komponent "sekcja" (section), dostępny na karcie Standard palety składników.

Sekcje to logiczne grupy komponentów. Można ich używać do grupowania komponentów w celu ich łatwego przemieszczania w obrębie raportu, lub jako zasobnik bliźniaczych kopii (Mirrors). Obecnie skorzystamy właśnie z tej ostatniej możliwości.

Dodaj w tej sekcji to, co chcesz, by zostało wydrukowane. W tym przypadku musi to być nieco DataTexts. Nasz przykładowy nagłówek wygląda tak:

Wskazówka: zamiast zmieniać właściwości czcionki wielu elementów nagłówka na te same, powiąż je ze składnikiem FontMaster, dostępnym na karcie Standard palety składników i tam ustaw właściwości czcionki. W ten sposób łatwiej będzie zmienić właściwości czcionki w przyszłości, gdy zajdzie taka potrzeba.

Teraz dodajmy kolejną sekcję do strony 1 SimpleReport. Włącz właściwości Mirror dla GlobalPage1.Section1. Zobaczysz kopię nagłówka, utworzonego na stronie "gobal page". Zrób to samo dla ParametrizedReport. Teraz oba raporty mają taki sam nagłówek. W naszym przykładzie wygląda to tak:

Druk warunkowy (Conditional Printing)

Czasami zachodzi potrzeba wydrukowania tylko części raportu, zależnie od warunków. Rave dysponuje bardzo skutecznym rozwiązaniem w tym zakresie. Można warunkowo tworzyć lustrzane kopie sekcji, posługując się wartościami pól lub parametrami. Utwórzmy nowy raport i nazwijmy go ConditionalReport.

Załóżmy przez chwilę, że nowy raport to sztuczka. Użytkownik może wybrać nagłówek, który ma być drukowany, spośród dwóch różnych typów nagłówka. Może też zdecydować, że raport będzie drukowany bez nagłówka. Posłużymy się parametrem, by określić, jaki rodzaj nagłówka ma się znaleźć w raporcie. DataMirrorSection dokona wyboru właściwego nagłówka w czasie rzeczywistym (w trakcie wykonywania).

Po pierwsze, dodaj do nowego raportu parametr o nazwie HeaderKind. Załóżmy, że będzie on miał wartości H0 (bez nagłówka), H1 (dla pierwszego nagłówka) i H2 (dla drugiego rodzaju nagłówka). Teraz do "gobal page" dodaj nową sekcję (możesz posłużyć się w tym celu widokiem drzewa projektu) z drugim rodzajem nagłówka. Niech to będzie nagłówek podobny do pierwszego, z inną czcionką i ramką wokół wartości. Nasz przykładowy nagłówek wygląda tak:

Teraz wróć do Page1 raportu ConditionalReport i dodaj DataMirrorSection, dostępną na karcie Report palety składników. Przejdź do edytora właściwości DataField i ustaw Param.HeaderKind jako wyrażenie. Teraz przejdź do edytora właściwości DataMirrors i dodaj dwa DataMirrors: gdy wartość wynosi H1, wybrany zostanie pierwszy nagłówek, zaś wartość H2 spowoduje wybór drugiego nagłówka. Ponieważ do H0 nic nie jest przypisane, wybór H0 nie spowoduje druku nagłówka. Przykład wygląda tak:

Zauważ, że każda z sekcji została wcześniej nazwana w sposób umożliwiający rozróżnienie. Wskazówka: możesz posłużyć się zdarzeniem OnMirrorValue z DataMirrorSection, by pracować z wieloma wartościami.

Teraz wróć do Delphi i dodaj kod, by ustawić parametry zgodnie z wyborem użytkownika. Jeżeli dodasz ComboBox z opcjami, kod będzie wyglądał tak:

 procedure  TFormMain.btnExecuteClick(Sender: TObject);
 begin 
  RvProject.Open;
  RvProject.SelectReport(cmbReports.Text,False);
   case  cmbReports.ItemIndex  of 
   1: RvProject.SetParam('Name',edName.Text);
   2: RvProject.SetParam('HeaderKind',Format('H%d',[cmbHeaderKind.ItemIndex]));
   end ;
  RvProject.Execute;
  RvProject.Close;
 end ;
				

Teraz będzie drukowany właściwy nagłówek, zgodnie z wyborem użytkownika.

Zagnieżdżanie projektu w "executable"

Gdy używasz aplikacji, musi ona zawierać twój plik projektu. Możesz przechowywać go jako oddzielny plik, co ułatwia jego aktualizację - wystarczy zamienić plik, nie ma potrzeby rekompilacji aplikacji albo włączyć go do pliku wykonywalnego (exe). To łatwe - otwórz edytor właściwości StoreRAV we właściwościach RvProject. Możesz teraz kliknąć Load, by dołączyć plik do DFM, Save - by rozpakować wcześniej zapisany plik, lub Clear, by usunąć zagnieżdżony plik. Gdy plik jest zawarty w dfm, nie musisz go oddzielnie wysyłać.

Podsumowanie

Przedstawiliśmy sposób pracy z narzędziem Visual Designer oraz kilka trików, które umożliwiają elastyczne tworzenie raportów. Projekt zawierający utworzone tu przykładowe raporty możesz znaleźć w CodeCentral. W trzeciej części nauczymy się tworzyć raporty DataAware i posługiwać się komponentami Band.

III) Rave Reports - Raporty Data Aware

W poprzednich częściach wyjaśniłem, jak korzystać z mechanizmu Code Based oraz Visual Designera. W tym dokumencie zbadamy funkcje inteligentnej analizy danych w Rave Reports.

Połączenie z bazą danych

Istnieją dwa sposoby uzyskiwania dostępu do danych z poziomu raportu: można wykorzystać połączenie nawiązane przez aplikację i pobierać rekordy z zestawów danych istniejących na formularzach lub w modułach danych, albo skonfigurować nowe połączenie w raporcie, dzięki czemu będzie on niezależny od konkretnej aplikacji. Pierwsza metoda wykorzystuje widok Direct Data View, a druga - Driver Data View. W raporcie widok danych działa podobnie do kombinacji DataSource/DataSet.

Jeśli zamierzasz wdrożyć aplikację z wykorzystanie Rave Report Server firmy Nevrona, powinieneś używać widoków Driver Data View.

Widok Driver Data View

Utwórzmy prosty raport bazy danych z wykorzystaniem widoku Driver Data View. Uruchom Rave Visual Designer i rozpocznij nowy projekt. W tym celu wybierz z menu polecenie File/New Database Object albo kliknij szósty przycisk na pasku narzędzi (fioletowy sześcian). Ukaże się okno dialogowe Data Connections:

Wybierz pozycję Database Connection; pojawi się pytanie, którego łącza danych (Data Link) zamierzasz użyć. W katalogu instalacyjnym Rave znajduje się folder o nazwie DataLinks, który zawiera kilka plików z rozszerzeniem .rvd odpowiedzialnych za mechanizm połączenia. Domyślnie możesz wybrać spomiędzy połączeń BDE, DbExpress i ADO. W tym przykładzie użyję połączenia BDE. Wybierz opcję BDE i kliknij przycisk Finish; pojawi się okno Database Connection Parameters. Każde łącze danych ma własny zbiór parametrów połączenia, podobnych do tych dostępnych w środowisku IDE Delphi. Na razie po prostu ustaw opcję Alias na DbDemos i kliknij przycisk OK. Zwróć uwagę, że do drzewa projektu, pod nagłówkiem Data View Dictionary, został dodany obiekt bazy danych:

Zauważ, że ustawienia skonfigurowane w oknie Database Connection Parameters - w tym nazwa użytkownika i hasło, jeśli są potrzebne - zostały zapisane we właściwości AuthDesign komponentu Database. We właściwości AuthRun możesz podać inne ustawienia, które będą używane w czasie wykonania, kiedy raport zostanie wdrożony.

Teraz utworzymy widok Driver Data View. Kliknij przycisk Data Object, a następnie wybierz pozycję Driver Data View. Następnie należy wybrać połączenie z bazą danych, z którego będzie korzystał ten widok danych; wybierz obiekt Database utworzony w poprzednim etapie. Pojawi się okno Query Avanced Designer. Przeciągnij i upuść tabelę customer.db z listy tabel do okienka Layout. Powinno ono wyglądać tak:

Jeśli masz więcej niż jedną tabelę, powinieneś wskazać, poprzez przeciąganie, pola, które powinny zostać złączone między tabelami. Jeśli klikniesz przycisk Editor, będziesz mógł sprawdzić wygenerowany kod SQL albo wpisać ręcznie bardziej zaawansowaną kwerendę. Na razie posłużmy się prostą listą klientów. Kliknij przycisk OK, a komponent DriverDataView zostanie dostany do drzewa projektu, pod komponentami Database. Jego elementami podrzędnymi będą wybrane pola tabeli:

Zauważ, że połączeniu z bazą danych i widokowi danych nadałem bardziej opisowe nazwy. Właśnie w drzewie projektu należy ustawiać właściwości pól, takie jak Display Label (właściwość FullName) oraz DisplayFormat.

Regiony i pasma

Komponenty raportu, które powinny być drukowane w niezmiennym położeniu na każdej stronie (takie jak stałe nagłówki i stopki), można umieścić bezpośrednio na stronie. Komponenty, których położenie zależy od poprzednio wydrukowanych elementów, należy umieścić w pasmach (ang. bands). Pasma DataBands będą drukowane po jednym razie na każdy rekord w dołączonym widoku danych, natomiast zwykłe pasma Bands będą drukowane tylko raz, bez względu na to, ile rekordów wybrano. Oba rodzaje pasm mogą zawierać komponenty Data-Aware (takie jak DataText) albo zwykłe komponenty (takie jak Text).

Pasma należy umieszczać w regionach. Regiony ograniczają szerokość pasm oraz maksymalną wysokość, jaką może zająć pasmo, zanim zostanie rozpoczęta nowa strona. Jedna strona może zawierać wiele regionów, a jeden region może zawierać wiele pasm.

Dodaj do strony region pokrywający cały jej obszar. Wewnątrz regionu dodaj pasmo Band, które będzie używane jako nagłówek raportu, pasmo DataBand, które będzie drukować informacje o kliencie, oraz kolejne pasmo Band na stopkę raportu.

Jeśli chcesz zmienić kolejność istniejących pasm w raporcie, użyj przycisków Move Forward i Move Behind na pasku narzędzi Aligment.

Nadaj pasmom bardziej opisowe nazwy (ja użyłem nazw Header, CustomerData i Footer). Ustaw właściwość DataView obiektu CustomerData na DvCustomer, a następnie ustaw CustomerData jako obiekt ControllerBand pasm Header i Footer. Powinieneś również uruchomić edytor stylów pasm (Band Style Editor) z inspektora obiektów (Object Inspector) i ustawić właściwość Print Location obu pasm na - odpowiednio - Body Header i Body Footer. Aby dowiedzieć się, jak mniej więcej zostanie wydrukowany raport, obserwuj okienko Band Display podczas modyfikowania ustawień. Pasma iteracyjne są wyświetlane w nim trzykrotnie, a pozostałe pasma tylko raz:

Chcemy również, aby nagłówek był drukowany na innych stronach, gdyby lista rekordów zajęła więcej niż jedną stronę; zaznacz opcję New Page w ramce Print Occurrence w tym samym oknie dialogowym.

Pasmo Footer zostanie wydrukowane dopiero wtedy, gdy wyczerpią się rekordy w obiekcie DvCustomers. Jeśli chcesz, aby było drukowane na każdej stronie, po prostu umieść komponenty bezpośrednio na stronie, pod regionem, a nie w paśmie.

W edytorze możesz szybko zidentyfikować związki między pasmami, ich style oraz wystąpienia w druku:

Dodawanie pól

Dodawanie pól do raportu nie jest trudne. Możesz przytrzymać wciśnięty klawisz Ctrl i przeciągnąć je z widoku DataView w drzewie projektu, aby dodać do raportu komponenty DataView. Jeśli zamiast klawisza Ctrl przytrzymasz wciśnięty klawisz Alt, dodasz komponenty Text zawierające właściwość Fullname. Pozwala to szybko utworzyć układ raportu. Teraz dodaj kilka pól do pasma CustomerData, a ich tytuł - do pasma Header. Ja dodałem pola CustNo, Company, Phone, TaxRate oraz LastInvoiceDate.

Nie zapomnij, że za pomocą narzędzi na pasku Alignment możesz wyrównać komponenty, nawet jeśli znajdują się w różnych pasmach.

Do pasma Header dodałem tytuł, a do pasma Footer - prosty tekst, który wskazuje, że listing dobiegł końca. W jednym z następnych artykułów wyjaśnię, jak użyć komponentów CalcOp i CalcTotal, aby dodać do stopki sumy, średnie i inne wartości obliczane.

Dodawanie raportu do projektu

Aby dodać raport do projektu, użyj metody opisanej w części II: użyj obiektu RvProject na formularzu lub w module danych, dołącz go do pliku raportu i wywołaj jego metodę Execute. Kiedy jednak używasz widoków Driver Data View, aplikacja musi wczytać odpowiedni sterownik. W tym celu wystarczy dodać do klauzuli uses jednostkę RvDLBDE (jeśli używasz BDE), RvDLDBX (jeśli używasz DbExpress) albo RvDLADO (jeśli używasz ADO).

Wnioski

W tym artykule wyjaśniłem, jak tworzyć proste raporty DataAware. Projekt z opracowanym tu raportem znajdziesz w CodeCentral. W części IV opiszę, jak używać widoku Direct Data View, jak tworzyć raporty typu Master/Detail i jak wyświetlać sumy i pola obliczane.

IV) Rave Reports - więcej o raportach z inteligentną analizą danych

W części III zbadaliśmy funkcje inteligentnej analizy danych w Rave Reports, korzystając z widoku Driver Data View. W części IV nauczymy się korzystać z widoków Direct Data View, tworzyć raporty typu Master/Detail oraz używać komponentów CalcOP i CalcTotal do wyświetlania wartości obliczanych i sum.

Widok Direct Data View

Widok Direct Data View umożliwia współdzielenie połączeń z bazą danych nawiązanych przez aplikację i pobieranie danych bezpośrednio z obiektów DataSet zawartych w aplikacji. Może być dołączony do dowolnej klasy wywiedzionej z TDataSet, a po dodaniu odrobiny kodu może nawet pobierać dane z niestandardowych struktur danych, takich jak tablice rekordów albo listy TStringList. Poza tym działa tak samo jak widok Driver Data View opisany w części III.

Używanie połączeń DataSet

Zaprojektujmy raport typu nadrzędny-szczegółowy (master/detail) z wykorzystaniem widoków Direct Data View. Utwórz nową aplikację i skonfiguruj połączenie z bazą danych za pośrednictwem wybranego szkieletu Db Framework. W tym przykładzie dla celów demonstracyjnych będziemy nadal korzystać z BDE. Dodaj dwie tabele (jeśli wolisz - kwerendy), wybierając dane z tabeli zamówień i tabeli pozycji. Dla każdego obiektu DataSet dodaj odpowiednie połączenie TRvDataSetConnection (dostępne na karcie Rave na palecie).

Ustaw właściwość DataSet każdego połączenia DataSetConnection na odpowiedni komponent i nadaj im znaczące nazwy (ja nazwałem je dscItems i dscOrders).


Nazwa jest istotna: to łącze, które wiąże aplikację z raportem. Nie można mieć dwóch połączeń DataSet o tej samej nazwie (nawet w różnych raportach), bo jeśli ktoś spróbuje jednocześnie uruchomić oba raporty, mogą pojawić się problemy.

Po skonfigurowaniu obiektów DataSet wróć do narzędzia projektowego Rave Reports. Wybierz polecenie New Data Connection ; powinieneś zobaczyć połączenia DataSet, które dodałeś do formularza w narzędziu projektowym Delphi:

Wybierz połączenie dscItems, aby utworzyć pierwszy widok DataView, a następnie powtórz procedurę, aby utworzyć widok DataView związany z połączeniem dscOrders. W widoku drzewa projektu powinieneś teraz zobaczyć pola pod nowo dodanymi widokami DataView:

Nie zapomnij nadać widokom lepszych nazw niż DataView1 i DataView2.

Tworzenie pasm

Po utworzeniu widoków DataView należy skonfigurować pasma. Utwórz region składający się z całego obszaru strony i dodaj jedno pasmo (Header), dwa pasma danych (Master i Detail) oraz kolejne pasmo (Footer). Ustaw właściwości ControllerBand pasm Header, Detail i Footer na Master. Za pomocą edytora właściwości BandStyle ustaw styl pasma Header na Body Header (B) , styl pasma Detail na Detail (D) , a styl pasma Footer na Body Footer (b) . Zauważ, że Band Display pokazuje podgląd wydruku pasm:

Musisz również połączyć właściwość DataView pasma Master z dvOrders, a pasma Detail - z dvItems. Aby utworzyć zależność nadrzędny-szczegółowy, ustaw właściwość MasterDataView pasma Detail na dvOrders, a właściwości MasterKey oraz DetailKey - na pole OrderNo.

Komponent FontMaster

Prawdopodobnie chciałbyś, aby podobne elementy (na przykład wszystkie elementy w paśmie Detail) były drukowane tą samą czcionką. Zamiast ustawiać każdą właściwość Font z osobna, możesz dodać komponent FontMaster. Dodaj do strony komponent FontMaster i ustaw jego właściwość Font na Times New Roman, 10. W następnym etapie, kiedy będziesz dodawał komponenty Text i DataText, ustaw ich właściwości FontMirror na FontMaster. Jeśli teraz zmienisz zdanie co do czcionki używanej w raporcie, nie będziesz musiał zmieniać ustawień każdego komponentu - wystarczy, że zmodyfikujesz komponent FontMaster, a zmiana zostanie odzwierciedlona w każdym dołączonym do niego komponencie. Możesz dodać do raportu tyle komponentów FontMaster, ile potrzebujesz.

FontMaster to komponent typu niewizualnego, co oznacza, że nie jest wyświetlany w obszarze projektu. Jeśli zechcesz go ponownie zaznaczyć, będziesz to musiał zrobić za pomocą widoku drzewa projektu.

Dodawanie komponentów DataTexts

Teraz wystarczy dodać do pasm komponenty Text i DataText. Pamiętaj, że możesz je przeciągnąć z widoku drzewa projektu, przytrzymując wciśnięte klawisze Ctrl i Alt. Pola OrderNo, SaleDate, Terms, PaymentMethod, AmountPaid oraz Freight dodałem do pasma Master, a pola ItemNo, PartNo, Qty oraz Discount - do pasma Detail. Nie zapomnij, że właściwość DisplayFormat pól zmiennoprzecinkowych jest ustawiona w samych polach, w widoku drzewa projektu, a nie w komponentach DataText.

Dodawanie sum i pól obliczanych

Do tworzenia obliczeń i wartości zagregowanych służą komponenty CalcOP i CalcTotal dostępne na karcie Report. Rezultaty obliczeń można umieścić w parametrach, obiektach PI Var albo wykorzystać jako wynik pośredni w innych obliczeniach. My umieścimy je w parametrach, więc zaznacz swój projekt w widoku drzewa projektu i dodaj dwa parametry o nazwach AmountPaidTotal i FreightTotal:

Teraz dodaj dwa komponenty CalcTotal do pasma Footer i ustaw ich właściwość Controller na pasmo Master, właściwość DataView na widok dvOrders, właściwości DataField na pola AmountPaid i Freight, a właściwości DestParam - na utworzone wcześniej parametry AmountPaidTotal i FreightTotal. W komponencie CalcTotal określa się również właściwość DisplayFormat wyświetlanej wartości.

Zauważ, że komponenty Calc są obliczane w takiej kolejności, w jakiej pojawiają się w widoku drzewa projektu. Jeśli wynik CalcOp ma być wyświetlany przez komponent DataText, upewnij się, że w drzewie widoku pojawia się przed tym komponentem. Możesz zmieniać kolejność elementów za pomocą przycisków Move Forward i Move Behind na pasku narzędzi Alignment.

Teraz możesz dodać w paśmie Footer dwa komponenty DataText, które będą wyświetlać te zmienne. Zwróć uwagę, że wartości zostały zsumowane, a za pomocą właściwości CalcType komponentów CalcTotal możesz definiować rodzaj wykonywanej operacji.

Przykładowe dane dołączone do projektów DbDemo nie zawierają wartości Freight w żadnym z rekordów. Możesz zmodyfikować kilka rekordów, aby zaobserwować dodawanie wartości.

Przypuśćmy teraz, że chcemy dodać obie sumy i wyświetlić je w paśmie stopki. Dodaj do raportu nowy parametr o nazwie Total oraz komponent CalcOp poniżej komponentów CalcTotal, w paśmie Footer. Ustaw właściwość Src1DataField na Param.AmountPaidTotal, a właściwość Scr2DataField na Param.FreightTotal. Ustaw właściwość DestParam na Total i określ format wyświetlania wartości ( DisplayFormat ). Dodaj komponent DataText, aby wyświetlić wartość.

Finishing Up

Aby dodać raport do projektu, postąp tak samo jak w przypadku poprzednich raportów: połącz go z obiektem RvProject i wywołaj metodę Execute. Możesz zechcesz przefiltrować obiekt DataSet według danych dostarczonych przez użytkownika, ale to również robi się w zwykły sposób.

Wnioski

Wyjaśniliśmy, jak tworzyć raporty z inteligentną analizą danych korzystające z widoków Direct Data View, jak konfigurować zależności nadrzędny-szczegółowy i jak korzystać z komponentów Calc. Projekt zawierający opracowane tu raporty można znaleźć w CodeCentral (ID: 21330, Rave Reports Master/Detail Example).

Uwaga!
Informacje zawarte w tym dokumencie reprezentują poglądy autora, który jest całkowicie odpowiedzialny za jego treść. Firma BSC Polska nie gwarantuje prawidłowości tych informacji.
ďťż