Kurs Oracle Reports



Materiały szkoleniowe

Podstawy budowy raportów w Oracle Reports 2.5 ćwiczenia

wersja poprawiona 17.04.2000

0x08 graphic
Autor

Paweł Żołnierczyk

Spis treści

Zawartość tabel wykorzystywanych na kursie


Zawartość tabel wykorzystywanych na kursie

Zawartość tabeli DEPT

DEPTNO DNAME LOC

---------- -------------- -------------

10 ACCOUNTING NEW YORK

20 RESEARCH DALLAS

30 SALES CHICAGO

40 OPERATIONS BOSTON

Zawartość tabeli EMP

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO--------- ---------- --------- --------- -------- --------- --------- ---------

7839 KING PRESIDENT 81/11/17 5000 10

7698 BLAKE MANAGER 7839 81/05/01 2850 30

7782 CLARK MANAGER 7839 81/06/09 2450 10

7566 JONES MANAGER 7839 81/04/02 2975 20

7654 MARTIN SALESMAN 7698 81/09/28 1250 1400 30

7499 ALLEN SALESMAN 7698 81/02/20 1600 300 30

7844 TURNER SALESMAN 7698 81/09/08 1500 0 30

7900 JAMES CLERK 7698 81/12/03 950 30

7521 WARD SALESMAN 7698 81/02/22 1250 500 30

7902 FORD ANALYST 7566 81/12/03 3000 20

7369 SMITH CLERK 7902 80/12/17 800 20

7788 SCOTT ANALYST 7566 82/12/09 3000 20

7876 ADAMS CLERK 7788 83/01/12 1100 20

7934 MILLER CLERK 7782 82/01/23 1300 10

Zawartość tabeli SALGRADE

GRADE LOSAL HISAL

--------- --------- ---------

1 700 1200

2 1201 1400

3 1401 2000

4 2001 3000

5 3001 9999

Budowa tabel wykorzystywanych na kursie

Podczas kursu będziemy korzystać z uprzednio utworzonych tabel opisujących zatrudnionych w pewnej firmie, ich wynagrodzenia i miejsca pracy. Firma dzieli się na departamenty. Każdy pracownik należy do pewnej grupy zaszeregowania, w zależności od wysokości pensji, którą otrzymuje.

Tabela DEPT — tabela zawierająca wszystkie departamenty

Kolumna

Opis

DEPTNO

Departament number — unikalny numer departamentu

DNAME

Nazwa departamentu — przechowywana w zapisie dużymi literami

LOC

Lokalizacja departamentu (miasto w którym znajduje się departament)

Tabela EMP wykaz wszystkich pracowników

Kolumna

Opis

EMPNO

Employee number — unikalny numer pracownika

ENAME

Nazwisko pracownika — przechowywane w zapisie dużymi literami

JOB

Etat, stanowisko pracy

MGR

Identyfikator szefa (czyli EMPNO we wierszu szefa)

HIREDATE

Data zatrudnienia

SAL

Pensja

COMM

Prowizja naliczona od początku roku, dotyczy pracowników zatrudnionych na stanowisku SALESMAN

DEPTNO

Numer departamentu w którym zatrudniony jest pracownik. Wartość w tym polu musi odpowiadać jednemu i tylko jednemu wierszowi w tabeli DEPT

Tabela SALGRADE — tabela „widełek” zaszeregowania

Kolumna

Opis

GRADE

Numer grupy zaszeregowania

LOSAL

LOW SALARY — dolna granica widełek płacowych dla stawki zaszeregowania GRADE

HISAL

HIGH SALARY — górna granica widełek

Podstawy

Wykonanie Raportu w zaprojektowanego Reports Designerze 2.5 polega w na wykonaniu instrukcji SELECT na serwerze. Uzyskane w wyniku tej lub tych instrukcji dane otrzymuje klient, można zauważyć, że otrzymywane przez niego dane mają formę „tabelki” która podlega dalszej obróbce na kliencie. Oprócz szaty graficznej na komputerze-kliencie wykonywane są niektóre operacje sumaryczne, obliczenia korzystające z wbudowanych komponentów lub samodzielnie napisanych procedur i funkcji.

Zapytanie i model danych

Reports Designer składa się z wielu obiektów. Przyjrzymy się ich roli i własnościom tworząc elementarny raport.

Model danych - model danych to graficzny obraz danych jako zapytania, lub zapytań które zostaną wykonane oraz obliczeń którym te dane zostaną poddane.

Wchodzimy do edytora modelu danych klikając na ikonę Data Model. Następnie sięgamy po narzędzie SQL, przy jego pomocy rysujemy zaokrąglony prostokąt.

