Programowanie w języku Delphi » Artykuły

Rave Reports - Raporty Master-Detail

Witam wszystkich ;) Jest to mój pierwszy artykuł tutaj więc proszę o wyrozumiałość ;).

Na naszej stronce możemy znaleźć już 3 artykuły na temat Rave'a, ale żaden z nich nie mówi jak dokonać raportu Master/Detail, więc postanowiłem wziąć sprawy w swoje ręce i ku przyszłym pokoleniom opisać proces tworzenia takiego raportu.

Ok, do lewej ręki kubek z kawą, do prawej mysz i zaczynamy.

Na początku uruchamiamy Rave'a i tworzymy nowy project: File->New.
Z prawej strony naszego środowiska jest "project manager", przypominający nam troszkę tego z produktów Borland'a. Klikamy na Report Library -> Report1 -> Page1.

Z lewej strony Rave'a, mamy coś a'la Object Inspectora. Odnajdujemy pozycję PaperSize i zmieniamy na A4. Zmieniamy także właściwość FullName na Strona1.

Następnym krokiem jaki poczynimy, będzie stworzenie połączenia z bazą danych. Poniższy przykład opiszę na podstawie MS SQL Server 2008.

Zaraz pod głównym menu, znajduje się szereg przycisków (tzw Toolbar). Klikamy przycisk z fioletowym sześcianem i napisem "view":
art1.jpg

Pojawi nam się okienko Data Connections:
art2.jpg

Wybieramy w nim "Database Connection" klikamy "Next". W następnym kroku "Database Connetcion Type" wybieramy "ADO" i klikamy na Finish.

Pojawi nam się okienko "Database Connection Parameters". Klikamy w przycisk [...].
art3.jpg

Otworzy się okno z właściwościami połączenia. Wybieramy w nim "Microsoft OLE DB Provider for SQL Server" i klikamy dalej.
art4.jpg

Pokaże się zakładka połączenie. Tam wybieramy nazwę naszego serwera, sposób autoryzacji oraz bazę danych na podstawie której stworzymy raport.
art5.jpg

Klikamy OK, dopóki nie znikną wszystkie okienka które pootwieraliśmy. Łyk kawy.

Przygryzamy kostką czekolady i ponownie klikamy na fioletowy sześcian z napisem "view" na toolbarze pod menu.
Tym razem w okienku poniżej, wybieramy "Driver Data view":
art2.jpg

Klikamy next i finish. Pojawi się nam coś takiego:
art6.jpg

Jest to "Query Advanced Designer". Przypomina nam on trochę Query Designera z SQL Server'a. Po prawej stronie znajduje się lista tabel i widoków. Nas będą interesowały widoki.

Kolejny łyk kawy ;)

Teraz stworzymy zapytanie dla tabeli master.

W moim przypadku tabelą "master" jest tabela Rodzaje_indeksów, a więc użyję widoku który sobie nazwałem "v_rodzaje_indeksow". A tabelą "Detail" będzie tabela "indeksy" i analogicznie widok v_indeksy. Odszukujemy więc po lewej stronie na liście widok który chcemy użyć jako master i klikamy na niego myszą i przeciągemy na żółte pole, tak aby wszystko wyglądało jak na załączonym obrazku:
art7.jpg

UWAGA! Nie dodajemy teraz  tabeli "Detail" (lub jak kto woli slave).
Klikamy Ok, okienko się zamyka. Z prawej strony okna programu w tzw Project Manager'ze odnajdujemy "DriverDataview1" i zmieniamy jego właściwość name na "TabelaMaster".

Ok, teraz czyniąc to samo co wyżej, tworzymy sobie tabele slave. Czyli znów klikamy fioletowy sześcian z napisem view na tolbarze pod menu. Wybieramy Driver Data view. Klikamy next i finish. Dodajemy teraz tabelę którą chcemy dodać jako detail (slave). W moim przypadku jest to tabela v_indeksy.

I tutaj znów chciałbym zwrócić uwagę, aby wszystko działało prawidłowo, to w tabelach musimy mieć utworzone Relationship (relacje). U mnie ta relacja w MS SQL Server wygląda w ten sposób:
art8.jpg