0x01 graphic

Wchodzimy do właściwości tego obiektu (prawy przycisk myszy). Przed nami ukazuje się następujące okienko:

0x01 graphic

Wypełniamy je w sposób pokazany na rysunku. Poszczegolne właściwości oznaczają:

0x01 graphic

Klikamy na Applay(Zastosuj). W modelu danych poniżej czarnego zaokrąglonego prostokąta zapytania pojawił się prostokąt grupy. Jeżeli nazwaliśmy zapytanie Q_emp to uzyskaliśmy grupę G_emp. Dalej konsekwetnie ta nazwa zostanie odziedziczona przez graficzny obiekt - ramkę, będzie to ramka R_emp.

Rozkład domyślny

Rozkład raportu - jest to graficzny projekt przyszłego raportu, zawierający obiekty określające sposób (kolor, kierunek itp) drukowania obiektów wystepujących w modelu danych.

Tworzenie rozkładu raportu rozpoczynamy od kliknięcia na ikonę 0x01 graphic
 Default Layout (Rozkład Domyslny). Ukazuje nam się okno w którym wybieramy Tabular (Tabelaryczny) i klikamy na przycisk OK.

Teraz pownien nam się ukazać rozkład gdzie poniżej etykiet leżą pola raportu. W przypadku gdy danych w tabeli jest bardzo dużo lub szerokość strony jest waska może do zawinięcia danych na rozkładzie - tzn. etykiety i pola które nie zmieściły się w pierwszym wierszu umieszczane są w odpowiadających im ramkach rozpoczynając od lewej strony.

Modyfikacje rozkładu domyślnego

Jeżeli generator przygotował nam rozkład domyślny możemy skorzystać z narzędzi do kolorowania obiektów. Są to po kolei wypełnianie obiektów kolorem, obrysowywanie obiektów kolorem, kolorowanie trzcionek.

0x01 graphic

Zmiany formatów czcionki dokonujemy z menu Format/Font. Przykład zmodyfikowanego rozkładu domyślnego znajduje się na poniższej ilustracji.

0x01 graphic

Uruchomienie raportu

Jeżeli rozkład odpowiada naszym oczekiwaniom możemy go uruchomić. Ikoną 0x01 graphic
uruchamiamy raport, pojawia się tak zwana formatka uruchomienia raportu. Na formatce która się pojawiła klikamy na „Run Report”.

0x01 graphic

Teraz przed nami powinien pojawić się wykonany raport.

0x01 graphic

Widzimy że zapytanie które w SQL+ było w prostej formie tekstowej, teraz jest “ubrane” w pewną formę graficzną. Wygenerowany “wydruk” możemy zamknąć(CLOSE) aby przyjrzeć się strukturze ramek. Aby lepiej było ją widać rozsunąłem ramki i pokolorowałem je nieco intensywniej:

0x01 graphic

Ramka czerwona to ramka obejmująca jej rola to pilnowanie położenia obiektów. Znaki “dzwonek” na jej bokach to oznaczenie iż posiadaja zdolność do rozszerzania się w pionie.

Ramka koloru zielonego to ramka która drukuje się dla każdego wiersza wybranego w zapytaniu. Ciemna strzałka na jej krawędzi ramki określa kierunek drukowania.


Łamanie i funkcje grupowe

Model danych

Operacja łamania może kojarzyć się z grupowaniem w SQL. Weźmy raport zbudowany na:

SELECT *

FROM emp;

Dane pochodzące z tego raportu „połammy” ze względu na numer departamentu i zawód.

Powyższy wykres uzyskamy wyciągając z G_emp pola deptno i job.

0x01 graphic

Jednak różnica polega na tym że w odróżnieniu od grupowania łamanie nie powoduje utraty dostępu do danych szczegółowych.

0x01 graphic

Teraz należy jeszcze „nazwać” grupy i uporządkować rozkład np. w następujący sposób:

0x01 graphic

Dobranie rozkładu domyślnego

Do sporządzonego modelu danych możemy przygotować dwa rozkłady. Jeżeli wybierzemy rozkład tabelaryczny to uzyskamy poniższy efekt: (Wartość rozpoczynająca każdą nową grupę jest drukowana tylko raz).

0x01 graphic

Ze względu na wielkość prezentowany jest poniżej jedynie fragment rozkładu

nadrzędny-podrzędny (master-detail), rozkład wyglądający następująco:

0x01 graphic

Przygotowany w tym raporcie rozkład warto zachować do wykorzystania w następnym rozdziale.

Funkcje grupowe w raportach

W tytule tego rozdziału pojawiło się hasło funkcje grupowe. Z tego typu funkcjami mogliśmy mieć wcześniej do czynienia w SQL'u. Czy jest to więc drugi raz to samo? Okazuje się że nie. Funkcje grupowe wykorzystywane w SQL redukowały każdą grupę do jednego wiersza. Dane z serwera miały być zwrócone w postaci tabelki, nie mieliśmy możliwości odniesienia się do poszczególnych elementów z grup. W funkcjach grupowych w raportach działamy na kliencie, nie tracimy informacji o elementach grup.

Podsumowania

Aby zrozumieć istotę działania funkcji grupowych przeanalizujmy następujący problem. Dla modelu danych z poprzedniego rozdziału przygotujmy raport z podsumowaniami:

CS_total - sumaryczna kwota pensji w firmie

CS_deptno - sumaryczna kwota pensji w każdym departamencie

CS_job - sumaryczna kwota pensji w każdym departamencie przypadająca na dane stanowisko.

Żądane sumy musimy przygotować w Modelu Danych. W tym celu rozciągam nieco w dół prostokąty G_deptno i G_job tak abym mógł korzystając z narzędzia 0x01 graphic
umieścić na każdym z poziomów sumy.

Pierwsza suma CS_job niech będzie sumą SAL zerowaną co G_job.

0x01 graphic

Kolejna suma CS_deptno niech będzie sumą w obrębie departamentu. Mogła by to być również suma po kolumnie sal ale zredukujemy ilość obliczeń czyniąc ja sumą po CS_job zerowaną co G_DEPTNO. Sumaryczna kwota wypłacanych pensji w firmie to oczywiście CS_total zerowana dla raportu i sumująca sumy wyliczone w poszczególnych departamentach.(Cechą intuicyjnie nie do końca oczywistą jest fakt iż CS_total leży niejako poza bloczkiem zapytania.)

0x01 graphic

Inne funkcje grupowe

Inne funkcje dostępne oprócz sumy to min.:

Rozkład

Do tak przygotowanego modelu proponuje wybrać rozkład nadrzędny-podrzędny. Wydruk raportu możemy mieć następującą formę (fragment):

0x01 graphic

Łączenie zapytań

Raport nadrzędny-podrzędny

Inna metoda uzyskania raportu master-detail dla tablic Dept i Emp to połączenie dwóch zapytań za pomocą narzędzia Link.

0x01 graphic

0x01 graphic
- narzędzie za pomocą którego łączymy zapytania

Za pomocą wspomnianego narzędzia ciągniemy linie od deptno w Q_dept do deptno w Q_emp.

0x01 graphic

Teraz dla każdego znalezionego wiersza w pierwszym zapytaniu uruchamiane będzie przeszukiwanie tablicy emp.

Struktura raportu jest może nieco przejrzystsza niż przy zredukowanej ilości zapytań. Niejednokrotnie również raport działa szybciej szczególnie wtedy gdy wielkość i ilość pozyskiwanych danych w zapytaniu nadrzędnym jest stosunkowo duża a w podrzędnym mniejsza.

Kolumny formuł i wypełniające

W tym rozdziale zapoznamy się z dwoma obiektami modelu danych:

0x01 graphic
- kolumna formuły

0x01 graphic
- kolumna wypełniająca

Kolumny formuł

Kolumna formuły to funkcja liczona każdorazowo przy nowej instancji elementu tabeli lub grupy łamania. Raport którego budowę prześledzimy w tym rozdziale powstał poprzez usuniecie grupy G_job i kolumny sumującej w tej grupie.

Korzystając z ikony umieszczamy w grupie G_emp funkcje. Przyjmijmy, że jest to funkcja obliczająca pensje pracownika brutto w ciągu całego roku. Funkcja zwraca wartość v_brutto dla każdego nowego wiersza wybranego instrukcją SELECT.

function CF_bruttoFormula return Number is

v_annual NUMBER(9,2);

begin

v_annual := 12*:sal+nvl(:comm,0);

return v_annual;

end;

Zwróćmy uwagę że jeżeli w kodzie pojawia się odniesienie do zmiennej zewnętrznej stosujemy notację z dwukropkiem.

Kolumna wypełniająca

Funkcja zwraca jedną wartość, przypuśćmy jednak że zależy nam aby w tej funkcji wyliczyć dwie wartości. Można by taki efekt uzyskać gdyby na poziomie każdego wiersza istniała zmienna której wartość mogłaby być ustawiana na poziomie każdego wiersza pobranego w zapytaniu. Rolę takiej zmiennej może pełnić pełni kolumna wypełniająca. Umieśmy kolumnę CP_ofe na poziomie grup G_emp. Teraz zmodyfikujmy ciało funkcji tak aby CP_ofe stanowiło 40 % kwoty zarobków pracownika.