Gdy już wybierzemy interesujący nas widok i przeciągniemy go na żółte pole, to nazywamy nowo dodany DriverDataview jako "TabelaSlave".

Ok, popijamy kawkę i z menu Tools wybieramy: Report Wizards -> Master/Detail Report.

Pojawi się następujące okienko:
art9.jpg

Program pyta nas, który driverdataview chcielibyśmy używać jako Master. Wybieramy TabelaMaster i klikamy next. Następne pytanie, to pytanie o DetailDataview, wybieramy naszą "TabelaSlave" i ponownie klikamy next.

Kolejnym krokiem będzie wybór pól z naszej tabeli master:
art10.jpg

Klikając dalej, wybieramy sobie kolejność pól, które zaznaczyliśmy na poprzedniej formatce.
Klikamy next i wybieramy pola, które chcemy wyświetlić z naszej tabeli slave - w moim przypadku będą to pola indeks, nazwa indeksu, rozmiar i kolor. Klikamy dalej w celu ustalenia kolejności pól.
Po ustaleniu kolejności pól musimy przypisać tzw "relacje", czyli które id z tabeli podrzędnej jest przypisane do tabeli nadrzędnej. W moim wypadku wygląda to tak:
art11.jpg
(czerwoną linię dorysowałem w Photoshop'ie w celu zobrazowania relacji ;) ).

Klikamy next i w okienku Report Layout Options ustawiamy opcję naszego raportu:
art12.jpg
Report title wpisujemy nazwę raportu, w margins ustawiłem wartości z 1.0 na 0.2, gdyż 1.0 to zdecydowanie za dużo.

Next ;)

W następnym okienku możemy ustawić sobie fonty naszego raportu. Tym razem zostawiam domyślne.

Popijamy kawy. Klikamy Generate. I powinien się wygenerować projekt raportu.

Projekt powinien wyglądać tak:
art13.jpg
Jak widzimy jest on podzielony na kilka sekcji. Szare pole które widzimy to tzw "Region", na którym umieszczamy elementy raportu zwane "Band-ami". Pierwszy Band od góry to title Band. Tam możemy umieszczać dodatkowe elementy raportu jak pola tekstowe, pola tekstowe z parametrami, obrazy, kody kreskowe, kształty itp. Nie będę tutaj opisywał jak to się robi i jak się ustawia parametry poszczególnych komponentów, ponieważ są już tutaj artykuły na ten temat.

Klikamy lewym przyciskiem myszy na "TabelaMasterRegion: TabelaMasterTitleBand" i  w Object Inspectorze Otwieramy właściwości "Band Style".
Pojawi się nam okienko podobne do tego:
art14.jpg

Kreskami oznaczyłem jaka właściwość odpowiada jakiemu band'owi. Uwaga! Aby w tym okienku pojawia się lista wszystkich band'ów, ale edytujemy właściwości tylko zaznaczonego w oknie projektu!
Cyferkami oznaczyłem osobną właściwość bandu którą poniżej wyjaśnię:
1 - Band tytułu - możemy na nim umieszczać dowolne komponenty.
2 - Tabela Master Band - jest to band na którym znajdują się tytuły kolumn naszej tabeli master. Tytułom tym można przypisać swoje nazwy, czcionkę i inne parametry. Można je także usunąć. Do tego Bandu można również dodawać różne komponenty. Myślę że metoda prób i błędów we wszystkich bandach będzie najodpowiedniejszą ;).
3 - Tabela Master DataBand Master - jest to band w którym będą znajdywać się poszczególne rekordy z tabeli master.
4 - Tabela Slave Band - jest to band w którym znajdują się tytuły pól tabeli slave. Jest on bardzo podobny w działaniu jak band nr 2.
5 - TabelaSlaveDataBand - jest to band w którym wyświetlać się będą rekordy tabeli slave.

Sekcja Prin Location określa ile razy i gdzie ma być drukowany poszczególny Band.
6 - Body Header - będzie drukowany u góry strony (w nagłówku).
7 - Group Header - będzie drukowany na początku każdej grupy.
8 - Row Header - będzie drukowany na początku każdego rekordu.

Ja TabelaMaster badn ustawiłem na Row Header, tak aby tytuły pól były drukowane przy każdym rekordzie z tabeli id. Ale mówię, najodpowiedniejszą metodą jest tutaj metoda prób i błędów.