function CF_bruttoFormula return Number is

v_annual NUMBER(9,2);

begin

v_annual := 12*:sal+nvl(:comm,0);

:CP_ofe := 0.4*v_annual;

return v_annual;

end;

Skoro raport dotyczy zarobków rocznych logicznym jest aby zmienić źródło sumowania CS_deptno z sal na CF_brutto.

0x01 graphic

Ponieważ nastąpiło wiele zmian w modelu danych najłatwiej będzie przygotować nowy rozkład korzystając z rozkładu domyślnego.

Wyjątki

Przyjrzyjmy się następującej sytuacji. Niech będzie dany raport wybierający wszystkie dane wiersze z tablicy emp. W procedurze CF_mgr_name chcielibyśmy obliczać nazwiska wybranych pracowników.

Raport składa się z jednej grupy w której umieszczamy procedurę następującej treści:

function CF_mgr_nameFormula return Char is

v_mgr_ename emp.ename%TYPE;

begin

SELECT ename

INTO v_mgr_ename

FROM emp

WHERE empno = :mgr;

return v_mgr_ename;

end;

Czytelnika nie znającego PL/SQL zastanowiać może deklaracje v_mgr_name. Ten rodzaj deklaracji to chrakterystyczny właśnie dla PL/SQL, zmienna będzie takiego typu jak kolumna ename w tablicy emp.

Procedura kompiluje się tak jak i cały raport. Przygotowujemy rozkład domyślny i uruchamiamy raport i ... dostajemy informację o wystąpieniu sytuacji wyjątkowej.

0x01 graphic

Jaka to sytuacja wyjątkowa? Oczywiście KING pracownik który nie posiada szefa. Tę sytuację należy w jakiś sposób obsłużyć, dokonujemy tego w bloku obsługi wyjątków. Sytuacja wyjątkowa pojawia się w instrukcji SELECT ...INTO..., następnie sterowanie przechodzi do bloku obsługi wyjatków.

function CF_mgr_nameFormula return Char is

v_mgr_ename emp.ename%TYPE;

begin

SELECT ename

INTO v_mgr_ename

FROM emp

WHERE empno = :mgr;

return v_mgr_ename;

exception

when NO_DATA_FOUND then

v_mgr_ename := 'THE BOSS';

return v_mgr_ename;

end;

Zapobiegliwy programisty mógłby jeszcze dodać obsługę wszystkich innych wyjątków:

function CF_mgr_nameFormula return Char is

v_mgr_ename emp.ename%TYPE;

begin

SELECT ename

INTO v_mgr_ename

FROM emp

WHERE empno = :mgr;

return v_mgr_ename;

exception

when NO_DATA_FOUND then

v_mgr_ename := 'THE BOSS';

return v_mgr_ename;

when OTHERS then

v_mgr_ename := 'STRANGE !!!';

return v_mgr_ename;

end;

Ostatecznie interesujący nas raport będzie miał formę jak na poniższym rysunku(fragment):

0x01 graphic

Raport Macierzowy

Raport macierzowy na trzech zapytaniach

Raport macierzowy to rodzaj raportu w którym dla pewnych dwóch wymiarów drukowanych jeden w poziomie, drugi w pionie na ich przecięciu umieszczane są wartości przecięcia.

Przygotowanie raportu rozpocznijmy od skonstruowania zapytań wybierających wymiary przyszłego raportu. Niech Q_jobs wybiera wszystkie zawody w firmie, a Q_depts wszystkie numery i nazwy departamentów.

Zapytania będą miały postać:

SELECT DISTINCT job

FROM emp;

SELECT deptno, dname

FROM dept;

Trzecie zapytanie Q_values musi przygotowywać trójki x,y, f(x,y). Wartość f(x,y) będzie to w naszym przypadku ilość osób w danym departamencie na danym stanowisku, równie dobrze mogła by to być sumaryczna czy średnia wartość zarobków itp.

SELECT deptno, job, count(*)

FROM emp

GROUP BY deptno, job;

0x01 graphic

Teraz dwa pierwsze zapytania należy przykryć obiektem zwanym produktem krzyżowym.

0x01 graphic

Teraz rozciągamy prostokąt produktu krzyżowego tak aby przykryć grupy G_jobs i G_depts. Tak utworzoną nową grupę nazywam G_matrix.

0x01 graphic

Teraz przy pomocy 0x01 graphic
łączę odpowiednie pola z G_matrix do odpowiednich pól G_values.

0x01 graphic

Teraz możemy przystąpić do generacji domyślnego rozkładu - będzie to oczywiście rozkład macierzowy(matrix). Warto zwrócić uwagę, że pozostałe domyślne ustawienia wymagają przestawienia.

0x01 graphic

Na drugiej zakładce musimy wybrać która grupa będzie drukowana wszerz. W rozkładzie domyślnym na przecięciu deptno i job wpisywane są zarówno deptno, job, count(*) z dwóch pierwszych wartości warto zrezygnować - raport stanie się czytelniejszy. Również przestrzeń rezerwowana na wyniki obliczeń count(*), 40 znaków jest stanowczo za duża, nawet gdyby w emp było do 1000 rekordów wystarczyły by 3 znaki.

0x01 graphic

Bo dokonaniu tych zmian wygenerujmy rozkład.

0x01 graphic

W rozkładzie tym również dokonuję kilku zmian, o znaczeniu raczej kosmetycznym dzięki czemu raport stanie się czytelniejszy. Przede wszystkim należy wprowadzić ramki dzięki czemu wyraźnie widać kolumny i wiersze. Usuwam również szablon tekstowy count.

0x01 graphic

W wyniku tych zmian ostatecznie otrzymuję.

0x01 graphic

Problem pustych miejsc

Jednym z problemów w raportach Developera 2000 który często pojawia się na listach dyskusyjnych są puste miejsca. Wynikają one z tego, iż wartości raportów ustalone są tylko tam gdzie dla x i y istnieje pewna wartość f(x,y). Jak jeżeli przyjrzymy się poniższemu zapytaniu widzimy, że wyznacza ono tylko 9 wartości. Oznacza to że 11 komórek raportu pozostanie pustych.

SQLWKS> SELECT deptno, job, count(*)

2> FROM emp

3> GROUP BY deptno, job;

DEPTNO JOB COUNT(*)

---------- --------- ----------

10 CLERK 1

10 MANAGER 1

10 PRESIDENT 1

20 ANALYST 2

20 CLERK 2

20 MANAGER 1

30 CLERK 1

30 MANAGER 1

30 SALESMAN 4

9 wierszy wybranych.

Istnieją sztuczki graficzne typu graficzne zero które pokazuje się we wszystkich nie zadrukowanych komórkach. Sztuczka ta czasem się udaje ale jest to uzależnione np. od sterowników drukarki. Formalne rozwiązanie tego problemu polega jednak na takim zmodyfikowaniu zapytania aby wybierało te dodatkowe zera dla tych przecięć deptno i job dla których nie ma żadnej danej.

SELECT deptno, job, count(*)

FROM emp

GROUP BY deptno, job

UNION

SELECT D.deptno, E.job, 0

FROM dept D, emp E

WHERE (D.deptno,E.job) NOT IN (SELECT deptno, job

FROM emp

GROUP BY deptno, job);

Powyższe zapytanie sumuje poprzez UNION [DISTINCT] te przecięcia dla których są dane z zapytaniem, w którym uzyskano iloczyn kartezjański kolumny job i wszystkich numerów departamentów eliminując zbędne zestawienia poprzez umieszczenie nieco zmodyfikowanego pierwszego zapytania w klazuli WHERE zapytania drugiego. Duplikaty zwracane przez drugie zapytanie zostały wyeliminowane przez UNION.

Zmodyfikowane zapytanie wybiera.

DEPTNO JOB COUNT(*)

---------- --------- ----------

10 ANALYST 0

10 CLERK 1

10 MANAGER 1

10 PRESIDENT 1

10 SALESMAN 0

20 ANALYST 2

20 CLERK 2

20 MANAGER 1

20 PRESIDENT 0

20 SALESMAN 0

30 ANALYST 0

30 CLERK 1

30 MANAGER 1

30 PRESIDENT 0

30 SALESMAN 4

40 ANALYST 0

40 CLERK 0

40 MANAGER 0

40 PRESIDENT 0

40 SALESMAN 0

Modyfikacja zapytania nie spowoduje zmiany działania raportu i konieczności modyfikowania raportu. Po rozbudowaniu zapytania możemy od razu obejrzeć oczekiwane zera na ekranie.

0x01 graphic

Raport o zredukowanej ilości zapytań

Spróbujmy stworzyć ten sam raport na mniejszej ilości zapytań. Zatem jedno zapytanie musi zwracać trójki.

0x01 graphic

Z bloczek zwracający trójki musimy połamać.

0x01 graphic

Teraz na dwie pierwsze grupy nakładamy produkt krzyżowy. Po uporządkowaniu uzyskuję:

0x01 graphic

Funkcjonalnie raport nie różni się od poprzedniego. Problemem może być ujedynie uzyskanie deptno za pomocą kolumny formuły.

0x01 graphic

Gdzie ciało funkcji:

function CF_dnameFormula return Char is

v_dname varchar2(20);

begin

SELECT dname

INTO v_dname

FROM dept

WHERE deptno = :deptno1;

return v_dname;

end;

Druga możliwość to modyfikacja zapytania na przykład do postaci:

SELECT dname, job, count(*)

FROM emp E, dept D

WHERE E.deptno=D.deptno

GROUP BY dname, job

UNION

SELECT D.dname, E.job, 0

FROM dept D, emp E

WHERE (D.deptno,E.job) NOT IN (SELECT deptno, job

FROM emp

GROUP BY deptno, job);

Programowe sterowanie wydrukiem

Programowe wyłączenie

Zdarza się że dopiero w czasie drukowania raportu pewne ramki dla pewnych danych nie muszą być w ogóle drukowane. Może to być np. raport opisujący korzystanie z pewnych usług. W sumie ukazuje się, że osoby korzystające z tych usług mogły to robić, za darmo i nie są nam na wydruku potrzebne.

Dla przykładu spróbujmy wyeliminować KINGA z wydruku. W tym celu w możemy przerobić raport w którym w funkcji znajdowaliśmy nazwisko szefa. Stajemy na ramce R_emp i wyświetlamy jej właściwości. Przechodzimy na drugą zakładkę.

0x01 graphic

Następnie klikamy na w bloku Foramat Trigger na przycisk Edit. Pokazuje się nam okienko do wpisywania kodu PL/SQL. Wpisujemy:

function R_empFormatTrigger return boolean is

begin

if :mgr is null then

return (FALSE);

else

return (TRUE);

end if;

end;

Aby przekonać się że wyzwalacz faktycznie jedynie ukrywa (usuwa z drukowani) ramki R_emp warto umieścić sumę pensji wszystkich pracowników. Wtedy wyraźnie widać, że pensja KINGA, 5000 jest brana pod uwagę w obliczeniach, ale sam wiersz KINGA nie jest drukowany.

Formatowanie warunkowe

Jeżeli chcielibyśmy pewne rekordy wyróżnić na wydruku np. pracownicy o dochodach poniżej tysiąca byli drukowani innym atrybutem wizualnym korzystamy z funkcji z wbudowanego pakietu SRW.

W wymienionym na poprzedniej stronie wyzwalaczu umieszczamy kod który zmieni kolor drukowania wszystkich tych ramek wewnątrz których pensja jest mniejsza od 1000.

function R_empFormatTrigger return boolean is

begin

if :sal < 1000 then

srw.attr.bfcolor := 'cyan';

srw.set_attr(0, srw.attr);

end if;

return (TRUE);

end;

0x01 graphic

Warto zaglądnąć do pakiety SRW nie tylko wtedy kiedy programowo zmieniamy kolory czy czcionkę ale również wtedy kiedy chcemy wyświetlić w czasie wykonywania raportu wiadomość czy wykonać w bazie instrukcje DML (np. po to aby odnotować w jakiejś tablicy fakt uruchomienia raportu).

Uruchamianie raportu z parametrem

Parametr uruchomienia raportu.

Raport może sam pobierać swoje parametry z formatki wywołania raportu lub może je otrzymać z .zewnętrznego uruchamiającego go programu. Wtedy formatka parametrów nie jest pokazywana.

Zapytanie z parametrem

Nowy parametr użytkownika możemy utworzyć w nawigatorze obiektów lub podać w zapytaniu.

0x01 graphic

Warto zwrócić uwagę, że przed PARAMETR_DEPTNO występuje dwukropek.

SELECT *

FROM emp

WHERE deptno = :PARAMETR_DEPTNO;

Jeżeli podaliśmy parametr bezpośrednio w zapytaniu Raports_Designer stworzy go automatycznie. Trzeba jedynie zwrócić uwagę czy jest on oczekiwanego przez nas typu.

0x01 graphic

Tak utworzony parametr pojawia się na formatce uruchomienia raportu.

0x01 graphic

To rozwiązanie w zupełności wystarcza jeżeli raport jest gdzieś indziej podpinany. Jeżeli jednak raport funkcjonuje jako samodzielny program. Warto byłoby dołożyć do niego rozwijaną listę z której użytkownik wybierałby departament dla którego chce uruchomić raport. W tym celu musimy wrócić do parametrów uruchomienia raportów i wejść w jego właściwości.