Sekcja Print Occurrence. W niej określamy na jakich stronach ma się dodatkowo pojawić dany Band. Tutaj proponuję zostawić domyślne ustawienia, bądź też pobawić się różnymi kombinacjami.
9 - Pierwsza strona.
10 - Każda następna strona.

Spróbujcie przerobić wasz projekt tak, aby wyglądał jak mój:
art15.jpg

Po dokonanych modyfikacjach, zapisujemy nasz raport: File -> Save.
Teraz nadeszła "wiekopomna chwiła" :D. Tworzymy podgląd naszego raportu:
File -> Execute Raport -> Preview -> Ok. Powinniśmy zobaczyć coś takiego (lub podobnego ;p):
art16.jpg

Możecie teraz już wykorzystać w Delphi pliki *.rav waszego raportu. Oczywiście nie zapomnijcie w sekcji uses dodać: RvDLADO.

Dziękuję wszystkim za uwagę. Mnie się już kawa skończyła, nie wiem jak wam ;)

Pozdrawiam
-Mariusz Jernalczyk

5 komentarzy

organista18 2009-11-20 11:14

Rzeczywiście, jeśli używamy TrvDataSetConnection, to takiego problemu, jak opisała Pani Jadwiga nie ma.

jadzian 2009-11-09 13:31

Udało mi się w końcu problem rozgryźć. Może to kogoś zainteresuje więc napiszę w czym rzecz.
Korzystam z "Database Connection" DBX.  Nie piszę żadnego kodu w Delphi tylko wykorzystuję edytor Rave dla przygotowania raportu. Potem ten raport jest wywoływany w programie.

Tworzę 2 SQL-e jeden dla powiedzmy klientów drugi dla zamówień.

1.SQL

Select
 Firma.ID,
 Firma.Nazwa
from
 Firma

2.SQL

Select
 Zamowienie.ID,
 Zamowienie.FirmaID
from
 Zamowienie

Wpisuję to do Driver Data View i nazywam: tblFirma (1a. SQL-a) oraz tblZamowienie (2. SQL).
Oczywiście tworzę na tym raport wg opisu jak w artykule powyżej ale… to nie daje efektu jakiego się spodziewałam. Dostaję dla każdej firmy wszystkie zamówienia jakie tylko są w bazie. Żeby dostać wynik poprawny muszę dodatkowo w QueryParams dla SQL-a drugiego (czyli tblZamowienie ) wpisać odwołanie do tblFirma, która jest w tym przypadku nadrzędna.
Wpisuję:
KontrahentID = tblFirma.ID
Dodatkowo muszę lekko zmienić SQL dla zamówień tak, aby łykał zadeklarowany przeze mnie parametr.

Select
 Zamowienie.ID,
 Zamowienie.FirmaID
from
 Zamowienie
Where
 Zamowienie.FirmaID = :KontrahentID

To wszystko.

Problem konsultowałam z miłym kolegą, który tworzy raporty bezpośrednio w Delphi korzystając "Direct Data View" i komponentów RAVE-a pod Delphi

TRvDatasetConnection
TRvSystem
TRvProject

i jak twierdzi nie ma takich problemów.

Jadwiga Nowak

jadzian 2009-10-30 13:25

Witam,

Wszystko jest świetnie opisane tylko… wynik, który otrzymujemy jest zły. Z tego co się orientuję raport Master detail w detalach dla każdej grupy powinien pokazywać inne detale. W wyniku wyraźnie widać, że dla każdej grupy mamy dokładnie te same detale.
Wg mnie to jest jakiś błąd RAVE i nie mam pojęcia jak go obejść. Może ktoś już na to wpadł? Nie wiem jak to zwalczyć.

Jadwiga Nowak

organista18 2009-07-10 12:29

Generalnie spróbuj się pobawić liniami w bandzie ...SlaveDataBand.

robert.gg 2009-07-02 21:16

Artykuł bardzo mi pomógł, mam tylko jedno pytanko jak zrobić linje pionowe rozdzielające pola w wierszu tak żeby to była pełna tabelka, odrazu powiem że stała długość linji odpada bo kożystam z MemoData.