0x01 graphic

Jeżeli zaznaczymy opcję SELECT okienko zmieni swoja postać.

0x01 graphic

Teraz mamy możliwość wpisania zapytania. Oraz dwie opcje do wyboru. Możliwości użytkownika są ograniczone jedynie do tego co wybiera lista (Restrict List to Predetermined Values) i Hide First Column jeżeli nie chcemy pokazywać użytkownikowi kluczy. Jeżeli chcemy aby użytkownik miał możliwość pominąć ten parametr i uruchamiać raport dla wszystkich departametów musimy odznaczyć Restrict List to Predetermined Values i zmodyfikować główne zapytanie raportu:

SELECT *

FROM emp

WHERE

(deptno = :PARAMETR_DEPTNO OR :PARAMETR_DEPTNO is null);

Teraz z okienka parametrów można skasować wartość w polu DEPTNO i raport uruchomi się dla wszystkich.

0x08 graphic

Druga możliwość to zmodyfikowanie listy przy użyciu UNION tak aby pojawiała się dodatkowa pusta wartość.

Przekazanie fragmentu zapytania

Druga możliwość przekazania sparametryzowania raportu to przekazywanie fragmentu zapytania. Tym razem trzeba obowiązkowo rozpocząć od nawigatora obiektów. Dodajemy nowy parametr np. o nazwie PARMETR_DOKLEJENIE typu znakowego od razu ustawiając jego wartość np. na 1=1.

Teraz możemy rozbudować raport z poprzednich stron. W zapytaniu dodajemy:

SELECT *

FROM emp

WHERE

(deptno = :PARAMETR_DEPTNO OR :PARAMETR_DEPTNO is null) and

(&PARAMETR_DOKLEJENIE);

Wartość domyślna(1=1) używana jest na etapie parsowania i sprawdzania poprawności instrukcji SELECT.

W czasie uruchamiania raportu, zawsze poprawną wartość domyślną zamieniamy na interesujący nas warunek.

0x01 graphic

0x01 graphic

Ten sposób jest czasem wykorzystywane przez programistów przy czym użytkownik widzi np. pewne grup klasyfikacji klientów, wybiera je z listy, a jest to równoznaczne z wykonaniem pewnego zapytania do tablicy w której trzymane są fragmenty zapytań. Oczywiście należy jeszcze zadbać o używanie tych samych aliasów i o to aby grupy klasyfikacji itp. pokazywały się odpowiednio do treści zapytania zawartego w raporcie.

Suplement

W tym rozdziale przedstawione zostaną zagadnienia które nie zmieściły się poprzednich rozdziałach.

Data bieżąca

Źródłem częstego zaskoczenia programisty jest wbudowana data bieżąca. Jeżeli sięgniemy po pole typu 0x01 graphic
w edytorze rozkładu, to w polu tym jako źródło wypełniania możemy podać &Current Date.

0x01 graphic

Jeżeli zarówno nasz serwer jak i komputer mają zgodnie i prawidłowo ustawiony czas nigdy nie zauważymy, że nie jest to niestety data z serwera ale data z systemu operacyjnego. Jeżeli użytkownik z jakiś względów utrzymuje na komputerze niewłaściwą datę (np. ze względu na pirackie oprogramowanie) to drukuje raporty ze złą datą. Zdarzają się też przypadki, że użytkownicy którzy posługiwali się takimi raportami celowo cofali datę aby przygotować raporty które powinny być wydrukowane wcześniej.

Aby zmusić raport do pisania właściwej daty z serwera należy napisać samodzielnie funkcję (kolumnę formuły), która wykorzysta:

select sysdate

into ....

from dual;

Tryb dopasowania

W czasie dostosowywania rozkładu domyślnego do naszych potrzeb tracimy wiele czasu na rozciąganie ramek. Pracę z ramkami możemy jednak znacznie uprościć, jeżeli skorzystamy z Trybu Dopasowania. Ikonka odpowiedzialna za ten tryb ma dwie postaci:

0x01 graphic
- włączony tryb dopasowania

0x01 graphic
- wyłączony tryb dopasowania.

Zanim projektant raportu zapozna się z tymi dwoma ikonkami (czasami nie następuje to nigdy) rozciąga ramki aby zrobić miejsce na nowy obiekt. Okazuje się, że jeżeli tryb dopasowania jest włączony, przesuwany obiekt sam toruje sobie drogę spychając lub powiększając obiekty które stoją na jego drodze. Obiekt cofając się działa w sposób odwrotny.

W domyślnym, a więc wyłączonym trybie dopasowania przesuwane pole tekstowe dosuwa się do ograniczającej jego grupę ramki i dalej nie może się przesunąć.

Rozkład listowy

Rozkład listowy do taki w którym występuje pewien tekst w którym pojawiają się nazwy pól poprzedzone znakiem &. W czasie wykonywania raportu pola te wypełniają się za pomocą pól, które są poziomo zmienne i ukryte. Najczęściej element ten stosowany jest do drukowania nagłówków i stopek raportów.

Na poniższym rysunku znajduje się pewien tekst a obok niego trzy ukryte, poziomo zmienne pola.

0x01 graphic

Warto zwrócić uwagę że fragmenty tekstu wklejanego „dziedziczą” własności z obiektów ukrytych, nazwisko pojawia się pogrubione, a job i hiredate - kursywą.

0x01 graphic

Kierunek tekstu

Ponieważ pola 0x01 graphic
nie chcą się obracać (rotate), a czasem chcielibyśmy wydrukować je w pionie , można wykorzystać w tym celu pola tekstowe(T) które pozwalają się obracać.

Wyzwalacze Raportu

Istnieje pięć sytuacji które możemy obsłużyć w czasie wykonywania raportu. Są to po kolei:

Before Parameter Form

After Parameter Form

Before Report

Between Pages

After Report

Dzięki tym wyzwalaczom możemy kontrolować kiedy z jakiego komputera były uruchamiane raporty. W wyzwalaczach tych możemy stosować instrukcje DML, wykonanie instrukcji DDL wymaga użycia pakietu.

function BeforeReport return boolean is

V_instrukcja varchar2(150);

V_numer varchar2(5);

begin

SELECT to_char(dziennik_seq.nextval)

INTO V_numer

FROM dual;

V_instrukcja := 'CREATE table dziennik'||V_numer||'(dzi_id NUMBER,kto VARCHAR2(40),kiedy DATE)';

--Ponizej wykonuje instrukcje na serwerze tworzac tymczasowa tabele ...

SRW.do_sql(V_instrukcja);

--Ponizej bezposrednio wykonuje instrukcje DDL(insert,commit)

INSERT INTO dziennik values(dziennik_seq.nextval,' PRZED RAPORTEM',SYSDATE);

commit;

return (TRUE);

end;


Wyjątkiem od tej sytuacji może być struktura klient-serwer raportów- serwer. Tego typu strukturę stosuje się w przypadku gdy klient jest mało wydajny.

Efekt łamania i obliczania podsumowań jest dostępny w skryptach SQL+ - łamanie instrukcją BRAKE ON, a obliczanie instrukcją COMPUTE jednak ze względu na istnienie programów graficznych są one prawie zupełnie niewykorzystywane.

NP. SELECT job, max(sal) FROM emp GROUP BY job; - nie możemy w tej instrukcji dopisać kolumny ename po słowie SELECT .... - w koneksie grupy ta informacja jest niedostępna.

Można wyobrazić sobie raport macierzowy dla trzech i więcej wymiarów jednak ze względu na dwuwymiarowość papieru może być to tylko np. raport gdzie każdy nowa wartość zmiennej Z spowoduje np. otwarcie nowej strony raportu.

Na następnych stronach będzie opisana konstrukcja raportu macierzowego wyłącznie na jednym zapytaniu.

UNION - domyślnie UNION jest to UNION DISTINCT czyli suma zbiorów w sensie znanym na z matematyki, nie domyślne zachowanie UNION można by uzyskać poprzez zastosowanie UNION ALL wtedy w sumie elementy powtarzające się pozostałyby.

0x01 graphic
Podstawy

Budowa raportów 0x01 graphic

Strona 2

Strona 3

0x01 graphic
Podstawy

Podstawy 0x01 graphic

Strona 47

0x01 graphic



Wyszukiwarka

Podobne podstrony:
Podstawy budowy raportów w Oracle Reports 2 5 ćwiczenia Materiały Szkoleniowe
kurs oracle podstawy sql 4FTEY3ZEMDW5YMC7JVMVHLV3IJIVX2DSWAXXO3Y
Pages from Kurs Oracle transakcje
Kurs Php & Mysql, Informatyka, ● PHP, MySQL, ORACLE
Kurs ?ministracja Oracle
KURS ETYKI
Choroba hemolityczna p odu na kurs
zapotrzebowanie ustroju na skladniki odzywcze 12 01 2009 kurs dla pielegniarek (2)
kurs
wady postawy kurs
ostre białaczki 24 11 2008 (kurs)
AT kurs analityka giełdowego 3
Pielęgniarki kurs wersja 6 V 01
Kurs 03 Dynamika

więcej podobnych podstron