Język REPORT

Transkrypt

Język REPORT
Praca zbiorowa
Język REPORT
Dla systemu Windows—Linux
Wydanie czternaste
Macrologic SA, Warszawa, styczeń 2014
Praca zbiorowa
Xpertis: Język REPORT; Dla systemu Windows—Linux
Wydanie czternaste
© Copyright by Macrologic SA, styczeń 2014
Macrologic SA
ul. Kłopotowskiego 22
03-717 Warszawa
tel. +48 (22) 511-8-115
fax +48 (22) 511-8-116
http://www.macrologic.pl
Podręcznik języka Report jest jednym z najstarszych wydawnictw firmy MacroSoft — Macrologic. Przez dwadzieścia lat życia był wielokrotnie aktualizowany. Dziś trudno jest ustalić, kto
i w jakim stopniu przyczynił się do powstania tego dzieła.
Redakcja: Tomasz Kossut, Krzysztof Zawisławski
Skład: Andrzej Odyniec, Krzysztof Odyniec
Druk: Niniejszy podręcznik został przygotowany w wersji elektronicznej i nie jest publikowany przez wydawcę w postaci papierowej a jedynie na nośnikach komputerowych oraz przez
Internet.
Macrologic oraz Xpertis są znakami handlowymi Macrologic SA.
Prawa do wszystkich występujących tutaj znaków handlowych należą do odpowiednich właścicieli. Ze względu na charakter publikacji i niekiedy częste używanie w tekście znaków handlowych, zamiast umieszczania po każdym wystąpieniu takiego znaku — symbolu znaku handlowego (TM ) lub zastrzeżonego znaku handlowego (®) utrudniającego czytanie, wszystkie znaki handlowe wyróżniamy pisząc je z wielkiej litery w trosce o przejrzysty styl wydawniczy i bez
intencji jakiegokolwiek ingerowania w znak lub naruszania praw z nim związanych.
ISBN: Publikacjom elektronicznym nie przydziela się
Spis treści
Uwagi wstępne
v
Opis ogólny języka Report
vii
I
1
1
4
5
5
5
14
16
17
18
20
21
22
22
22
23
24
25
26
28
28
30
30
30
Konstrukcje języka
1 Obiekty języka Report . . . . . . . .
2 Definiowanie wzorca . . . . . . . .
2.1 TITLE . . . . . . . . . . . . .
2.2 VERSION . . . . . . . . . . .
2.3 PRINTER . . . . . . . . . . .
3 Formatowanie wyników . . . . . . .
4 Rozmieszczenie wyników w wierszu
4.1 CENTER . . . . . . . . . . .
4.2 JUSTIFY . . . . . . . . . . . .
5 Rozmieszczenie wyników na stronie
5.1 LINE . . . . . . . . . . . . . .
5.2 SKIP . . . . . . . . . . . . . .
5.3 PAGE . . . . . . . . . . . . .
5.4 MARGIN . . . . . . . . . . .
5.5 HEADER . . . . . . . . . . .
5.6 FOOTER . . . . . . . . . . .
5.7 SIGNATURE . . . . . . . . .
5.8 MAXPAGE . . . . . . . . . .
5.9 ENTIRE . . . . . . . . . . . .
5.10 DIRECT . . . . . . . . . . . .
6 Zmiana czcionki i wysuwu . . . . .
6.1 FONT . . . . . . . . . . . . .
6.2 SPACE . . . . . . . . . . . . .
i
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
ii
Spis treści
7 Konstrukcje graficzne . . . .
7.1 DEFINEFONT . . . .
7.2 COLOR . . . . . . . .
7.3 BITMAP . . . . . . . .
7.4 IMAGE . . . . . . . .
8 Drukowanie w trybie graphic
8.1 GRAPHIC . . . . . . .
8.2 GRAPHICTEXT . . .
8.3 GRAPHICFONT . . .
8.4 GRAPHICIMAGE . .
9 Konstrukcje sterujące . . . .
9.1 IF . . . . . . . . . . .
9.2 WHILE . . . . . . . .
9.3 FOR . . . . . . . . . .
9.3.1 INDEX . . . . .
9.3.2 PREFIX . . . .
9.3.3 FROM, TO . . .
9.3.4 FILTER . . . .
9.3.5 SELECT . . . .
9.4 FIRST . . . . . . . . .
9.5 ADD . . . . . . . . . .
9.6 TOTAL . . . . . . . .
9.7 EXIT . . . . . . . . . .
10 Podprogramy i włączenia . .
10.1 MACRO . . . . . . . .
10.2 SUBSTITUTE . . . . .
10.3 CLEAR . . . . . . . .
10.4 INCLUDE . . . . . . .
10.5 REP . . . . . . . . . .
11 Prolog i epilog sprawozdania
11.1 BEGIN . . . . . . . . .
11.2 END . . . . . . . . . .
12 Komentarze . . . . . . . . .
12.1 COMMENT . . . . . .
II
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
31
31
34
36
37
38
39
41
42
43
45
45
46
49
50
50
50
51
52
55
56
57
64
65
65
66
68
68
69
70
70
71
73
73
Kompilacja wydruków
75
1 Translatory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
III Tryby drukowania
77
iii
Spis treści
IV Ograniczenia systemu
79
iv
Spis treści
Uwagi wstępne
W opisie zastosowano poniższe konwencje typograficzne ułatwiające odszukanie i identyfikację materiału.
— Na marginesach umieszczono gdzieniegdzie następujące ikony:
Ta ikona wskazuje przytoczone w podręczniku przykłady.
Ta ikona wskazuje szczególnie istotne wskazówki i ostrzeżenia przed błędami najczęściej popełnianymi przez użytkowników.
Ta ikona wskazuje fragmenty podręcznika, które odnoszą się do przepisów prawa oraz praktycznych rozwiązań proponowanych przez autorów
oprogramowania.
Ta ikona wyróżnia odsyłacze wskazujące podrozdziały, gdzie szerzej zostało opisane wybrane zagadnienie.
— Opisy funkcji oraz ich działania w wielu miejscach zostały zilustrowane
przykładami. Wykorzystane w nich dane mają na celu zademonstrowanie działania funkcji i algorytmów, nie stanowią żadnego odniesienia do
danych rzeczywistych.
v
vi
Uwagi wstępne
Opis ogólny języka Report
Język Report jest językiem programowania wysokiego poziomu. Służy do projektowania wzorców sprawozdań obrazujących zawartość bazy danych. W konstrukcjach języka wykorzystuje się wyrażenia języka Formula oraz definicje
schematów tabel stworzonych programem MacroBUILDER lub przez funkcję
tab_tmp(). Każdy wzorzec jest opisany w jednym zbiorze tekstowym. W jego treści można umieszczać dowolne znaki o kodach ASCII nie mniejszych
od kodu spacji oraz znak końca wiersza (reguła nie obowiązuje w konstrukcji {REP}, gdzie można umieszczać dowolne znaki). Zbiór może mieć dowolną nazwę, zgodną z konwencją danego systemu operacyjnego (Windows
lub Unix). Domyślnie przyjmowane jest rozszerzenie .rpm dla wydruków
oraz .rpi dla plików włączanych do wydruku. Przed uruchomieniem wydruku przygotowany wzorzec musi najpierw zostać skompilowany do postaci
binarnej przez funkcję języka Formula rep_tran() (por. opis) lub translator MacroREPORT (dla Windows report.exe). W wyniku powstają zbiory
z rozszerzeniem .rpt gotowe do wykonania. Użycie w wydruku niedozwolonych znaków (np. tabulacji lub dzwonka) spowoduje błąd podczas kompilacji: Niespodziewany znak. Generator sprawozdań, a więc moduł odpowiedzialny za tworzenie wydruków rozpocznie pracę, jeśli użyjemy funkcji
rep_exec(). Zostaną wtedy odszukane w katalogach wskazanych w zbiorze
z deklaracjami ścieżek wszystkie zbiory dyskowe o nazwach pasujących do maski podanej jako argument (z dodaniem rozszerzenia .rpt). Musimy też pamiętać, że raz uruchomiony generator musi zakończyć pracę (sterowanie musi
wrócić do miejsca wywołania), aby można go było uruchomić ponownie. Innymi słowy, nie jest możliwe rekurencyjne wywołanie generatora sprawozdań.
Próba takiego wywołania zakończy się błędem.
vii
viii
Opis ogólny języka Report
Rozdział I
Konstrukcje języka
1 Obiekty języka Report
Na wstępie omawiania tego języka podamy informacje dotyczące obiektów na
jakich język działa. Ogólnie, obiekty te dzielą się na teksty i konstrukcje języka.
Tekst jest ciągiem znaków w treści wzorca wydruku , nie zawierającym nawiasów klamrowych { i }. Teksty są dosłownie cytowane w wynikowym sprawozdaniu. Jeśli napiszemy następujący wzorzec:
Tekst jest ciągiem znaków w˜treści wzorca wydruku
.rpm, nie zawierającym nawiasów
klamrowych.
Teksty są dosłownie cytowane w˜wynikowym
sprawozdaniu.
to w wyniku otrzymamy na wydruku:
Tekst jest ciągiem znaków w˜treści wzorca wydruku
.rpm, nie zawierającym nawiasów
klamrowych.
Teksty są dosłownie cytowane w˜wynikowym
sprawozdaniu.
Teksty ze wzorca sprawozdania powielają się więc na wydruku. Jeśli chcemy, a tak jest najczęściej, umieścić na wydruku zmienną treść, musimy użyć
konstrukcji języka. Są one poleceniami wykonania jakichś czynności: formatowania i sterowania. Wszystkie konstrukcje języka Report są umieszczone w nawiasach klamrowych.
1
2
Rozdział I. Konstrukcje języka
Przykłady
{JUSTIFY}
{SPACE: ’c’}
{’Tak można zapisać znak { w˜treści sprawozdania’}
{PAGE}
Jeśli bezpośrednio po znaku { wystąpi jeden z poniższych identyfikatorów
będzie on traktowany jako słowo kluczowe języka Report:
ADD
BEGIN
BITMAP
CENTER
CLEAR
COLOR
COMMENT
DEFINEFONT
DIRECT
DO
ELIF
ELSE
END
ENTIRE
EXIT
FI
FILTER
FIRST
FONT
FOOTER
FOOTERLEFT
FOOTERRIGHT
FOR
FROM
HEADER
HEADERLEFT
HEADERRIGHT
IF
IMAGE
INCLUDE
INDEX
JUSTIFY
LINE
MACRO
MARGIN
MAXPAGE
OD
PAGE
PAGELEFT
PAGERIGHT
PREFIX
PRINTER
REP
SELECT
SIGNATURE
SKIP
SPACE
SUBSTITUTE
TITLE
TO
TOTAL
VERSION
WHILE
Jeśli pierwszym znakiem za { będzie jeden ze znaków:
< > , . + -
to dalsza konstrukcja będzie traktowana jako określenie pozycji lub formatu.
W pozostałych przypadkach tekst zawarty w nawiasach klamrowych będzie
traktowany jako wyrażenie języka Formula.
Przykłady Wiadomo, że SPACE jest słowem kluczowym języka. Użytkownik
powołał w języku Formula zmienną globalną SPACE. Następnie w treści wzorca
wydruku umieścił:
{SPACE :=’c’}
{SPACE:=’c’}
{SPACE:’c’}
I.1. Obiekty języka Report
Słowo SPACE jako słowo kluczowe stanowi część stałą zdania, po której musi
nastąpić część zmienna. Obie części muszą być oddzielone znakiem dwukropka. Co więcej, między słowem kluczowym, a dwukropkiem, nie może wystąpić
nic, nawet znak odstępu. Dlatego pierwszy wiersz jest błędny: za SPACE oczekiwano dwukropka, a znaleziono odstęp. W drugim wierszu dwukropek znalazł się za SPACE, lecz następnie wykryto znak = nie dozwolony przez składnię (por. opis {SPACE}). Znowu jest to błąd, tym razem jednak nie zostanie wykryty przez translator MacroREPORT. Błąd pojawi się podczas tworzenia wydruku, przy próbie interpretowania wyrażenia rozpoczynającego się od
=. W trzecim wierszu zdanie jest zapisane poprawnie: została ustawiona wartość odstępu międzywierszowego. Co jednak zrobić, aby zmiennej globalnej
SPACE przypisać wartość ’c’? Wystarczy napisać:
{ SPACE:=’c’}
Zwróćmy uwagę, że znak odstępu między { a SPACE wystarcza aby wiedzieć,
że w takim kontekście SPACE nie jest słowem kluczowym.
Oto warunki poprawnego zapisania słów kluczowych:
konstrukcje rozpoczyna znak otwierającego nawiasu klamrowego ({),
a kończy znak zamykającego nawiasu klamrowego (});
słowa kluczowe muszą być w zdaniach pisane bezpośrednio za znakiem {, stanowią one część stałą zdania;
za słowem kluczowym może wystąpić tylko znak dwukropka (:) albo
minusa (-) albo zamykającego nawiasu klamrowego (});
część zmienna konstrukcji, jeśli występuje, rozpoczyna się od znaku
dwukropka (:).
Część zmienna (jeśli występuje) parametryzuje konstrukcję rozpoczynającą się od słowa kluczowego. W części zmiennej może wystąpić dowolna sekwencja języka Formula albo stała określona przez składnię danego słowa kluczowego. Słowo kluczowe pisze się zawsze wielkimi literami. Konstrukcje traktowane jako wyrażenie języka Formula w tworzonym sprawozdaniu zastępowane są wartością danego wyrażenia.
3
4
Rozdział I. Konstrukcje języka
Przykłady
Poniższa formuła:
Liczba {
_b:=6+4;
_a:=_b/2;
_a
} spełnia równanie
2*x - 4 = 6
spowoduje wydrukowanie:
Liczba 5 spełnia równanie
2*x - 4 = 6
Jak widać, fragment ujęty w nawiasy klamrowe został zastąpiony przez 5 —
wynik formuły.
Konstrukcje tego typu są szczególnie wygodne do wyprowadzania zawartości bazy danych. Zdania ze słowami kluczowymi są przeznaczone do organizowania wyglądu wydruku i do tworzenia konstrukcji programowych (wybór,
iteracja, iteracja po tabeli, itp.).
Jeszcze jedna uwaga. W opisie konstrukcji języka będziemy używać literowych oznaczeń argumentów. W miejscu takiego argumentu może wystąpić
formuła, zwracająca wynik odpowiedniego typu, albo też stała. Niekiedy jednak formułę w takim kontekście będzie trzeba ograniczyć nawiasami klamrowymi — zaznaczymy to zawsze w naszym opisie.
2 Definiowanie wzorca
Pliki z wzorcami sprawozdań (*.rpm, *.rpi) mogą być kodowane w jednym z
dwóch standardów:
UTF-8
wtedy pierwsza linia pliku musi rozpoczynać się od znaków
:!UTF-8
(rejest liter jest istotny). Podane znaki mogą być ewentualnie poprzedzone znacznikiem BOM, czyli ciągiem znaków o kodach: 0xef 0xbb 0xbf.
Jeśli plik spełnia powyższy warunek, to będzie traktowany jako zapisany
w standardzie UTF-8. Pierwsza linia takiego pliku będzie ignorowana,
mazovia
jeśli plik nie spełnia warunków, aby był traktowany jako zapisany w standardzie UTF-8. Oznacza to, że pliki utworzone we wcześniejszych wersjach będą miały (bez modyfikacji) identyczne znaczenie.
I.2. Definiowanie wzorca
W przypadku wczytywania pliku zapisanego w standardzie UTF-8 mogą
pojawić się błędy, jeśli nie będzie on prawidłowo zakodowany.
Nazwy wspomnianych tu plików mogą zawierać znaki tylko o kodach
większych niż 31 i mniejszych niż 127.
2.1 TITLE
Pierwszą linią we wzorcu sprawozdania powinno być:
{TITLE: report_name}
Jako report_name umieszczamy tytuł — tekst, który będzie identyfikował
sprawozdanie w menu po wywołaniu rep_exec(). Operator będzie wybierał
z menu wydruk, wskazując stosowny tytuł. Konstrukcja ta może się znajdować
tylko w pierwszej linii sprawozdania. Jeśli nie zostanie użyta, zamiast tytułu
wyświetlona zostanie nazwa zbioru dyskowego .rpt razem ze ścieżką.
2.2 VERSION
Konstrukcja:
{VERSION: description}
pozwala na zdefiniowanie wersji danego wzorca wydruku. Argument
description może być dowolnym tekstem, który zostanie zwrócony
we wnętrzu sprawozdania po użyciu funkcji rep_ver() (poza sprawozdaniem funkcja jest niedostępna). Jeśli fraza {VERSION} nie została użyta we wzorcu wydruku, to wynikiem funkcji będzie ’ST’ (od słowa STANDARD). Konstrukcję we wzorcu sprawozdania może poprzedzać jedynie zdanie {TITLE}.
2.3 PRINTER
Po wybraniu wydruku, zanim rozpocznie się jego wykonywanie, system poszuka jeszcze jednego zbioru dyskowego, zawierającego definicję drukarki zapisaną w specjalnym formacie .prt (domyślnie standard.prt). Jego istnienie jest konieczne dlatego, żebyśmy mogli użyć tego samego wzorca wydruku nawet w wypadku zmiany drukarki. Zawarte są w nim właściwości oraz
sekwencje sterujące dla danego typu drukarki. Dotyczą one kroju i wielkości
pisma, odstępu międzywierszowego, zmiany strony, długości i szerokości strony, itd. Takie cechy drukarki nie muszą być znane osobie projektującej wydruk.
5
6
Rozdział I. Konstrukcje języka
Zobaczymy potem, że ma ona do czynienia jedynie z umownym, ogólnym,
sposobem zapisu żądanych parametrów wydruku, który zostanie później na
podstawie opisu drukarki przetłumaczony na odpowiednie sekwencje wysyłane na drukarkę. Jest możliwe dedykowanie danego sprawozdania na konkretną
klasę drukarek. Trzeba tylko we wzorcu wydruku wskazać odpowiedni zbiór
z opisem za pomocą konstrukcji:
{PRINTER: printer_name}
gdzie printer_name zastępujemy wyrażeniem w języku Formula zwracającym napis — nazwę zbioru z opisem drukarki (bez końcówki .prt). Domyślnie przyjęta zostanie nazwa ’standard’. System poszuka go w katalogu
wskazanym w zbiorze z deklaracją ścieżek. Konstrukcja może być umieszczana
tylko po zdaniach {TITLE} i {VERSION}.
Przykłady
Jeśli, napiszemy w wydruk1.rpm:
{TITLE: Katalog}
{VERSION: 8.10}
{PRINTER: ’epson’}
zaś w wydruk2.rpm:
{TITLE: Ponaglenia}
{VERSION: 8.10}
{PRINTER:
{? prot_key() = ’adm’ ||
’laser’
|| ’oki’
?}
}
to w pierwszym wypadku drukarka i jej właściwości będą określane przez zbiór
epson.prt, a w drugim — dla użytkownika o kluczu protekcji ’adm’ przez
laser.prt, dla pozostałych przez oki.prt.
Konstrukcja {PRINTER} może dodatkowo modyfikować pewne cechy zawarte w opisie drukarki. Pełna forma tej konstrukcji ma postać:
I.2. Definiowanie wzorca
7
{PRINTER:
printer_name,
nopanel,
viewon,
printon,
copy,
fontstd,
spacestd,
dummy1,
number_of_copies,
dummy2,
bottomline,
endpanelon,
phisical_margin,
margin_left,
margin_top,
margin_right,
margin_bottom,
signatureoff,
graphic,
paper_size
}
W miejscu każdego argumentu można podać wyrażenie języka Formula zwracające wartość odpowiedniego typu. Oto znaczenie poszczególnych argumentów:
printer_name
napis będący nazwą zbioru z opisem drukarki, domyślnie’standard’.
nopanel
0
chęć wykonania wydruku operator będzie potwierdzał w dialogu, w którym może dodatkowo zmienić wartości argumentów: printer_name, viewon, printon, copy, fontstd,
spacestd, number_of_copies, bottomline, signatureoff,
margin_left, margin_top, margin_right, margin_bottom (w dialogu pojawi się już obliczona wartość marginesu
od brzegu kartki);
8
Rozdział I. Konstrukcje języka
liczba różna od 0
dialog się nie pojawi.
Wartość domyślna pobierana jest z opisu drukarki określonego przez
printer_name.
viewon
liczba różna od 0
wydruk pojawi się na ekranie;
0
nie będzie wyświetlany na ekranie.
Wartość domyślna pobierana jest z opisu drukarki określonego przez
printer_name.
printon
liczba różna od 0
wydruk będzie skierowany na drukarkę;
0
nie będzie drukowany.
Wartość domyślna pobierana jest z opisu drukarki określonego przez
printer_name.
copy
liczba różna od 0
tworzony będzie plik do późniejszego wykorzystania poprzez
funkcję rep_copy();
0
plik nie będzie utworzony.
Wartością domyślną jest 0.
fontstd
napis składający się z jednej litery, oznaczający jeden ze zdefiniowanych
krojów pisma w opisie drukarki. Wskazany krój będzie używany jako
standardowy. Wartość domyślna pobierana jest z opisu drukarki określonego przez printer_name.
I.2. Definiowanie wzorca
spacestd
napis składający się z jednej litery, oznaczający jeden ze zdefiniowanych
odstępów międzywierszowych w opisie drukarki. Wskazany wysuw będzie używany jako standardowy. Wartość domyślna pobierana jest z opisu drukarki określonego przez printer_name.
dummy1
wartość argumentu jest ignorowana.
number_of_copies
liczba egzemplarzy. Wartością domyślną jest 1.
dummy2
wartość argumentu jest ignorowana.
bottomline
liczba różna od 0
aktualnie drukowany wiersz wyświetlany będzie w najniższej linii
ekranu;
0
nie będzie wyświetlany.
Wartość domyślna pobierana jest z opisu drukarki określonego przez
printer_name.
endpanelon
0
wydruk skierowany na drukarkę wydrukuje się bez konieczności
zatwierdzania;
liczba różna od 0
pojawi się dodatkowy dialog przed rozpoczęciem drukowania
z możliwością wyboru opcji: drukowania do pliku, drukowania zadanych stron, trybu tekstowego, ilości i sortowania kopii — dialog
ten pojawi się zawsze przy wyborze drukowania z menu podglądu
wydruku.
Wartością domyślną jest 1.
phisical_margin
9
10
Rozdział I. Konstrukcje języka
0
obszar do drukowania, będzie dodatkowo pomniejszony o obszar
nie do drukowania ustawiony dla drukarki w systemie operacyjnym;
liczba różna od 0
margines będzie równy większej z liczb — przypisanej wartości
marginesu i odpowiadającej mu wartości obszaru nie do drukowania.
Wartość domyślna pobierana jest z opisu drukarki określonego przez
printer_name.
margin_left
lewy margines w milimetrach. Wartość domyślna pobierana jest z opisu
drukarki określonego przez printer_name.
margin_top
górny margines w milimetrach. Wartość domyślna pobierana jest z opisu drukarki określonego przez printer_name.
margin_right
prawy margines w milimetrach. Wartość domyślna pobierana jest z opisu drukarki określonego przez printer_name.
margin_bottom
dolny margines w milimetrach. Wartość domyślna pobierana jest z opisu drukarki określonego przez printer_name.
signatureoff
0
sygnatura będzie umieszczana na wydruku (o ile została zdefiniowana);
liczba różna od 0
sygnatura nie będzie wyliczana, ani umieszczana na stronie.
Wartość domyślna pobierana jest z opisu drukarki określonego przez
printer_name.
graphic
I.2. Definiowanie wzorca
0
11
wyłączenie graficznych konstrukcji języka (nie będą interpretowane: zmiana kroju czcionki, ustawienie koloru tekstu i tła, włączanie
grafiki) oraz włączenie trybu drukowania tekstu z pozycjonowaniem każdego znaku (znaki drukowane w kolumnach);
liczba różna od 0
interpretacja elementów graficznych i tryb drukowania z pozycjonowaniem całych napisów (dla wyłączonej opcji Tylko tekst).
Wartość domyślna pobierana jest z opisu drukarki określonego przez
printer_name,
paper_size
rozmiar kartki na jaką przygotowywany jest wydruk. Dopuszczalne są
następujące wartości, określające format strony wydruku:
’A0’ ’A1’ ’A2’ ’A3’ ’A4’ ’A5’ ’A6’ ’A7’ ’A8’ ’A9’ ’A10’
’B0’ ’B1’ ’B2’ ’B3’ ’B4’ ’B5’ ’B6’ ’B7’ ’B8’ ’B9’ ’B10’
’C3’ ’C4’ ’C5’ ’C6’
’DESIGNATED_LONG’ ’LETTER’ ’LEGAL’ ’5X7’ ’8X10’
’NUMBER_9_ENVELOPE’ ’NUMBER_10_ENVELOPE’ ’NUMBER_11_ENVELOPE’
’NUMBER_12_ENVELOPE’ ’NUMBER_14_ENVELOPE’
’6X9_ENVELOPE’ ’7X9_ENVELOPE’ ’9x11_ENVELOPE’ ’9x12_ENVELOPE’
’10x13_ENVELOPE’ ’10x14_ENVELOPE’ ’10X15_ENVELOPE’
Dodatkowo można użyć każdą z powyższych wartości z dodaną spacją
i słowem landscape. Oznaczać to będzie, że strona o danym formacie drukowana będzie poziomo. Czyli np. ’A4 landscape’ oznacza
stronę o rozmiarze A4 o orientacji poziomej.
W przypadku określenia rozmiaru strony należy również podać wartości
marginesów (można podać 0, nie można natomiast pominąć ani ustalić
wartości mniejszej niż 0). Dodatkowo parametr phisical_margin musi
przyjąć wartość różną od 0.
Jeśli rozmiar kartki nie został określony, to wydruik będzie składany na
kartce o rozmiarze i marginesach podanych w panelu wydruku. W przeciwnym przypadku, wydruk będzie tworzony dla określonego rozmiaru papieru
i marginesów w zdaniu ıPRINTER. Dzięki temu wydruk będzie przygotowywany na konkretny rozmiar kartki z uwzględnieniem marginesów określonych
w zdaniu PRINTER. Jeśli użytkownik podczas tworzenia wydruku ustawi inne
12
Rozdział I. Konstrukcje języka
marginesy lub określi inne wymiary papieru w taki sposób, że wydruk nie mieściłby się w określonych rozmiarach, to zostanie przesunięty i przeskalowany
tak, aby był cały widoczny. Nie dopuszcza się jednak, aby wydruk po przeskalowania był mniejszy niż 40% rozmiaru wydruku źródłowego. W przypadku,
gdyby wydruk musiał być bardziej pomniejszony, użytkownik zostanie poproszony o zmianę marginesów lub rozmiaru kartki podczas próby zatwierdzenia
panelu wydruku.
Jeśli wydruk z określonym rozmiarem papieru zostanie zapisany do kopii,
to podczas drukowania z kopii będą podpowiadane ustawienia marginesów
określone ze zdania {PRINTER: }. Dopuszczalna jest wtedy zmiana drukarki i marginesów. Jeśli wydruk nie będzie się mieścił w wyznaczonym obszarze,
to zostanie przeskalowany i ewentualnie przesunięty. Dotyczy to tylko wydruku z kopii robionego z panelu wydruku (w dialogu po rep_copy nie można
zmieniać rozmiaru marginesów). Domyślnie (przy pominięciu argumentu lub
przekazaniu pustego napisu) wydruk jest tworzony na kartce o rozmiarze wynikającym z ustawień w zdaniu PRINTER. Dla przykładu, jeśli w zdaniu PRINTER podamy:
{PRINTER: ,,,,,,,,,,,,1,20,20,20,20,1,1,’A4’}
czyli dwa centymetry marginesu z każdej strony, to wydruk będzie tworzony na obszarze kartki A4, pomniejszonym o 4 centymetry w pionie i w poziomie.
Przypuśćmy, że użytkownik wybierze dla wydruku kartkę A4 i poda lewy
i górny margines równy 3 cm, zaś prawy i dolny po 1 cm. Rozmiar wydruku
nie jest zatem mniejszy od obszaru projektu wydruku, zatem skalowania nie
będzie. Różnią się natomiast podane marginesy podane w panelu i w projekcie
wydruku, zatem wydruk będzie przesunięty tak, aby marginesy były takie, jakie
zostały podane w panelu. W przykładzie będzie to przesunięciu o 1 cm w dół
i w prawo.
Jeśli użytkownik podał lewy margines równy 3 cm, zaś pozostałe 2 cm, to
obszaru wydruku byłby węższy niż w projekcie wydruku. W takim przypadku wydruk będzie nieco pomniejszony w stosunku do projektu, jednak skład
będzie identyczny. Jeśli rozmiar strony nie byłby określony, to wiersze mogłyby być zawijane i strona wyglądałaby inaczej. Oprócz przeskalowania wydruk
będzie przesunięty tak, aby obszar wydruku rozpoczynał się 3 cm od lewej krawędzi kartki i 2 cm od górnej krawędzi.
Jeśli rozmiar kartki jest zdefiniowany w zdaniu PRINTER, to po wywołaniu
rep_exec z parametrem no_printer równym 1 wydruk będzie składany na
podany rozmiar (zamiast domyślnego formatu A4).
I.2. Definiowanie wzorca
Po pierwszym wykonaniu danego wydruku ustawienia niektórych parametrów zapisywane są w pliku printer.ini. Są to parametry:
— printer_name
— margin_left
— margin_top
— margin_right
— margin_bottom
Plik umieszczany jest w katalogu z kopiami. Przy kolejnym wykonaniu
sprawozdania program odczytuje z niego wartości parametrów dla odpowiedniego wzorca i nie pobiera ich już z opisu drukarki ani z konstrukcji
{PRINTER}. Należy o tym pamiętać jeżeli dokonujemy zmian (związanych
z ustawieniami drukarki) we wzorcu, który był już w danym systemie wykonywany. Parametry te można zmienić w panelu wydruku (jeśli panel jest dostępny).
Przykłady Jeżeli w pliku podsum.rpm umieścimy następującą linię:
{PRINTER: ,1,1,0,,,,,,,,,1,15,15,15,15,,1}
to po wywołaniu rep_exec(’podsum’) wynik sprawozdania pojawi się na
ekranie bez konieczności wykonania dodatkowych akcji przez operatora —
gwarantuje to drugi i trzeci argument, natomiast czwarty argument gwarantuje, że treść sprawozdania nie będzie wysyłana na drukarkę. Dodatkowo dziewiętnasty parametr zapewnia możliwość korzystania z konstrukcji graficznych
(dla wyłączonej opcji Tylko tekst w sterowniku drukarki). Parametry od trzynastego do siedemnastego ustawiają wartości marginesów na 15 mm od brzegu kartki każdy (o ile zdefiniowany dla drukarki obszar nie do drukowania nie
jest większy). Zwróćmy uwagę, że po pierwszym wykonaniu wydruku w trybie
graficznym, zmiana parametrów od trzynastego do siedemnastego w zdaniu
{PRINTER} nie wpłynie na wydruk (ustawienia marginesów zapisane będą
w pliku printer.ini).
13
14
Rozdział I. Konstrukcje języka
3 Formatowanie wyników
Wyniki wyprowadzane na drukarkę (drukowane) są ciągami znaków. Oznacza
to, że jakiegokolwiek typu jest wartość obiektu, która ma być wydrukowana, to
dla potrzeb wydruku musi ona zostać zamieniona do postaci znakowej. Jeśli
wypisujemy ciąg znaków — sprawa jest prosta: należy wypisać po kolei tworzące go znaki. Jeśli chcemy wypisać wyrażenie innego typu, musimy dokonać
konwersji do postaci znakowej. Mówimy, że wyniki trzeba sformatować. Umiemy już dokonywać konwersji typów dzięki operatorom języka Formula. Poznamy teraz inny sposób — formatowanie wyników konstrukcją języka Report.
Jeśli pierwszym znakiem za { jest kropka, oznacza to, że liczba bezpośrednio
za kropką określa numer formatu. Formatowany będzie wynik wyrażenia języka Formula, które jest umieszczone pomiędzy numerem formatu, a znakiem
}. Sposób formatowania zależy od typu zwracanego przez wyrażenie:
DATE
sposób formatowania określa poniższa tabelka:
format
postać wyniku
1
rrrr/mm/dd
2
rrrr.mm.dd
3
dd/mm/rrrr
4
dd.mm.rrrr
5
mm.dd.rrrr
6
d mmmmmm rrrr
7
tttt, d mmmmmm rrrr
8
mmmmmm rrrr
TIME
sposób formatowania określa poniższa tabelka:
format
postać wyniku
1
gg:mm
2
gg:mm ampm
3
gg:mm:ss
4
gg:mm:ss ampm
NUMBER
numer formatu określa precyzję — liczbę cyfr znaczących po kropce
dziesiętnej. Format 99 oznacza, że wynik będzie przedstawiony w no-
I.3. Formatowanie wyników
tacji naukowej. Jeśli po znaku { zamiast kropki użyjemy przecinek, tysiące będą oddzielone przecinkami, zaś część dziesiętna kropką. Dodatkowo kropkę (lub przecinek) można poprzedzić znakiem + lub -. Plus
oznacza, że liczba zawsze będzie poprzedzona znakiem (normalnie tylko
liczby ujemne są pisane ze znakiem). Z kolei minus powoduje, że tylko
liczby nieujemne będą poprzedzone znakiem.
STRING
numer formatu nie ma wpływu na sposób wyprowadzenia tekstu na wydruku.
VOID, DICT
typ pusty i typy słownikowe: złączenia, obiekty nie mają reprezentacji
tekstowej. Wyrażenia tych typów nie pojawią się na wydruku bez względu na numer formatu.
Przykłady
{.3 date(2000,1,1)}
{.7 date(2003,4,4)}
{.2 time(16,30)}
spowoduje wypisanie:
01/01/2000
piątek, 4 kwiecień 2003
4:30 pm
Użycie konstrukcji:
{.2 pi}
{.99 123.456}
{,4 12345678901.23456}
da w wyniku:
3.14
1.23456e2
12,345,678,901.2346
Po sformatowaniu tabelki:
15
16
Rozdział I. Konstrukcje języka
Znak
Wynik
0
> 0
< 0
=========================
nic
{ 0
}
{ 2
}
{ -5 }
+
{+.0 0}
{+.0 2 }
{+.0 -5}
-
{-.0 0}
{-.0 2}
{-.0 -5}
na wydruku otrzymamy:
Znak
Wynik
0
> 0
< 0
=========================
nic
0
2
-5
+
0
+2
-5
-
0
+2
5
Liczba oznaczająca format nie musi być stałą całkowitoliczbową. Może być
wyrażeniem typu NUMBER, jednak wtedy całe wyrażenie musi być w nawiasach klamrowych.
Przykłady Jeśli w zmiennej format będzie przechowywany numer formatu obowiązujący dla dat, zaś w zmiennej prec żądana precyzja dla liczb na
wydruku, to fragment:
Dnia {.{format} date} stwierdzono,
że liczba pi wynosi {.{prec} pi}
będzie sformatowany zgodnie z bieżącymi wartościami zmiennych format
i prec. Należy pamiętać, że przy określaniu formatu nie można wstawić spacji
ani przed, ani za kropką.
4 Rozmieszczenie wyników w wierszu
Rozpocznijmy od prostego przykładu. Dla ustalonego rekordu katalogu książek zawartego w tabeli KATAL, wypiszemy jej sygnaturę (pole ID), tytuł książki
(pole TYTUŁ) oraz jej cenę.
{KATAL.ID} {KATAL.TYTUŁ} {.2 KATAL.CENA}
17
I.4. Rozmieszczenie wyników w wierszu
Powyższa linia zapewnia, że wszystkie trzy informacje o książce zostaną wypisane w jednym wierszu i będą oddzielone od siebie spacją. Nie można jednak
nic powiedzieć o numerach kolumn, od których będą wypisywane poszczególne pola — zależy to od zawartości poszczególnych pól rekordu. Do pełnego
zapanowania nad postacią wiersza wydruku potrzebna jest jeszcze możliwość
podania pozycji w wierszu, od której ma być drukowany wynik formuły zdania
formatującego. Język Report daje taką możliwość. Popatrzmy na następujący
wzorzec wiersza:
{<1 KATAL.ID}{<10 KATAL.TYTUŁ}{>50.2 KATAL.CENA}
dla jednego z rekordów tabeli KATAL otrzymamy:
SN0009
Poezje
1.00
Opis formatu może więc rozpoczynać się od wskazania pozycji. Poprzedzenie jej znakiem < oznacza dorównanie wyprowadzanego tekstu do podanej
kolumny z lewej, jeśli pozycja poprzedzona zostanie znakiem >, to wyprowadzany tekst dorównany będzie do podanej kolumny z prawej. Naturalną praktyką jest dosuwanie ciągów znakowych do lewej, a liczb — do prawej strony.
Można również wynik umieścić pośrodku lub wyjustować, między podanymi
skrajnymi pozycjami w wierszu, podając zarówno lewy, jak i prawy skraj dla
pola:
{<1>50 ’DANE Z REKORDU’}
{<1 KATAL.ID}{<10 KATAL.TYTUŁ}{>50.2 KATAL.CENA}
co da na wydruku:
DANE Z REKORDU
SN0009
Poezje
1.00
Na to, czy tekst będzie pośrodku czy zostanie wyjustowany mają wpływ
następujące konstrukcje: {CENTER} i {JUSTIFY}.
4.1 CENTER
Ustawienie trybu wyśrodkowania tekstu w konstrukcji {< > } uzyskujemy
poprzez zdanie:
{CENTER}
Jest to tryb domyślny, ale musimy go użyć, jeżeli wcześniej użyta została konstrukcja {JUSTIFY}.
18
Rozdział I. Konstrukcje języka
4.2 JUSTIFY
Przestawienie trybu formatowania tekstu w konstrukcji {< > } na justowanie otrzymujemy po użyciu zdania:
{JUSTIFY}
Zostaną dostawione odstępy pomiędzy wyrazami tak, aby pierwszy zaczynał
się w pierwszej z podanych kolumn, zaś ostatni kończył się na drugiej z podanych kolumn. Dla tekstów jednowyrazowych (bez spacji) wyraz będzie wyrównany do lewej, z wypełnieniem spacjami z prawej strony.
Przykład z wyjustowaniem linii:
{JUSTIFY}
{<1>50’DANE Z REKORDU TABELI KATALOG’}
{<1 KATAL.ID}{<10 KATAL.TYTUŁ}{>50.2 KATAL.CENA}
da w wyniku:
DANE
SN0009
Z
REKORDU
TABELI
Poezje
KATALOG
1.00
Jak dotąd pozycję pola określaliśmy podając bezwzględny numer kolumny. W języku Report istnieje możliwość określania kolumny względem pozycji
ostatnio wydrukowanego pola. W takim przypadku przed numerem piszemy
znak +. Wtedy podana wartość liczbowa będzie dodana do numeru pozycji
określonej w poprzednim polu. Jeśli poprzednie pole miało określone zarówno lewy i prawy skraj (było umieszczane w środku lub justowane), to w tym
przypadku podana wartość będzie dodawana do kolumny, w której został wydrukowany ostatni znak pola (dla trybu {JUSTIFY} będzie to zawsze prawy
skraj, dla trybu {CENTER} jeśli w polu był wypisywany pusty ciąg znaków
będzie to średnia ze skrajów). Jeśli pole jest pierwsze w wierszu, to numer poprzedniej pozycji wynosi 1. Nasz przykład możemy więc zapisać:
{<+0 KATAL.ID} {<+9 KATAL.TYTUŁ
} {>+{55}.2 KATAL.CENA}
Możemy także przed numerem pozycji użyć znaku -. W tym przypadku numer kolumny będzie obliczony jako różnica numeru kolumny, w której byłoby
drukowane bieżące pole (gdybyśmy nie podali żadnej pozycji) oraz podanej za
znakiem - liczby. Zmniejszenie numeru kolumny może mieć miejsce jedynie
wtedy, gdy poprzedzające znaki na wydruku są spacjami. Można tę konstrukcję
wykorzystać do przesunięcia pola w lewą stronę na wydruku, jeśli poprzedzające pola wyprowadzały puste ciągi znaków. Dla wierszy:
I.4. Rozmieszczenie wyników w wierszu
{<1 ’Tytuł:’} {<10 KATAL.TYTUŁ} { ’ <<’}
{<1 ’Tytuł:’} {<10 KATAL.TYTUŁ} {<-10 ’ <<’}
jeśli KATAL.TYTUŁ zawiera pusty ciąg znaków, wynik będzie wyglądać jak na
wydruku:
Tytuł:
<<
Tytuł: <<
Pozycja jest określana, jak widać, przez podanie znaku < lub > i stałej liczbowej równej numerowi kolumny. Można zamiast stałej podać wyrażenie typu NUMBER umieszczając go w nawiasach klamrowych. Jako przykład pokażemy, jak określać pozycję danego pola w sposób przyrostowy względem poprzedniego, korzystając tylko z bezwzględnego określania numeru kolumny:
{<{p:=1} KATAL.ID} {<{p+=9} KATAL.TYTUŁ
} {>{p+=55}.2 KATAL.CENA}
Jeśli na podanej dla pola pozycji został już wcześniej wydrukowany jakiś
tekst (np. tytuł zawiera 60 znaków), to pole zostanie umieszczone za wypisanym do tej pory tekstem. Dzięki temu możemy mieć pewność, że żadna dana
nie zostanie na wydruku zafałszowana na skutek obcięcia końcowych znaków.
Dopuszcza się jednak zapisywanie końcowej serii spacji.
Bezpośrednio za opisem pozycji można umieścić opis formatu. Ogólna postać konstrukcji wyprowadzającej wartość formuły wygląda:
[pozycja][format]
formuła
gdzie pozycja ma postać:
[<[stała|{formuła}][>[stała|{formuła}]
zaś format:
[+|-][.|,][stała|{formuła}]
Podsumowując: zdanie formatujące może się składać z trzech członów: pozycji, formatu i formuły. Pozycja ustala numer kolumny w wierszu dla pola
wynikowego. Format określa długość rozwinięcia dziesiętnego dla liczb lub
postać wyniku dla daty i odstępu czasowego. Formuła zwraca wartość, podlegającą formatowaniu i umieszczeniu w polu wynikowym na wydruku. Jeśli
nie chcemy, aby zdanie formatujące wypisywało cokolwiek na wydruku, wynik
19
20
Rozdział I. Konstrukcje języka
formuły powinien być typu pustego (tj. ~~). Takie zdania są używane do wykonania obliczeń pomocniczych, których wyniki nie powinny się znaleźć na
wydruku.
Powyższe konstrukcje gwarantują nam odpowiednie wyrównanie całego
wyprowadzanego tekstu do podanej kolumny. Wyrównanie każdego ze znaków jest uzależnione od trybu wydruku (tekstowy czy graficzny) i ustawienia
parametru graphic w konstrukcji {PRINTER}. Dla trybu tekstowego, włączonej opcji Tylko tekst lub parametru graphic równego 0 każdy znak jest
pozycjonowany do kolumny, w której powinien się znajdować. W przeciwnym
przypadku (czyli dla trybu graficznego i graphic różnego od 0) teksty wyprowadzane są w sposób ciągły, bez pozycjonowania każdego ze znaków niezależnie od użytej czcionki (również dla czcionki nieproporcjonalnej). Przez
to litera, która powinna być w danej kolumnie może być wydrukowana bliżej
lub dalej a znaki z ustalonej kolumny nie muszą być wypisane bezpośrednio
pod sobą. Wyjątkiem są znaki ramki, które są zawsze pozycjonowane — dzięki temu ciągłe linie w tabelkach zawsze będą wypadały pod sobą. Również po
zmianie czcionki lub koloru tekstu wymuszane jest wyrównanie następnego
znaku. Może to np. spowodować większy odstęp w stosunku do poprzedniego
znaku. Drukowane znaki nie mogą na siebie nachodzić. Oznacza to, że jeśli
tekst drukowany przed wyrównywanym znakiem nachodziłby na podaną kolumnę, a w przypadku pozycjonowania znaków zmieściłby się, to zostanie wydrukowany pomniejszoną czcionką. W specyficznych przypadkach może się
zdarzyć, że zawartość komórek tabelki będzie drukowana różnymi czcionkami, chociaż czcionka nie będzie zmieniana. Odstępstwem od reguły są dorównywane znaki odstępów, które mogą być nadpisywane.
5 Rozmieszczenie wyników na stronie
Tekst wyprowadzany jest na wydruk z podziałem na wiersze takim, jak we
wzorcu sprawozdań. Jest jednak wyjątek od tej reguły. Jeśli w wierszu sprawozdania występują konstrukcje języka Report, a poza nimi tylko spacje, to
będzie on wydrukowany pod pewnym warunkiem. Przynajmniej jedną z konstrukcji musi być pole wyprowadzające na wydruk jakiś tekst. Będzie to wtedy,
gdy formuła w polu zwraca wartość typu STRING, DATE, TIME lub NUMBER. Linia będzie wypisana również w przypadku, gdy formuła zwraca napis
pusty (”). Nie zostanie wyprowadzona, jeśli we wzorcu sprawozdania w linii
będzie tylko formuła zwracająca wartość typu pustego lub słowo kluczowe języka Report. Znaki końca wiersza zawarte pomiędzy nawiasami klamrowymi
I.5. Rozmieszczenie wyników na stronie
({}) służą tylko do formatowania konstrukcji języka Report i nie mają wpływu
na format drukowanej strony. Dla przykładu fragment:
linia 1
{SPACE: ’c’}
linia 2
{ _a:=3;
_b:=pi*_a;
˜˜
}{ format:=4; ˜˜}
linia 3
{<{format} ’linia 4’}
da wynik:
linia 1
linia 2
linia 3
linia 4
Teraz zaprezentujemy konstrukcje języka Report wpływające na format
drukowanej strony.
5.1 LINE
Pierwszym zdaniem, które tu omówimy, jest:
{LINE: n_lines}
Zdanie to zrealizuje przesunięcie w dół strony o n_lines wierszy. Jeśli w trakcie zmiany wiersza zostanie osiągnięty koniec strony, wydruk ustawi się na
pierwszym wierszu nowej strony. Tego zdania używamy często, jeżeli potrzeba umieścić n_lines - 1 pustych wierszy po wierszu bieżącym. Po takim
przesunięciu pozycją w wierszu jest jego początek (drukowanie rozpocznie się
od lewego marginesu). Użycie {LINE} bez argumentu jest równoważne podaniu n_lines równego 1. Ujemna wartość n_lines powoduje pominięcie
zdania.
21
22
Rozdział I. Konstrukcje języka
5.2 SKIP
Możemy ustawić bieżący wiersz w pewnej odległości liczonej od początku strony. Stosujemy wtedy:
{SKIP: high}
W argumencie podajemy odległość od początku strony w calach. Jeśli w trakcie wysuwania papieru zostanie osiągnięty koniec strony, wydruk ustawi się
na pierwszym wierszu nowej strony. Po takim wysunięciu pozycją w wierszu jest jego początek (drukowanie rozpocznie się od lewego marginesu). Jeśli high jest mniejsze od odległości aktualnie drukowanego wiersza, zdanie
zostanie pominięte. Ujemna wartość high powoduje pominięcie zdania. Użycie {SKIP} bez argumentu nie wywoła żadnego wysuwu.
5.3 PAGE
Przejście do nowej strony wydruku realizuje jedna z poniższych konstrukcji:
{PAGE}
{PAGELEFT}
{PAGERIGHT}
Pierwsza z nich wysuwa papier do nowej strony. Druga wysuwa papier do strony numerowanej parzyście, a trzecia — do strony numerowanej nieparzyście.
Jeśli jednak w opisie drukarki nie zostało zdefiniowane rozróżnianie stron lewych i prawych, wtedy wszystkie trzy instrukcje mają identyczne działanie.
5.4 MARGIN
Do ustawiania szerokości lewego marginesu służy zdanie:
{MARGIN: length}
gdzie length jest szerokością marginesu w calach. Można użyć tego zdania
bez argumentu, co jest równoważne podaniu argumentu równego zeru (brak
lewego marginesu).
Obecnie zajmiemy się możliwością definiowania paginy. Pagina górna
(główka) pojawia się na każdej stronie u jej góry. Pagina dolna (stopka lub sygnatura) pojawia się na każdej stronie u jej dołu. Jeśli chcemy otrzymać wydruk tabelaryczny z numerowaniem stron i drukowaniem nazw kolumn na
górze strony oraz „domknięciem” tabelki na dole strony, zdefiniujemy paginy
następująco:
I.5. Rozmieszczenie wyników na stronie
{HEADER}
{70*’=’}
| {>70 ’str. ’+$page+’, dn. ’+date$1+’ |’}
{70*’=’}
|
Czytelnik {<42 ’ ’} Adres {<70 ’|’}
{70*’=’}
|{<70 ’|’}
{HEADER-}
{FOOTER}
|{<70 ’|’}
{70*’=’}
{FOOTER-}
otrzymamy wtedy:
======================================================================
|
str. 1, dn. 2003/10/29 |
======================================================================
|
Czytelnik
Adres
|
======================================================================
|
|
| Błaszczyk Stefania
Trąby 7, 03-146 Warszawa
|
| Grzybowski Wacław
Marcina z Wrocimowic 2, 03-145 Warszawa
|
| Jakubowicz Wanda
Aluzyjna 26, 03-149 Warszawa
|
.
.
.
|
|
======================================================================
5.5 HEADER
Nagłówek definiujemy w następujący sposób:
{HEADER}
fragment
{HEADER-}
gdzie fragment jest dowolną poprawną składniowo konstrukcją języka. Nagłówek będzie drukowany na początku każdej strony. Będzie zajmował tyle
wierszy, ile będzie wyprowadzonych w wyniku wykonania fragmentu pomiędzy {HEADER} a {HEADER-}. Może zatem zmieniać swoje rozmiary na różnych stronach. Aby ustalić minimalny rozmiar dla nagłówka należy rozpocząć
jego definicję linią:
{HEADER: high}
23
24
Rozdział I. Konstrukcje języka
gdzie high jest wyrażeniem numerycznym oznaczającym wysokość w calach.
Drukowany nagłówek będzie dopełniony do takiego rozmiaru pustymi wierszami.
Jeżeli na stronach nieparzystych ma być drukowany inny nagłówek, niż na
stronach parzystych deklarujemy go pomiędzy liniami
{HEADERRIGHT} i {HEADERRIGHT-} dla tych pierwszych, oraz
{HEADERLEFT} i {HEADERLEFT-} — dla tych drugich.
Można również użyć opisanych tu konstrukcji z podaniem argumentu.
Nagłówek jest opracowywany po wydrukowaniu pierwszego wiersza (lub
wierszy w przypadku {ENTIRE}) na stronie. Pojawią się one na wydruku tuż
po nagłówku.
5.6 FOOTER
Definicja stopki ma format:
{FOOTER}
fragment
{FOOTER-}
gdzie fragment jest dowolną poprawną składniowo konstrukcją języka, drukowaną na dole każdej strony. Stopka ma ustalony rozmiar na sztywno. Rezerwowanych jest na jej wydrukowanie tyle wierszy, ile było we wzorcu sprawozdania pomiędzy {FOOTER} a {FOOTER-} (bez wliczania złamań wierszy w wyrażeniach języka Formula). Jeśli faktyczna liczba wyprowadzanych
wierszy będzie mniejsza — stopka będzie dopełniona pustymi wierszami, jeśli
większa — zostanie zgłoszony błąd o nieprawidłwej stopce. Jeśli w takim przypadku, przynajmniej jeden drukowany wiersz na stronie był za szeroki i został
drukowany w dwóch wierszach, to w komunikacie o błędzie znajdzie się sugestia o zmianie rozmiaru papieru lub orientacji strony. Rozmiar stopki można
również określić rozpoczynając definicję linią:
{FOOTER: high}
gdzie argument high oznacza wysokość stopki w calach.
Często nie potrzeba drukować stopki u samego dołu strony, jeśli treść wydruku skończyła się wcześniej. Powstaje bowiem wtedy wolne miejsce (puste wiersze) między końcem wydruku, a stopką. Tak będzie się zdarzać na
ostatniej stronie, która przeważnie nie jest zapełniona do końca. Aby tego
uniknąć i dosunąć stopkę do wydruku rozpoczynamy jej definiowanie od
I.5. Rozmieszczenie wyników na stronie
lub z argumentem mniejszym od 0. W pierwszym przypadku liczba linii w stopce jest określana jak dla definicji stopki bez argumentu,
w drugim stopka będzie miała wysokość w calach równą bezwzględnej wartości argumentu.
Jeżeli na stronach nieparzystych ma być drukowana inna stopka, niż na
stronach parzystych deklarujemy ją pomiędzy liniami
{FOOTERRIGHT} i {FOOTERRIGHT-} dla tych pierwszych, oraz
{FOOTERLEFT} i {FOOTERLEFT-} — dla tych drugich.
Można również stosować opisane tu konstrukcje z podanym argumentem.
Stopka jest opracowywana po wydrukowaniu ostatniego wiersza mieszczącego się na stronie.
{FOOTER: 0}
5.7 SIGNATURE
Oprócz stopki możemy dodatkowo zdefiniować sygnaturę:
{SIGNATURE}
fragment
{SIGNATURE-}
gdzie fragment jest dowolną poprawną składniowo konstrukcją języka, ale
na wydruku musi zmieścić się w jednym wierszu —- inaczej zostanie zgłoszony błąd w trakcie przygotowywania strony. Wiersz z sygnaturą będzie umieszczony poniżej stopki, ale nie będzie dosunięty do wydruku razem ze stopką.
Korzystamy z tego, gdy chcemy użyć stopki z argumentem 0, a na dole strony
potrzebujemy umieścić np. numer strony.
W panelu drukarki można usunąć zaznaczenie pola Sygnatura jeśli sygnatura ma się nie pojawiać na wydruku (nie będzie wtedy również wyliczana). Domyślna wartość dla tego pola jest ustalana na podstawie parametru
signatureoff z opisu drukarki (.prt) i osiemnastego argumentu zdania
{PRINTER}.
Sygnatura jest opracowywana po zakończeniu przygotowywania stopki
(lub ostatniego wiersza na stronie, jeśli stopka nie została zdefiniowana).
Przed drukowaniem nagłówka, stopki i sygnatury odstęp międzywierszowy ({SPACE}) czcionka ({FONT}), kolor ({COLOR}) oraz sposób równania
do środkowej kolumny ({CENTER} lub {JUSTIFY}) są ustalane na takie, jakie były ustawione bezpośrednio przed definicją odpowiednio nagłówka, stopki i sygnatury. Po zakończeniu drukowania odpowiedniej paginy przywracane
są wartości obowiązujące przy drukowaniu treści sprawozdania.
25
26
Rozdział I. Konstrukcje języka
5.8 MAXPAGE
Aby w wydruku umieścić sumaryczną liczbę stron korzystamy z konstrukcji:
{MAXPAGE: format; left_txt; num_form; right_txt}
Argument format określa sposób formatowania całego wyprowadzanego
tekstu i jest identyczny jak dla formatu pola. Jako left_txt i right_txt
umieszczamy wyrażenia zwracające tekst, który będzie wypisany odpowiednio przed i za liczbą wszystkich stron. Argument num_form to dwa znaki, za
pomocą których określamy format drukowania samej liczby stron. Pierwszy
z nich, to cyfra różna od 0 i oznacza szerokość wynikowego tekstu w znakach.
Jeśli liczba stron będzie miała więcej znaków niż rezerwowana, to zamiast liczby pojawią się znaki zapytania. Można pominąć wpisanie tego znaku, wtedy
domyślną wartością będzie 6. Drugi znak może przyjąć jedną z poniższych
wartości:
L
liczba będzie dosunięta do lewego skraju zarezerwowanego dla niej miejsca, pozostałe znaki będą odstępami;
R
dosunięcie liczby do prawego skraju zarezerwowanego obszaru;
C
umieszczenie liczby na środku zarezerwowanego obszaru;
0
liczba zostanie dopełniona zerami z lewej strony, do szerokości zarezerwowanego obszaru.
Również on może zostać pominięty. W takim przypadku wartość domyślna zależy od parametru format. Jeśli tam występuje dosunięcie do lewej, to przyjmuje wartość L, do prawej — R, zaś w przypadku centrowania — C. Drukowany napis może ulec zmianie, jeśli liczba formatowana jest do lewej, zaś całość
do:
prawej
wtedy spacje z zarezerwowanego obszaru na liczbę stron przenoszone są
na początek napisu;
lewej
spacje z zarezerwowanego obszaru na liczbę stron są przenoszone na
koniec napisu;
centrowana
spacje z zarezerwowanego obszaru na liczbę stron są przesuwane na
przemian na prawy i lewy koniec napisu.
27
I.5. Rozmieszczenie wyników na stronie
Dzięki temu, można dosunąć tekst zwracany przez right_txt bezpośrednio
za ostatnią cyfrę liczby stron.
Przykłady Chcąc dosunąć zakończenie tabelki do wydruku w poprzednim
przykładzie, a na dole strony umieścić wyśrodkowany numer strony i sumaryczną liczbę stron, zdefiniujemy paginy następująco:
{HEADER}
{70*’=’}
|
{>70 ’dn. ’+date$1+’ |’}
{70*’=’}
|
Czytelnik {<42 ’ ’} Adres {<70 ’|’}
{70*’=’}
|{<70 ’|’}
{HEADER-}
{FOOTER: 0}
|{<70 ’|’}
{70*’=’}
{FOOTER-}
{SIGNATURE}
{MAXPAGE: <1>{charleft};
’( ’+$page+’ / ’; 3L; ’ )’}
{SIGNATURE-}
co da w wyniku:
======================================================================
|
dn. 2003/10/29 |
======================================================================
|
Czytelnik
Adres
|
======================================================================
|
|
| Błaszczyk Stefania
Trąby 7, 03-146 Warszawa
|
| Grzybowski Wacław
Marcina z Wrocimowic 2, 03-145 Warszawa
|
| Jakubowicz Wanda
Aluzyjna 26, 03-149 Warszawa
|
|
|
======================================================================
.
.
.
( 1 / 1 )
Definicja paginy jest fragmentem programu zamkniętym między zdaniem
rozpoczynającym definicję, a zdaniem ją kończącym. Zdanie kończące zawiera to samo słowo kluczowe, co zdanie rozpoczynające, a bezpośrednio za słowem kluczowym występuje znak - (minus). Z podobnym zapisem spotkamy
28
Rozdział I. Konstrukcje języka
się jeszcze wielokrotnie: oba zdania i fragment między nimi tworzą konstrukcję
zdaniową. Fragment w każdej konstrukcji zdaniowej musi być zamknięty, tzn.
każda w nim rozpoczęta konstrukcja, musi w nim także się kończyć.
5.9 ENTIRE
Zdanie:
{ENTIRE}
definiuje fragment wydruku, który ma w całości zmieścić się na jednej stronie.
Pewnych zestawów danych nie należy łamać przejściem do nowej strony, a raczej rozpoczynać ich drukowanie już na nowej stronie. Typowym przykładem
jest drukowanie imiennych zawiadomień, wyciągów bankowych, itp. Koniec
fragmentu zaznaczamy zdaniem:
{ENTIRE-}
Choć w zapisie podobna do konstrukcji, ta struktura nie jest konstrukcją. Nie
ma bowiem wymagania zamknięcia fragmentu zawartego między {ENTIRE},
a {ENTIRE-}. Użycie {ENTIRE} przełącza generator wydruków w tryb wysyłania drukowanych znaków do specjalnego bufora. Jednocześnie obliczane
jest zużycie miejsca na bieżącej stronie. Gdyby okazało się, że taki fragment
przekroczyłby granicę stron to następuje jego wydrukowanie od początku strony (po wydrukowaniu nagłówka): bieżącej lub następnej w przypadku, gdy bieżąca strona nie była pusta (wykonuje się wysuw papieru do nowej strony). Po
wydrukowaniu pierwszej strony generator wydruków ustawiany jest z powrotem w tryb standardowy. Jeżeli generator nie natrafi na koniec strony, bufor
drukowany jest po natrafieniu na zdanie {ENTIRE-}.
Funkcja lineleft() w konstrukcji {ENTIRE} zwraca liczbę wierszy,
jaka pozostała do końca strony w momencie przetwarzania. Wartość ta może
być znacząco różna od liczby wierszy w sporządzonym sprawozdaniu w przypadku, gdy fragment zostanie przeniesiony na nową stronę.
5.10 DIRECT
Oprócz zdania {ENTIRE} istnieje drugi sposób umieszczenia fragmentu na
jednej stronie — przełączenie drukowania w tryb dostępu swobodnego. Tu jednak, jeśli tekst nie mieści się na stronie — zostanie zgłoszony błąd. W trybie dostępu swobodnego mamy możliwość drukowania w dowolnym miejscu strony,
także w wierszu o numerze mniejszym od numeru wiersza bieżącego. Przełączenie generatora wydruków w ten tryb następuje po natrafieniu na zdanie:
I.5. Rozmieszczenie wyników na stronie
{DIRECT}
zaś powrót do trybu bezpośredniego następuje po:
{DIRECT-}
W trybie dostępu swobodnego wiersze są numerowane, a numer wiersza bieżącego można odczytać funkcją line() języka Formula. Numer pierwszy ma
wiersz rozpoczynający fragment, a nie wiersz pierwszy na stronie. Wywołanie
line() z argumentem spowoduje ustawienie nowej wartości numeru bieżącego wiersza na równy wartości argumentu. Jeśli zmienimy wiersz na wydrukowany wcześniej, zawartość nowego wiersza będzie nałożona na starą zawartość tak, że znaki odstępu w nowej zawartości nie zakryją zawartości starej,
a znaki różne od odstępu w nowej zawartości zastąpią znaki w starej zawartości.
Przykłady Mając następujący wzorzec wydruku:
{DIRECT}
Początek
xxx xxx xxx --- linia {line}
{ line(4); ˜˜}
yyyy yyyy yyyy --- linia {line}
{ line(2); ˜˜}
zzzz
{DIRECT-}
koniec.
otrzymujemy w wyniku następujący wydruk:
Początek
xxzzzzx xxx --- linia 2
yyyy yyyy yyyy --- linia 4
koniec.
Nie wolno umieszczać instrukcji {ENTIRE} przy aktywnym trybie
{DIRECT} (i na odwrót). Użycie takie spowoduje błąd podczas wykonania.
29
30
Rozdział I. Konstrukcje języka
6 Zmiana czcionki i wysuwu
Wyróżnienie na wydruku niektórych treści możemy osiągnąć poprzez zmianę
czcionki lub odstępu międzywierszowego.
6.1 FONT
Ustawienie odpowiedniej czcionki zapewnione jest dzięki zdaniu:
{FONT: name}
Argument name to napis będący nazwą czcionki (jednoliterową dla nazw zdefiniowanych w opisie drukarki lub dowolną, zdefiniowaną wcześniej poleceniem {DEFINEFONT}). Dozwolony jest również znak ’@’, który oznacza odmianę standardową, ustawioną dla danego wzorca i ważną od początku wydruku, aż do napotkania zdania {FONT}. Standardowa odmiana czcionki ustalana
jest na podstawie parametru fontstd z opisu drukarki (.prt) i szóstego argumentu zdania {PRINTER}. Można ją zmienić w panelu drukarki w polu
Czcionka.
Zmiana czcionki może być podyktowana nie tylko potrzebą zmiany kroju,
czy wielkości liter, ale również strony kodowej, np. jeżeli chcemy wydrukować tekst w innym języku lub umieścić znaki kodów paskowych. Przy czym
w trybie tekstowym, dla opcji Tylko tekst lub dla parametru graphic konstrukcji {PRINTER} równego 0 można używać jedynie czcionek nieproporcjonalnych, zdefiniowanych w opisie drukarki, mających jednoliterowe nazwy. Dla czcionek zdefiniowanych konstrukcją {DEFINEFONT} ustawiona
będzie czcionka bazowa, natomiast dla trybu graficznego ważne będą również
ustawienia strony kodowej i konwersji (por. opis {DEFINEFONT}). Taki sposób drukowania może być bardziej preferowany dla różnego typu formularzy,
w których ważniejsze będzie odpowiednie pozycjonowanie liter niż kolor czy
proporcjonalny krój czcionki.
6.2 SPACE
Ustawienie odpowiedniego odstępu międzywierszowego (wysuwu) zapewnione jest dzięki zdaniu:
{SPACE: name}
I.7. Konstrukcje graficzne
Argumentem name jest napis będący literą, która określa wielkość odstępu międzywierszowego z istniejących w definicji .prt. Odstęp standardowy oznaczamy znakiem ’@’. Jego wartość domyślna ustalana jest na podstawie parametru spacestd z opisu drukarki i siódmego argumentu zdania
{PRINTER}. Można ją następnie zmienić w panelu drukarki w polu Wysuw.
Jest on ważny od początku wydruku, aż do napotkania zdania {SPACE}.
Zdanie {SPACE} wpływa na liczbę wierszy, które mogą się zmieścić na
jednej stronie. System sprawdza, czy w wyniku wysłania kolejnego znaku nowego wiersza na drukarkę, została przekroczona ustalona wysokość strony
(z uwzględnieniem pagin). Jeśli tak, nastąpi automatyczna zmiana strony wydruku (z ewentualnym wydrukowaniem stopki i sygnatury). Zwróćmy uwagę,
że podczas definiowania stopki i sygnatury określa się ich rozmiar (wysokość
w calach) na podstawie liczby wierszy i odstępu międzywierszowego ustalonego przed ich definicją. Późniejsze zwiększenie wartości odstępu międzywierszowego może doprowadzić do błędu przy ich drukowaniu.
7 Konstrukcje graficzne
Dodatkowe możliwości w definiowaniu wydruków oferują konstrukcje graficzne. Są one dostępne tylko z parametrem graphic konstrukcji {PRINTER}
różnym od 0, przy wyłączonej opcji Tylko tekst. Dzięki nim możemy zmieniać
krój czcionki (np. na proporcjonalny), definiować kolory dla tekstu i tła, włączać grafikę.
7.1 DEFINEFONT
Możliwość wykorzystania innych czcionek niż nieproporcjonalne (czcionki
proporcjonalne, kody paskowe) oraz drukowanie w innych stronach kodowych otrzymujemy przez zdefiniowanie nowych czcionek we wzorcu. Każda
nowa czcionka musi bazować na zdefiniowanej w opisie drukarki czcionce nieproporcjonalnej. Liczba znaków wypisanych w wierszu dla obu tych czcionek
będzie taka sama. Jeżeli użyte znaki w wyprowadzonym tekście będą mniejsze
od średniej szerokości znaku, pozostanie wolna przestrzeń. Jeżeli będą szersze
i napis nie zmieściłby się w zadanym obszarze (ewentualnie obszarze jaki by
zajmował, gdyby był drukowany czcionką bazową), to czcionka zostanie odpowiednio pomniejszona. Nowa czcionka dziedziczy atrybuty (tzn. pochylenie,
pogrubienie, podkreślenie) swojej czcionki bazowej, czyli oprócz atrybutów
wynikających z definicji nowego kroju przypisane zostaną atrybuty wynika-
31
32
Rozdział I. Konstrukcje języka
jące z definicji czcionki bazowej w sterowniku drukarki. Do definicji nowej
czcionki służy zdanie:
{DEFINEFONT: definition}
gdzie definition jest napisem postaci:
’ID=Czcionka,Wys,Baza,Kod,MaxOds,MinOds,BezKonw’
zawierającym identyfikator definiowanego kroju (ID), który będzie później wykorzystywany jako argument konstrukcji {FONT} w celu ustawienia
zdefiniowanej czcionki jako bieżącej. Następnie znak równości (=) oraz następującą po nim listę parametrów oddzielonych przecinkami. Identyfikator
może składać się z liter i cyfr a jego długość nie może przekraczać 31 znaków.
Znaczenia kolejnych parametrów są następujące:
Czcionka
nazwa czcionki (zainstalowanej w systemie operacyjnym). Domyślnie będzie to czcionka ze sterownika drukarki. Jeśli w sterowniku
czcionka nie została określona wówczas przyjęta zostanie czcionka
Courier New.
Jeśli czcionka określona w parametrze nie jest zainstalowana w systemie,
to zostanie odnotowana taka informacja w pliku jterm.ini w sekcji
[!reports fonts]. Kolejne wiersze sekcji będą miały po lewej stronie znaku równości nazwę z parametru Czcionka, zaś po prawej nazwę czcionki dobraną z systemu. Plik można redagować (jeśli nie jest już
używany przez klienta) wskazując inną czcionkę w systemie. Będzie ona
użyta, o ile zostanie odnaleziona. Jeśli przy kolejnym wywołaniu DEFINEFONT zostanie odnaleziona czcionka o dokładnie takiej nazwie, jaką podano w parametrze (np. po doinstalowaniu czcionki w systemie),
to będzie ona użyta, zaś wpisy z sekcji [!reports fonts] zostaną
usunięte,
Wys
procent wysokości czcionki bazowej. Może przyjmować wartości od 75
do 300, domyślnie 100 (wysokość czcionki bazowej),
Baza
litera czcionki bazowej (zdefiniowana w opisie drukarki). Domyślnie jest
to znak @ (czcionka standardowa dla danego wydruku),
I.7. Konstrukcje graficzne
Kod
numer strony kodowej czcionki. Dodatkowo dla wartości różnych od
238 (strona polska) nie ma konwersji znaków z Mazovii do Windows.
Domyślną wartością jest numer strony kodowej czcionki bazowej. Dopuszcza się użycie niestandardowej strony kodowej oznaczonej liczbą 8
— stronę kodową UTF-8. Oznacza ona, że wszystkie teksty drukowane będą bez żadnych konwersji. Dla pozostałych, obsługiwanych stron
kodowych, konwersja dotyczy tylko znaków ze standardu Mazovii: polskich liter, znaków ramek i niektóry znaków symboli,
MaxOds
ograniczenie górne dla odstępu międzyliterowego. Może przyjmować
wartości od 0 do 50 i oznacza szerokość odstępu, liczoną w procentach
średniej szerokości znaku. Jeżeli podamy ograniczenie górne musimy
podać też ograniczenie dolne (oba parametry muszą być podane lub oba
pominięte). Wartość domyślna jest dopasowywana do czcionki,
MinOds
ograniczenie dolne dla odstępu międzyliterowego. Może przyjmować
wartości od -20 do 50 (znaczenie jak dla ograniczenia górnego), przy
czym wartość ujemna oznacza, że poszczególne znaki mogą na siebie
zachodzić. Ograniczenie dolne nie może być większe niż ograniczenie
górne, jeśli oba parametry będą równe, to system będzie stosował wskazany odstęp. Wartość domyślna określana jest zależna od czcionki,
BezKonw
wyłączenie konwersji znaków. Jeżeli parametr przyjmie wartość 1, to niezależnie od wartości strony kodowej zostanie wyłączona konwersja znaków z Mazovii do Windows oraz drukowanie ramek (w miejscu rysowanych znaków ramek pojawią się znaki z fontu). Jeżeli przyjmie wartość
0 lub zostanie pominięty, to włączone będzie rysowanie ramek, zaś dla
strony kodowej równej 238 wykona się konwersja znaków. Domyślną
wartością jest 0.
Przykłady Aby uzyskać wydruk czcionką Times New Roman, z cechami
czcionki standardowej dla wydruku użyjemy konstrukcji:
{DEFINEFONT: ’times=Times New Roman’}
{FONT: ’times’}
33
34
Rozdział I. Konstrukcje języka
Niedostępne dla polskiej strony kodowej znaki możemy wydrukować stosując zapis:
{DEFINEFONT: ’ansi=,,,0’}
{FONT: ’ansi’}{%167}{FONT: ’@’} 22. Paragraf.
{FONT: ’ansi’}{%149}{FONT: ’@’} wypunktowanie;
Została użyta tu domyślna strona kodowa ANSII również dla standardowej
czcionki.
Litery alfabetu rosyjskiego w czcionce Arial ze zmniejszoną wysokością
czcionki otrzymamy definiując:
{DEFINEFONT: ’arial_rosyjska=Arial,75,,204,,,1’}
{FONT: ’arial_rosyjska’}
{ _litery:=’’;
{! _lit:= 192..255 |! _litery+=%_lit !};
_litery
}
Drugi parametr ustawia wysokość czcionki na trzy czwarte wysokości czcionki
bazowej, czwarty parametr ustawia rosyjską stronę kodową, natomiast siódmy
wyłącza konwersję znaków, aby na wydruku zamiast ramek pojawiły się litery
rosyjskie o kodach ASCII takich samych jak ramki.
Do wydrukowania kodów paskowych zastosujemy fragment:
{DEFINEFONT: ’kody=MacroBar Code128-10,,e,2,0,0’}
{FONT: ’kody’}
Została tu użyta czcionka znajdująca się na płytach z oprogramowaniem. Podana czcionka bazowa określa rozmiar znaków paskowych. Aby pojawiły się
one na wydruku strona kodowa musi zostać ustawiona na 2 (drukowanie symboli) oraz wydruk musi być wykonany w trybie graficznym. Parametry piąty
i szósty zapewniają zerowy odstęp międzyznakowy. Parametr siódmy nie został
użyty, co oznacza, że dla tej samej czcionki aktywne będzie rysowanie ramek.
7.2 COLOR
Zmianę koloru czcionki i tła wypisywanego tekstu umożliwia konstrukcja:
{COLOR: color}
I.7. Konstrukcje graficzne
Argument color jest tekstem zawierającym listę dwóch parametrów oddzielonych przecinkiem:
’kolor_tekstu,kolor_tła’
— kolor_tekstu określa kolor tekstu,
— kolor_tła określa kolor tła.
Oba mają postać:
rr:gg:bb
trzech liczb od 0 do 255 oddzielonych dwukropkiem — współrzędne RGB.
Pominięcie któregoś z parametrów oznacza kolor aktualnie obowiązujący odpowiednio dla tekstu lub tła. Domyślnymi parametrami przed rozpoczęciem
drukowania jest czarny dla tekstu i biały dla tła. Wskazane kolory obowiązują
do kolejnej zmiany.
Możliwe jest również użycie bitmapy jako koloru tła dla tekstu. Jako drugi
parametr w napisie przekazywanym do konstrukcji {COLOR}, zamiast współrzędnych RGB należy wtedy podać nazwę zbioru ujętą w podwójne apostrofy
(""). Po zmianie koloru tła na bitmapę, tło pod wypisywanym znakiem nie
musi przedstawiać lewego górnego rogu grafiki. Będzie to fragment, jaki zostałby odsłonięty w danym miejscu, jeśli bitmapa byłaby drukowana obok siebie na całej szerokości i wysokości kartki. Na podstawie rozdzielczości bitmapy
pobieranej z nagłówka pliku .bmp i jej rozmiarów określane są fizyczne rozmiary, które będzie zajmować na kartce. Będzie zatem identycznych rozmiarów niezależnie od rozdzielczości drukarki.
Przykłady Użycie konstrukcji postaci:
{COLOR: ’255:0:0,220:220:220’}
ustawi czerwony kolor tekstu na jasnoszarym tle . Natomiast jeśli chcemy
ustawić jako tło bitmapę nazwa.bmp napiszemy:
{COLOR: ’0:0:0,"nazwa.bmp"’}
Dla znaków ramek obowiązują nieco inne zasady ustalania tła. Tło z lewej
strony i z dołu ramki jest takie, jakie obowiązywało przy drukowaniu znaku.
Z prawej strony przyjmuje kolor tła następnego znaku, zaś z dołu kolor znaku drukowanego bezpośrednio pod nim. Dzięki temu, można wyróżnić oczko
tabelki, stosując poniższe zasady zmieniania koloru tła:
35
36
Rozdział I. Konstrukcje języka
— górną linię separującą drukujemy w zwykłym kolorze,
— po znaku lewej ramki komórki tabelki należy zmienić kolor tła na specjalny,
— po znaku prawej ramki zmienić kolor na zwykły,
— po pierwszym znaku dolnej linii separującej komórkę zmienić kolor na
specjalny,
— po ostatnim znaku dolnej linii separującej zmienić kolor na zwykły.
Przykłady Wykonując poniższy wzorzec otrzymamy na wydruku wypełnione różnymi kolorami komórki ramki na białym tle:
{ biały:=’,255:255:255’;
żółty:=’,255:255:0’;
niebieski:=’,0:0:255’;
zielony:=’,0:255:0’;
˜˜
}
{%218}{%196}{%191}{COLOR: biały}
{%179}{COLOR: żółty
}{%201}{%216}{COLOR: biały}{%187}
{%192}{COLOR: żółty
}{%215}{COLOR: zielony
}{%217}{COLOR: niebieski
}{%186}{COLOR: biały}
{%200}{COLOR: niebieski
}{%205}{%188}{COLOR: biały}
7.3 BITMAP
Wydruki można wzbogacać poprzez wstawianie plików graficznych w stosownym miejscu kartki. Służy do tego konstrukcja:
{BITMAP: bitmap}
gdzie bitmap jest tekstem będącym listą trzech parametrów oddzielonych
przecinkami:
I.7. Konstrukcje graficzne
nazwą pliku wraz z rozszerzeniem
ujętą w podwójne apostrofy (""), obsługiwane są pliki w formacie bitmap systemu Windows (.bmp),
szerokością
jaką ma mieć grafika na wydruku, liczona w znakach aktualnej czcionki,
może przyjmować jedynie wartości całkowite,
wysokością
liczoną w liniach bieżącego wysuwu, również liczba całkowita.
Jeden z parametrów — drugi lub trzeci — może być pominięty lub przyjąć
wartość 0. Oznacza to, że przyjęta będzie taka wartość, aby bitmapa zachowała
proporcje.
Lewy górny róg grafiki będzie umieszczony na pozycji bieżącego znaku.
Wydrukowana bitmapa musi się w całości mieścić na stronie. Jeśli część wychodziłaby na margines lub nakładała się na stopkę, to zostanie zgłoszony błąd.
Jeśli bitmapa jest drukowana we fragmencie {ENTIRE} i zajmuje więcej wierszy niż pozostało do stopki, to cały fragment zostanie przeniesiony na nową
stronę.
Użycie konstrukcji {BITMAP} nie zmienia pozycji drukowania. Kolejny
znak będzie wyprowadzany na takich samych zasadach, co w przypadku, gdyby konstrukcja nie była użyta. Oznacza to, że tekst może być umieszczony na
wydrukowanej grafice. Tekst będzie wtedy pisany na bitmapie, natomiast tło
znaków będzie niewidoczne.
Przykłady Poniższe wywołanie wydrukuje proporcjonalną bitmapę zajmującą 10 wierszy:
{BITMAP: ’"nazwa.bmp",,10’}
7.4 IMAGE
Pliki związane z polem typu BLOBIMAGE można umieszczać w sprawozdaniach w analogiczny sposób, w jaki umieszczane są grafiki poleceniem i
{BITMAP}. Służy do tego konstrukcja:
{IMAGE: image; width; height; page_number}
gdzie:
37
38
Rozdział I. Konstrukcje języka
image
wartość typu BLOBIMAGE lub uchwyt do pliku z obrazkiem (wartość
typu FILE). Dopuszczalne formaty to: BMP, JPG, PNG i TIFF,
width
szerokość, jaką ma mieć grafika na wydruku, liczona w znakach aktualnej czcionki, może przyjmować wartości dodatnie, również z częścią
ułamkową;
height
wysokość, jaką ma mieć grafika na wydruku, liczona w liniach bieżącego
wysuwu, może przyjmować wartości dodatnie, również z częścią ułamkową.
page_number
wyrażenie liczbowe, określające numer strony. W przypadku pominięcia
argumentu, drukowana będzie pierwsza strona. Dla obrazków w formatach innych niż TIFF, argument jest ignorowany.
Jeden z parametrów — drugi lub trzeci — może być pominięty lub przyjąć
wartość 0. Oznacza to, że przyjęta będzie taka wartość, aby grafika zachowała
proporcje.
Przykłady Przypuśćmy, że do pola BLOB tabeli TAB jest przypisany plik z
grafiką. Wtedy poniższy fragment wydrukuje ją z zachowaniem proporcji, na
szerokości 20 znaków. Jeśli obrazek nie mieściłby się na bieżącej stronie, to
zostanie przemieszczony na następną:
{IF:
img_size(T.BLOB, 20) >= lineleft &
lineleft > 0
}
{PAGE}
{FI}
{IMAGE: TAB.BLOB;20}
8 Drukowanie w trybie graphic
Drukowanie w trybie graphic umożliwia drukowanie wypełnionych formularzy zapisanych w plikach PDF.
I.8. Drukowanie w trybie graphic
8.1 GRAPHIC
Konstrukcja {GRAPHIC: } rozpoczyna drukowanie strony w trybie graphic.
Użycie jej wymaga, aby podany był rozmiar papieru w konstrukcji PRINTER. Jako tło strony zostanie umieszczona wskazana strona z piku PDF. W
trybie graphic można umieszczać treści na wydruku jedynie instrukcjami
{GRAPHICTEXT:} (wypisanie tekstu) oraz {GRAPHICIMAGE:} (umieszczenie grafiki). Inne konstrukcje zmieniające zawartość strony są niedozwolone w trybie graphic — ich użycie spowoduje pojawienie się błędu. Dopuszczalne jest jedynie wyprowadzanie pustych wierszy (lub składających się z samych
spacji) — nie będą one jednak miały wpływu na wygląd wydruku. Zdefiniowane nagłówki, stopki i sygnatury nie są dla stron w trybie graphic przetwarzane
(bez zgłaszania błędu). Po wyjściu z trybu graphic będą na nowo przetwarzane.
Wydruk jest składany na papier o rozmiarach określonych przez 20 argument zdania {PRINTER: }. Elementy nie mieszczące się w całości na stronie
będą przycinane do rozmiarów kartki. Wyjście z trybu graphic następuje po
użyciu konstrukcji {GRAPHIC-}. Powoduje ona przejście do nowej strony i
zmianę trybu drukowania na standardowy. W momencie zakończenia opracowywania wydruku, drukowanie nie może być w trybie graphic — po przejściu
do trybu graphic zawsze trzeba go opuścić poprzez wywołanie {GRPAHIC-}.
Konstrukcja rozpoczynająca drukowanie w trybie graphic ma postać:
{GRAPHIC: [pdf_file]; [page]; [m_left]; [m_top];
[m_right]; [m_bottom]}
Powoduje ona przejście do nowej strony (jeśli coś pojawiło się wcześniej na
bieżącej stronie). Tłem strony będzie zawartość strony page pliku w formacie
PDF przekazana przez argument pdf_file. Tło jest nakładane w taki sposób, że
lewy górny róg kartki pokrywa się z lewym górnym rogiem strony z pliku PDF.
Jeśli rozmiar kartki w pliku PDF jest większy niż rozmiar kartki określony w
zdaniu {PRINTER: }, to jej zawartość zostanie przycięta. Kolejne argumenty określają marginesy określają marginesy tworzonej strony. To co znajdzie
się w obszarze wydruku, pojawi się również w obszarze wydruku na składanej stronie. Może być jednak przesunięte lub przeskalowane, w zależności od
określenia marginesów w zdaniu {PRINTER: }. Elementy, które pojawią się
na marginesie, mogą pojawić się na marginesie składanej strony lub nawet być
przycięte do jej rozmiarów.
Znaczenie argumentów jest następujące:
pdf_file
określa plik w formacie PDF, który będzie tłem bieżącej strony. Może być
nazwą pliku wyszukiwanego według deklaracji ścieżek, wartością pola
39
40
Rozdział I. Konstrukcje języka
typu BLOBIMAGE lub BLOBRAW zawierającego plik w formacie PDF
lub obiektem typu FILE, powiązanym z otwartym plikiem binarnym w
formacie PDF. Pominięcie argumentu (lub przekazanie pustego napisu)
powoduje, że tło będzie białe,
page
numer drukowanej strony z pliku PDF, Pominięcie numeru strony (lub
podanie liczby 0) oznacza pierwszą stronę. Ujemne wartości dla argumentu są niedopuszczalne. Jeśli wartość argumentu przekracza liczbę
stron w pliku plik_pdf, to tło strony będzie białe,
m_left
rozmiar lewego marginesu w milimetrach tworzonej strony,
m_top
rozmiar górnego marginesu w milimetrach tworzonej strony,
m_right
rozmiar prawego marginesu w milimetrach tworzonej strony,
m_bottom
rozmiar dolnego marginesu w milimetrach tworzonej strony.
Tworzona strona zostanie przesunięta na kartce w taki sposób, aby lewy
górny róg obszaru roboczego określonego w zdaniu PRINTER pokrywał się
z lewym górnym rogiem obszaru roboczego określonego w konstrukcji GRAPHIC.
Jeśli po przesunięciu obszar roboczy określony w konstrukcji GRAPHIC
nie zawiera się w obszarze roboczym określonym w zdaniu PRINTER, to tworzona strona będzie przeskalowana tak, aby powyższy warunek był spełniony.
Przy podawaniu tła bieżącej strony, warto zwrócić uwagę, aby rozmiar kartki w pliku PDF był identyczny z określonym w konstrukcji PRINTER. Dodatkowo należy w konstrukcji GRAPHIC podać marginesy, które występują w pliku PDF. Marginesy zawarte w pliku PDF będą nakładały się wtedy na marginesy kartki. Jeśli zostaną podane za małe, to brakująca część marginesów z
pliku PDF będzie zajmowała obszar drukowania, pomniejszając go. Wizualnie
może to prowadzić do większych marginesów niż określonych w konstrukcji
PRINTER i dodatkowo przeskalowania strony. W przypadku podania za dużych marginesów część strony z pliku PDF może znaleźć się na marginesie
wydruku lub nawet może być przycięta.
I.8. Drukowanie w trybie graphic
8.2 GRAPHICTEXT
Tekst w trybie graphic wypisywany może być jedynie konstrukcją:
{GRAPHICTEXT: text; x; y; [width]; [align]; [angle]}
Znaczenie argumentów jest następujące:
text
tekst, który ma być wypisany na stronie,
x
współrzędna pozioma (przesunięcie podane w milimetrach względem
lewej krawędzi kartki) początku, środka lub końca tekstu (w zależności od wartości parametru align). Jeśli współrzędna nie mieści się na
stronie, to zostanie zgłoszony błąd,
y
współrzędna pionowa (przesunięcie podane w milimetrach względem
górnej krawędzi kartki) początku, środka lub końca tekstu (w zależności od wartości parametru align). Określa ona linię podstawową (dla wartości dla wartości parametru align równej ’left’,
’center’ lub ’right’ lub linię dolną wypisywanego tekstu (dla wartości ’dl_left’, ’dl_center’ i ’dl_rigth’). Jeśli współrzędna
nie mieści się na stronie, to zostanie zgłoszony błąd,
width
maksymalna długość tekstu (podawana w milimetrach). Jeśli wypisywany tekst byłby dłuższy w naturalnej szerokości, to będzie on zwężony. Podanie wartości 0 (lub pominięcie argumentu) dopuszczalne jest tylko dla
wartości parametru align równej ’left’, ’center’ lub ’right’.
Oznacza, że tekst będzie wypisywany w naturalnej szerokości, bez ograniczeń na długość,
align
określa wyrównanie tekstu. Może przyjmować jedną z poniższych wartości:
’left’
tekst wyrównywany będzie do lewej, współrzędne wypisywanego
tekstu oznaczają jego początek. Jest to wartość domyślna w przypadku pominięcia argumentu lub przekazania pustego napisu,
’right’
tekst wyrównywany będzie do prawej, współrzędne wypisywanego
tekstu oznaczają jego koniec,
41
42
Rozdział I. Konstrukcje języka
’center’
tekst będzie wyśrodkowany, współrzędne wypisywanego tekstu
oznaczają jego środek,
’dl_left’
początek tekstu będzie miał współrzędne określone parametrami
(x, y),
’dl_center’
środek tekstu będzie określony współrzędnymi (x + width/2, y),
’dl_right’
koniec tekstu określony jest współrzędnymi (x + width, y),
angle
kąt obrotu wypisywanego tekstu względem współrzędnych x i y. Podawany jest w stopniach i może przyjmować wartości od 0, do 360. Domyślną wartością jest 0, czyli bez obrotu tekstu. Dla wartości parametru
align równej ’dl_left’, ’dl_center’ i ’dl_rigth’ parametr
musi być pominięty (lub mieć wartość 0).
8.3 GRAPHICFONT
Tekst w trybie graphic wypisywany jest czcionką, która była ostatnio ustawiona
konstrukcją GRAPHICFONT. Konstrukcja ta ma postać:
{GRAPHICFONT: [name]; [size]; [attr]; [text_color];
[margin_left]; [margin_bottom]; [margin_right]}
gdzie
name
napis będący nazwą czcionki, domyślnie Arial (w przypadku pominięcia argumentu lub przekazania pustego napisu),
size
liczba określająca rozmiar czcionki (w punktach), domyślnie 10. Może
przyjmować wartości 4 do 144,
attr
napis składający się ze znaków:
b
jeśli znak wystąpił w argumencie, to czcionka będzie pogrubiona,
I.8. Drukowanie w trybie graphic
i
jeśli znak wystąpił w argumencie, to czcionka będzie pochyła,
u
jeśli znak wystąpił w argumencie, to czcionka będzie podkreślona.
W przypadku pominięcia argumentu (lub pustej wartości) czcionka nie
będzie miała specjalnych atrybutów,
text_color
napis w postaci współrzędnych RGB oddzielonych dwukropkami
(’rr:gg:bb’), określający kolor wypisywanego tekstu. Domyślna
wartość w przypadku pominięcia argumentu lub przekazania pustej
wartości oznacza kolor czarny. Tło tekstu jest zawsze przezroczyste,
margin_left
lewy margines dla wypisywanych tekstów. Dla wyrównań dl_left,
dl_right oraz dl_center współrzędna x z wywoływanych konstrukcji
{GRAPHICTEXT: } będzie automatycznie powiększana o podaną
wartość, zaś parametr width będzie automatycznie zmniejszany o podaną wartość. Argument nie może być ujemny, domyślną wartością jest
1,
margin_bottom
dla wyrównań dl_left, dl_right oraz dl_center współrzędna y z wywoływanych konstrukcji {GRAPHICTEXT: } będzie automatycznie pomniejszana o podaną wartość. Argument nie może być ujemny, domyślną wartością jest 1,
margin_right
dla wyrównań dl_left, dl_right oraz dl_center parametr width z wywoływanych konstrukcji {GRAPHICTEXT: } będzie automatycznie pomniejszany o podaną wartość. Argument nie może być ujemny, domyślną wartością jest 1.
8.4 GRAPHICIMAGE
W trybie graphic oprócz wypisania tekstu, można nakładać na stronę grafiki.
Służy do tego konstrukcja:
{GRAPHICIMAGE: image; x; y; [w]; [h]; [angle]; [page]}
Znaczenie argumentów jest następujące:
43
44
Rozdział I. Konstrukcje języka
image
określa plik, który ma być wydrukowany na stronie. Dopuszczalne są
formaty BMP, JPG, PNG oraz TIFF. Argument może mieć wartość będącą:
nazwą pliku
plik będzie wyszukiwany zgodnie z deklaracją ścieżek,
obiektem typu FILE powiązaną z plikiem
drukowana będzie zawartość otwartego pliku,
wartością pola typu BLOBRAW lub BLOBIMAGE
drukowany będzie plik przypisany do pola,
x
współrzędna pozioma — odległość, podana w milimetrach, od lewej
krawędzi kartki do lewego górnego rogu grafiki . Jeśli współrzędna nie
mieści się na stronie, to zostanie zgłoszony błąd,
y
współrzędna pionowa — odległość, podana w milimetrach, od górnej
krawędzi kartki do lewego górnego rogu grafiki. Jeśli współrzędna nie
mieści się na stronie, to zostanie zgłoszony błąd,
w
szerokość (podana w milimetrach) drukowanej grafiki. Oryginalna grafika zostanie przeskalowana w poziomie do podanej wartości. Jeśli będzie pominięta (lub wartość parametru jest równa 0), to szerokość będzie dobrana tak, aby obrazek zachował proporcje w stosunku do podanej wysokości w parametrze h. Jeden z parametrów — w lub h — musi
mieć wartość większą od 0,
h
wysokość (podana w milimetrach) drukowanej grafiki. Oryginalna grafika zostanie przeskalowana w pionie do podanej wartości. Jeśli będzie
pominięta (lub wartość parametru jest równa 0), to wysokość będzie dobrana tak, aby obrazek zachował proporcje w stosunku do podanej szerokości w parametrze w. Jeden z parametrów — w lub h — musi mieć
wartość większą od 0,
angle
kąt obrotu drukowanej grafiki względem współrzędnych x i y. Podawany jest w stopniach i może przyjmować wartości od 0, do 360. Domyślną
wartością jest 0, czyli bez obrotu grafiki,
I.9. Konstrukcje sterujące
45
page
numer strony. W przypadku pominięcia argumentu, drukowana będzie
pierwsza strona. Dla obrazków w formatach innych niż TIFF, argument
jest ignorowany.
9 Konstrukcje sterujące
Konstrukcje sterujące pozwalają na zmianę sekwencyjnego sposobu opracowywania wzorca wydruku na taki, w którym opracowywanie pewnych fragmentów jest:
— zależne od spełnienia warunku logicznego (wybór),
— powtarzalne (iteracja).
Przejdziemy teraz do omówienia dostępnych konstrukcji sterujących języka.
9.1 IF
Wykonanie niektórych fragmentów wydruku może być uzależnione od spełnienia warunku logicznego. W celu wskazania odpowiedniego fragmentu do
wykonania stosujemy konstrukcję wyboru:
{IF: condition_1}
fragment_1
{ELIF: condition_2}
fragment_2
......
{ELSE}
fragment_n
{FI}
Czytamy ją następująco: jeśli condition_1 jest prawdą, wykonaj fragment_1, jeśli nie jest — to, jeżeli condition_2 jest prawdą, wykonaj fragment_2, jeśli nie — itd., a jeśli żaden z napotkanych warunków nie był prawdziwy — wykonaj fragment_n. Konstrukcja rozpoczyna się słowem kluczowym {IF} (z argumentem), kończy zaś słowem kluczowym {FI}. Tylko te
dwa elementy są obowiązkowe w konstrukcji; słowa {ELIF} i {ELSE} można pominąć, podobnie zresztą, jak i każdy fragment. W jednej konstrukcji
wyboru może być dowolnie dużo słów {ELIF} i tylko jedno słowo {ELSE},
46
Rozdział I. Konstrukcje języka
po którym nie może nastąpić słowo {ELIF} należące do tego samego poziomu konstrukcji. Mówimy tu o poziomie, ponieważ konstrukcja wyboru może
być zagnieżdżona w innej konstrukcji wyboru. Może być dowolnie dużo poziomów zagnieżdżenia. Pamiętajmy też, że po wykonaniu części fragment
sterowanie przechodzi do pierwszego znaku za słowem {FI}.
Przykłady Chcąc, aby na wydruku pojawiły się tylko dane dotyczące książek,
których nie zwrócono, wstawimy następującą konstrukcję:
{IF: WYP.ODDAŁ=’N’}
{WYP.CZYT().CZYT} {WYP.ODDAŁ} {
WYP.KSIĄŻKA().TYTUŁ}
{FI}
W wierszu wydruku otrzymamy nazwisko czytelnika, znacznik zwrotu książki
oraz tytuł książki dla rekordów spełniających warunek.
9.2 WHILE
Powtarzanie fragmentu programu zapewnia konstrukcja iteracyjna:
{WHILE: condition}
{DO}
fragment
{OD}
Wykonanie przebiega następująco: fragment będzie wykonywany dopóty,
dopóki warunek condition jest spełniony. Sprawdzenie warunku następuje
przed każdym wykonaniem części fragment. Gdy nie będzie on spełniony,
iteracja zostanie zakończona. Konstrukcja iteracyjna może być zagnieżdżona
w innej konstrukcji iteracyjnej, jednak maksymalna liczba zagnieżdżeń pętli
wynosi 30 (po przekroczeniu tej wartości zgłaszany jest błąd o przekroczeniu
głębokości rekurencji).
Przykłady
Taki wzorzec (z zagnieżdżoną pętlą {WHILE}):
{DIRECT}
{ n:=1; ˜˜}
47
I.9. Konstrukcje sterujące
{<1>50’Tabliczka mnożenia’}
{WHILE: (n+=1)<11}
{DO}
{ m:=1;
p:=(n+1)%*3 * 20 + 1;
{? n%*3 < 2 || line(line-10) ?};
˜˜
}
{WHILE: (m+=1)<11}
{DO}
{<{p} n} x {m} {<{p+7} ’=’} {n*m}
{OD}
{OD}
{DIRECT-}
daje w wyniku wydruk:
Tabliczka mnożenia
2 x 2
= 4
3 x 2
= 6
4 x 2
= 8
2 x 3
= 6
3 x 3
= 9
4 x 3
= 12
2 x 4
= 8
3 x 4
= 12
4 x 4
= 16
2 x 5
= 10
3 x 5
= 15
4 x 5
= 20
2 x 6
= 12
3 x 6
= 18
4 x 6
= 24
2 x 7
= 14
3 x 7
= 21
4 x 7
= 28
2 x 8
= 16
3 x 8
= 24
4 x 8
= 32
2 x 9
= 18
3 x 9
= 27
4 x 9
= 36
2 x 10 = 20
3 x 10 = 30
4 x 10 = 40
5 x 2
= 10
6 x 2
= 12
7 x 2
= 14
5 x 3
= 15
6 x 3
= 18
7 x 3
= 21
5 x 4
= 20
6 x 4
= 24
7 x 4
= 28
5 x 5
= 25
6 x 5
= 30
7 x 5
= 35
5 x 6
= 30
6 x 6
= 36
7 x 6
= 42
5 x 7
= 35
6 x 7
= 42
7 x 7
= 49
5 x 8
= 40
6 x 8
= 48
7 x 8
= 56
5 x 9
= 45
6 x 9
= 54
7 x 9
= 63
5 x 10 = 50
6 x 10 = 60
7 x 10 = 70
48
Rozdział I. Konstrukcje języka
8 x 2
= 16
9 x 2
= 18
10 x 2 = 20
8 x 3
= 24
9 x 3
= 27
10 x 3 = 30
8 x 4
= 32
9 x 4
= 36
10 x 4 = 40
8 x 5
= 40
9 x 5
= 45
10 x 5 = 50
8 x 6
= 48
9 x 6
= 54
10 x 6 = 60
8 x 7
= 56
9 x 7
= 63
10 x 7 = 70
8 x 8
= 64
9 x 8
= 72
10 x 8 = 80
8 x 9
= 72
9 x 9
= 81
10 x 9 = 90
8 x 10 = 80
9 x 10 = 90
10 x 10= 100
Wiedząc już o możliwości iteracji spróbujmy wydrukować pewne informacje z bazy danych. Wybierzmy tabelę czytelników — CZYTEL. Po zdefiniowaniu nagłówka tabeli, polecimy drukować w każdym wierszu jeden rekord bazy,
aż do osiągnięcia ostatniego rekordu:
{70*’=’}
Czytelnik
Adres
{70*’=’}
{ CZYTEL.index(’CZYT’);
n:=CZYTEL.first;
˜˜
}
{WHILE: n}
{DO}
{<1 CZYTEL.CZYT} {<31 CZYTEL.ADRES}
{ n:=CZYTEL.next; ˜˜}
{OD}
W wyniku otrzymamy wydruk:
======================================================================
Czytelnik
Adres
======================================================================
Błaszczyk Stefania
Grzybowski Wacław
Jakubowicz Wanda
Kazanecka Danuta
Koszykowski Ryszard
Kot Jan
Łopieńska Barbara
Mrowiński Paweł
Nasiorowski Zbigniew
Ring Ingeborga
Żeromska Danuta
Trąby 7, 03-146 Warszawa
Marcina z Wrocimowic 2, 03-145 Warszawa
Aluzyjna 26, 03-149 Warszawa
Sprawna 16, 03-147 Warszawa
Dzierzgońska 18, 03-145 Warszawa
Tłuchowska 6, 03-147 Warszawa
pl. Światowida 1 m.8, 03-144 Warszawa
Sprawna 35, 03-147 Warszawa
Kępa Tarchomińska 10, 03-147 Warszawa
Poetów 4 m.2, 03-147 Warszawa
Aluzyjna 38, 03-149 Warszawa
49
I.9. Konstrukcje sterujące
9.3 FOR
Aby uzyskać iterację po tabeli bazy danych możemy skorzystać z konstrukcji:
{FOR: tab_acr}
{INDEX: index_acr}
{PREFIX: key_1,key_2,...}
{FROM: key_1,key_2,...}
{TO: key_1,key_2,...}
{FILTER}
{SELECT: actions}
{DO}
fragment
{OD}
Dzięki niej możemy przebiegać tabelę rekord po rekordzie bez konieczności
osobnego sterowania zmianą rekordu. Zmiana rekordu na następny w kolejności logicznej następuje po przeczytaniu zdania {OD}. Bufor bieżący jest wypełniany zawartością rekordu po przeczytaniu zdania {DO}. Przed pierwszym
obrotem pętli bieżącym rekordem staje się pierwszy w dziedzinie i dopóki nie
zostanie osiągnięty ostatni rekord, będzie wykonywany fragment zawarty
między zdaniami {DO} i {OD}. Obowiązkowym argumentem zdania {FOR}
jest akronim tabeli.
Zdania {INDEX}, {PREFIX}, {FILTER}, {FROM}, {TO} i {SELECT},
zwane atrybutami pętli {FOR}, nie są obowiązkowe. Co więcej, pewne
grupy atrybutów nie mogą wystąpić jednocześnie. Jeśli występuje atrybut
{PREFIX}, to nie można użyć atrybutów {FROM} i {TO}. Jeśli wystąpił któryś z atrybutów {FROM} lub {TO}, to nie można po nim użyć {SELECT},
ani {FILTER}. Użycie nieprawidłowej grupy atrybutów lub umieszczenie ich
w innej kolejności niż podana spowoduje pojawienie się błędu kompilacji:
Błędny zestaw atrybutów {FOR}.
Przykłady Ostatni przykład możemy zapisać w Reporcie za pomocą tej konstrukcji:
{70*’=’}
Czytelnik
{70*’=’}
{FOR: CZYTEL}
Adres
50
Rozdział I. Konstrukcje języka
{INDEX: ’CZYT’}
{DO}
{<1 CZYTEL.CZYT} {<31 CZYTEL.ADRES}
{OD}
9.3.1 INDEX
Rekordy będą pobierane do bufora tabeli zgodnie z kolejnością określoną przez
atrybut {INDEX}. Jego argumentem jest akronim indeksu. Możemy też napisać zdanie {INDEX} bez argumentu — wtedy na ekranie operator otrzyma
w okienku listę indeksów tabeli, z której będzie można wybrać żądaną kolejność. W okienku tym nie pojawią się jednak indeksy, które zostały zadeklarowane pod MacroBUILDEREM jako ukryte. Podanie jako akronimu indeksu napisu ’*’ oznacza możliwość utworzenia przez użytkownika swojej własnej kolejności. Będzie wtedy dostępna nowa pozycja menu Index tymczasowy, po wybraniu której będzie tworzony nowy indeks. Dodatkowo do wyboru będą dostępne wszystkie wcześniej utworzone (i nie usunięte) nieukryte indeksy tymczasowe. Pominięcie atrybutu {INDEX} spowoduje, że rekordy będą wczytywane w kolejności według indeksu aktywnego przed wykonaniem konstrukcji
{FOR}.
9.3.2 PREFIX
Dziedzinę tabeli ograniczamy atrybutem {PREFIX}, którego argumentem
jest ciąg wyrażeń języka Formula oddzielonych przecinkami, zwracającymi kolejne ograniczenia na klucz indeksowy — identycznie jak lista argumentów
wywołania metody prefix() dla tabeli. Opuszczenie atrybutu {PREFIX}
spowoduje, że przetwarzane będą wszystkie rekordy tabeli, bez ograniczenia
na dziedzinę.
9.3.3 FROM, TO
Kolejne atrybuty określają nam zakres danych na wydruku: od którego
({FROM}) i do którego ({TO}) rekordu należy czytać tabelę. Argumenty zakresu są konstruowane identycznie jak dla atrybutu {PREFIX} — oddzielane przecinkami kolejne wartości klucza indeksowego. Aby użyć atrybutów
{FROM}, {TO} trzeba opuścić atrybut {PREFIX}. Pominięcie jednego z atrybutów spowoduje, że zakres danych nie będzie ograniczany z dołu (opuszczenie atrybutu {FROM}) lub z góry (przy pominięciu atrybutu {TO}). Przetwarzane będą wszystkie rekordy, w których wartość klucza jest nie mniejsza niż
podana w atrybucie {FROM} i nie większa niż podana w atrybucie {TO}. Do
I.9. Konstrukcje sterujące
porównań jest brane tyle pól z klucza indeksowego ile wyszczególniono odpowiednio w atrybucie {FROM} i {TO}. Jeśli ostatnie pole jest typu STRING
i jest początkiem odpowiedniego pola rekordu, a pozostałe wartości pól klucza
są identyczne, to klucze uznawane są za równe. Jeśli chcemy aby pola przekazanego wzorca były uznawane za zgodne z polami rekordu tylko jeśli wszystkie
są sobie równe, wówczas za ostatnim argumentem typu STRING należy dostawić znak przecinka (właściwość ta opisana jest przy metodzie prefix()).
Reguła dotyczy zarówno atrybutów {FROM}, {TO} jak i {PREFIX}.
Przykłady Jeśli indeks CZYT szereguje rekordy według nazwisk czytelników,
to wzorzec wydruku:
{FOR: WYP}
{INDEX: ’CZYT’}
{FROM: ’G’}
{TO: ’R’}
{DO}
{WYP.CZYT().CZYT} {WYP.ODDAŁ} {
WYP.KSIĄŻKA().TYTUŁ}
{OD}
zapewni nam wydruk wypożyczeń książek przez czytelników, których nazwiska rozpoczynają się na literę ’G’ i większą, aż do ’R’ włącznie.
Zauważmy, że ponieważ ograniczanie zakresu z użyciem {FROM} i {TO}
jest dokonywane z użyciem indeksu, jest ono znacznie szybsze, niż wybieranie
rekordów przez {FILTER}.
9.3.4 FILTER
Ograniczenie dziedziny w dialogu z użytkownikiem otrzymujemy stosując
atrybut {FILTER}. Wybrane na wydruk zostaną tylko te rekordy tabeli, które zawierają takie wartości w polach, jakie operator zredaguje w okienku wyświetlanym na ekranie w następstwie natrafienia przez program na atrybut
{FILTER}. Wyświetlane jest okienko zdefiniowane programem MacroBUILDER i przypisane do tabeli jako okienko wzorca lub wskazane funkcją win_patt() (w trakcie trwania programu). Jeżeli brakuje ustalonego okienka
wzorca zostanie wyświetlone okienko redagowania (wskazane w MacroBUILDERZE lub funkcją win_edit()), w przypadku braku również tego okienka,
zostanie zgłoszony błąd.
51
52
Rozdział I. Konstrukcje języka
Przykłady
Rozpatrzmy następujący wzorzec wydruku:
{FOR: WYP}
{INDEX}
{FILTER}
{DO}
{WYP.CZYT().CZYT} {WYP.ODDAŁ} {
WYP.KSIĄŻKA().TYTUŁ}
{OD}
Łatwo zauważyć, że wydrukuje on zawartość tabeli wypożyczeń (WYP) — ściślej pola zawierające dane czytelnika (CZYT) z odwołania słownikowego do tabeli CZYTEL, znacznik zwrotu książki (ODDAŁ) oraz tytuł książki z odwołania
słownikowego pola KSIĄŻKA do pola TYTUŁ tabeli KATAL. Użycie instrukcji
WYP.KSIĄŻKA().TYTUŁ (i analogicznej dla pola CZYT) powoduje wyprowadzenie wartości pola TYTUŁ tabeli KATAL rekordu powiązanego z bieżącym
rekordem tabeli WYP. Ponieważ nie podaliśmy argumentu w zdaniu {INDEX},
na ekranie ukaże się okienko z dostępnymi do wyboru indeksami. Po wybraniu
żądanej kolejności program napotka na zdanie {FILTER} i wyświetli odpowiednie okienko do wprowadzenia wzorca. Wpisując w okienku wzorca do pól
niepuste wartości, operator otrzyma wydruk tylko tych rekordów, w których
zawartość pól o odpowiednich nazwach jest taka, jak wypełnił w okienku. Dla
pól typu tekstowego wystarczy, że zawartość jest początkiem nazwy.
9.3.5 SELECT
Innym sposobem wpływu na wybór rekordów przez użytkownika i ostatnim
z atrybutów konstrukcji {FOR} jest zdanie {SELECT}. Jego użycie wyklucza
umieszczenie atrybutów {FILTER}, {FROM} i {TO}. Po natrafieniu na nie
program zaprezentuje okienko wertowania tabeli z możliwością wyboru odpowiednich rekordów. Dla niepustej dziedziny dostępna będzie zawsze pozycja menu:
— TEN, po wybraniu której, wykonane zostanie ciało pętli dla bieżącego
rekordu. Po zakończeniu, bieżącym rekordem stanie się kolejny w dziedzinie (o ile istnieje). Jeśli akcja zostanie wybrana przy zaznaczonych
rekordach w okienku, to ciało pętli będzie wykonane dla wszystkich zaznaczonych rekordów w kolejności widocznej w okienku. Po zakończeniu, bieżącym rekordem będzie następny w stosunku do ostatnio przetworzonego lub pierwszy nieprzetworzony, jeśli przetwarzanie zostało
przerwane (np. na skutek zmiany zawartości rekordu od momentu zaznaczenia),
I.9. Konstrukcje sterujące
— standardowa akcja Szukaj, jeśli jest zdefiniowana dla okienka bez
zmienionej nazwy w menu.
Dodatkowo, jeśli fraza {SELECT} nie ma przekazanego parametru, zaś
w okienku będzie zdefiniowana akcja typu Menu o nazwie Szukaj zawierająca pozycje o nazwach:
— Szukaj dokładnie,
— szukaj Kontekstowo,
to wspomniane pozycje menu również zostaną dołączone do okienka.
W takim przypadku, będzie dołączana również akcja #F3, o ile została zdefiniowana dla okienka.
Można również dołączać dowolne akcje okienka. Wskazuje je się wtedy
poprzez argument frazy {SELECT: }, umieszczony po dwukropku. Ma on
postać napisu, składającego się z dwóch części oddzielonych dwukropkiem —
pierwsza część zawiera wyróżniki akcji okienka zdefiniowane dla niepustej
dziedziny, druga dla pustej. Brak dwukropka oznacza brak dołączanych akcji
dla pustej dziedziny. Parametr równy pustemu napisowi lub jego brak oznacza, że żadne dodatkowe akcje nie zostaną dołączone do okienka. Wyróżniki
akcji okienka muszą znajdować się w kolejności, w jakiej akcje mają się pojawić
w menu. Wyróżnikiem akcji jest pierwsza wielka litera w nazwie — mała dla
standardowych akcji — odpowiednio jeden ze znaków: dkpuvw3+ dla oznaczenia akcji Dołącz, Kolejność, Okienko, Popraw, Rekord, Szukaj, Usuń, Dołącz
za, Wyświetl, #F3 oraz +Słownik, wielka litera dla akcji typu Formuła i Menu.
Jeśli mają być włączone pozycje podrzędne, to ich wyróżniki należy umieścić
w nawiasach za wyróżnikiem akcji menu. Identyczną regułę stosuje się dla zagnieżdżonych akcji menu.
Operator za pomocą akcji TEN na wybranych rekordach (klawisz Enter ),
będzie mógł zdecydować, które z nich mają być objęte wydrukiem i w jakiej kolejności. Bezpośrednio po wskazaniu rekordu wykonywane są instrukcje pętli
{FOR} z wartością bufora pobraną z rekordu. Zakończenie wybierania nastąpi po naciśnięciu klawisza Esc . Jedynie dzięki zdaniu {SELECT} operator
ma możliwość wyboru rekordów tabeli w dowolnej kolejności (nie posortowanych) do wydruku.
Przykłady Podczas wykonywania poniższego fragmentu:
53
54
Rozdział I. Konstrukcje języka
{FOR: TAB}
{SELECT: ’dI(DO):d’}
{DO}
{TAB.ID}
{OD}
pojawi się okienko wertowania tabeli TAB z dodaną standardową akcją Dołącz
(dla pustej i niepustej dziedziny) oraz z menu Informacje z akcją Dodatkowe
i Opis (tylko dla niepustej dziedziny).
Konstrukcja {FOR} zapamiętuje i przywraca kontekst tabeli przed i po wykonaniu. Oznacza to, że przed i po wykonaniu sprawozdania będzie taki sam
bieżący rekord, indeks oraz prefiks. Na czas wykonywania pętli są ustawiane
odpowiednie zmiany zgodnie z podanymi atrybutami. Co więcej, instrukcja
{FOR} zapamiętuje i odtwarza kontekst przy każdym obrocie pętli. Pozwala to na swobodne zmiany pozycji bieżącego rekordu, indeksu lub prefiksu.
W każdym obrocie pętli na początku będzie wczytany do bufora kolejny rekord zgodnie z kolejnością opisaną atrybutami instrukcji {FOR}.
Przykłady Poniższy fragment wypisuje obok nazwiska każdego pracownika
nazwiska innych pracowników, którzy mają to samo imię. Wykorzystaliśmy
w nim zagnieżdżenie pętli {FOR} działających na tej samej tabeli.
{FOR: PRAC}
{INDEX: ’NAZW’}
{DO}
{ nazw:=PRAC.NAZW} { im:=PRAC.IM} { ’:’
}{FOR: PRAC
}{INDEX: ’IM’
}{PREFIX: im
}{DO}{IF: (PRAC.NAZW<>nazw) & (PRAC.IM=im)
} {PRAC.NAZW
}{FI}{OD}
{OD}
Wiersz wydruku będzie miał następującą postać:
Kowalski Jan : Kwiatkowski Nowak
Zwróćmy uwagę, że wszystkie nazwiska osób o tym samym imieniu będą wypisane w tym samym wierszu. Dzieje się tak dlatego, że cała wewnętrzna pętla
{FOR} nie wyprowadza znaku końca wiersza.
55
I.9. Konstrukcje sterujące
Do odkładania i przywracania kontekstu tabeli w pętli {FOR} są stosowane
te same mechanizmy co w funkcjach cntx_psh() i cntx_pop(). Dlatego,
w celu prawidłowego wykonania pętli, należy stosować następujące ograniczenia w wykorzystaniu tych funkcji na rzecz przetwarzanej tabeli:
— nie można odtwarzać kontekstu nie odłożonego w bieżącym obrocie pętli;
— w każdym obrocie pętli trzeba odtworzyć wszystkie odłożone w nim
konteksty.
9.4 FIRST
Poniższy wzorzec wydruku ma drukować kartotekę czytelników. Nad dwoma
polami powstałej tabeli ukaże się tytuł — objaśnienia zawartości pól, a więc
napis ’Czytelnik’ i ’Adres’:
Czytelnik
Adres
{70*’=’}
{FOR: CZYTEL}
{INDEX: ’CZYT’}
{DO}
{CZYTEL.CZYT} {<31 CZYTEL.ADRES}
{OD}
Zauważmy jednak, że jeśli tabela będzie pusta, również otrzymamy tytuł na
pustej stronie wydruku. Aby uniknąć takiej sytuacji, stosujemy konstrukcję
{FIRST}:
{FOR: CZYTEL}
{INDEX: ’CZYT’}
{DO}
{FIRST}
Czytelnik
{70*’=’}
{FIRST-}
{CZYTEL.CZYT} {<31 CZYTEL.ADRES}
{OD}
Konstrukcja {FIRST} ma postać:
Adres
56
Rozdział I. Konstrukcje języka
{FIRST}
fragment
{FIRST-}
gdzie fragment jest dowolną poprawną składniowo konstrukcją języka. Cały fragment pomiędzy {FIRST} i {FIRST-} będzie wykonywany tylko
w pierwszym przebiegu iteracji. Jeśli tabela jest pusta, fragment nie wykona
się ani razu. Konstrukcja ta może być zastosowana tylko w ciele pętli {FOR}
i {WHILE}. Zabronione jest użycie konstrukcji {FIRST} w sekcji {TOTAL}
oraz poza pętlą.
9.5 ADD
Często, podczas drukowania kolejnych wierszy, zachodzi potrzeba sumowania
wartości niektórych pól liczbowych i wypisania takiej sumy na końcu wydruku. Równie często zależy nam na tym, aby drukować sumy częściowe, np. sumy z pewnego zbioru rekordów o tym samym kluczu . Zadanie nasze możemy
zrealizować, używając zmiennych, w których będziemy sumować odpowiednie wartości, wypisywać je w chwili zmiany klucza i zerować je, przygotowując w ten sposób do sumowania wartości dla nowego klucza. W języku Report
jest wszakże możliwość zautomatyzowania tych czynności. System umożliwia
w konstrukcjach iteracyjnych wykorzystanie do tego celu sumatorów.
W ciele pętli możemy instrukcją {ADD} dodawać do sumatora wartość
wyrażenia liczbowego. Do sumatorów odwołujemy się przez jego nazwę, dzięki czemu możemy w jednej pętli użyć kilku niezależnych sumatorów (jednak
nie więcej niż 50). Do wartości sumatora można się odwołać we fragmencie
{TOTAL}, wykonywanym po zakończeniu przetwarzania pętli lub grupy (jeśli
użyliśmy argumentu grupującego). Instrukcja {ADD} ma następujący format:
{ADD: sum_name; format; num_expression}
Nazwę sumatora sum_name tworzymy identycznie jak nazwy zmiennych. Podawany format jest identyczny z formatem pola, z jednym wyjątkiem: dopuszczalny jest format #, blokujący drukowanie dodawanego wyrażenia numerycznego — num_expression. Konstrukcja {ADD} nie może wystąpić
poza pętlą. Takie użycie będzie sygnalizowane błędem w trakcie wykonywania
sprawozdania.
I.9. Konstrukcje sterujące
Przykłady Jako przykład podamy wzorzec wydruku generujący 10 liczb losowych. W podsumowaniu znajdzie się suma oraz suma kwadratów tych liczb,
natomiast nie będą drukowane wartości kwadratów liczb.
{
i:=0;
los:="int(100*rand)";
˜˜
}
{WHILE: i < 10}
{DO}
Losowanie {i+=1} {ADD: liczby; >30; a:= los()
} {ADD: kwad; #; a*a}
{TOTAL}
{30*’=’}
Suma: {>30 sum(’liczby’)}
Suma kwadratów: {>30 sum(’kwad’)}
{OD}
9.6 TOTAL
Fragment zawarty pomiędzy {TOTAL} a {OD} wykonuje się zawsze po zakończeniu instrukcji pętli (również w przypadku gdy nie był wykonany żaden
obrót). Wartość sumatora możemy pobrać wywołując funkcję języka Formula
sum() wywołaną z argumentem będącym nazwą sumatora. Oprócz zwykłej
instrukcji {TOTAL} można użyć wersji rozbudowanej:
{TOTAL: group_expression}
Fragment następujący po takiej instrukcji jest wykonywany po grupie obrotów
dla których wyrażenie grupujące group_expression (liczone na początku
każdego obrotu) miało identyczną wartość. Najczęściej używamy jej w pętli
{FOR} w celu uzyskania podsumowań globalnych i częściowych dla pewnej
grupy rekordów.
Przykłady Obliczymy wartość książek wypożyczonych przez każdego z czytelników i nie zwróconych (mających znacznik wypożyczenia WYP.ODDAŁ
równy ’N’). Wypiszemy również globalną wartość aktualnie wypożyczonych
książek.
57
58
Rozdział I. Konstrukcje języka
{<1>90 ’Wartość książek wypożyczonych’}
{90*’-’}
|{<23>90 ’Książka’}
Czytelnik
+{68*’-’}
|{<23>73 ’Tytuł’} {>90 ’Cena’}
{90*’=’}
{FOR: WYP}
{INDEX: ’CZYT’}
{DO}
{IF: WYP.ODDAŁ=’N’}
{WYP.CZYT().CZYT} {<25 WYP.KSIĄŻKA().TYTUŁ
} {ADD: ceny; >{90}.2; KATAL.CENA}
{FI}
{TOTAL: WYP.CZYT().CZYT}
{<74 (90-73)*’-’}
{<74 ’RAZEM’} {>{90}.2 sum(’ceny’)}
{TOTAL}
{90*’=’}
{<56 ’RAZEM WSZYSTKIE POZYCJE’
} {>{90}.2 sum(’ceny’)}
{OD}
Sumujemy na dwóch poziomach, według kolejności określonej przez nazwiska
czytelników (indeks CZYT). Pierwszy z nich jest określany przez wartość pola
NAZW powiązanego rekordu tabeli CZYTEL. Jeśli wartość ta się zmieni, drukujemy sumę częściową — wartość książek aktualnie wypożyczonych przez jednego czytelnika. Drugi poziom jest sumą całkowitą, dla wszystkich aktualnych
wypożyczeń z biblioteki. Możemy wykorzystać do obliczania tych sum jeden
sumator. Sumator zostaje automatycznie podzielony na tyle podsumatorów, ile
zostało zadeklarowanych fragmentów {TOTAL} w danej pętli. Każde użycie
{ADD} dodaje żądaną wartość do wszystkich podsumatorów. Każdy z podsumatorów jest zawsze zerowany przed rozpoczęciem pętli oraz po każdym wykonaniu odpowiadającego mu fragmentowi {TOTAL}. Wynikiem wykonania
wzorca wydruku jest wydruk:
Wartość książek wypożyczonych
-----------------------------------------------------------------------------------------|
Książka
Czytelnik
+-------------------------------------------------------------------|
Tytuł
Cena
==========================================================================================
Błaszczyk Stefania
Atlas roślin łąkowych i pastwiskowych
50.00
----------------RAZEM
50.00
59
I.9. Konstrukcje sterujące
Grzybowski Wacław
Jeśli zimową nocą podróżny ...
1.00
----------------RAZEM
1.00
Jakubowicz Wanda
Wszechświat - maszyna czy myśl?
1.00
----------------RAZEM
1.00
Kazanecka
Kazanecka
Kazanecka
Kazanecka
O miłości
Jaki to kwiat?
Dojrzewać do miłości
Słownik mitów i tradycji kultury
8.00
5.00
1.00
3.00
----------------RAZEM
17.00
Rok na działce
2.00
----------------RAZEM
2.00
Danuta
Danuta
Danuta
Danuta
Koszykowski Ryszard
Mrowiński Paweł
Mrowiński Paweł
Mieszkamy wśród kwiatów
Poezje
----------------RAZEM
0.00
----------------RAZEM
0.00
35.00
1.00
----------------RAZEM
36.00
----------------RAZEM
0.00
Ring Ingeborga
Ewolucja kosmosu i kosmologii
Żeromska Danuta
Żeromska Danuta
Wybór literatury do zabaw i zajęć w przedszkolu
Nauka i świat współczesny
2.00
----------------RAZEM
2.00
8.00
1.00
----------------RAZEM
9.00
==========================================================================================
RAZEM WSZYSTKIE POZYCJE
118.00
Od razu zauważamy, że jeśli czytelnik ma tylko jedną książkę w czytaniu,
suma częściowa jest równa cenie tej książki. Co więcej, dla czytelników którzy oddali wszystkie wypożyczone przez nich książki pojawiają się dodatkowo podsumowania o wartości 0. Możemy więc zrezygnować z wypisywania
’RAZEM’ dla takich wypadków, polepszając czytelność i oszczędzając miejsce:
{<1>90 ’Wartość książek wypożyczonych’}
{90*’-’}
|{<23>90 ’Książka’}
Czytelnik
+{68*’-’}
|{<23>73 ’Tytuł’} {>90 ’Cena’}
{90*’=’}
{FOR: WYP}
{INDEX: ’CZYT’}
{DO}
{IF: WYP.ODDAŁ=’N’}
{WYP.CZYT} {<25 WYP.KSIĄŻKA().TYTUŁ
60
Rozdział I. Konstrukcje języka
} {ADD: ceny; >{90}.2; KATAL.CENA
} {ADD: licznik; #; 1}
{FI}
{TOTAL: WYP.CZYT}
{IF: sum(’licznik’)>1}
{<74 (90-73)*’-’}
{<74 ’RAZEM’} {>{90}.2 sum(’ceny’)}
{FI}
{IF: sum(’licznik’)>0}
{FI}
{TOTAL}
{90*’=’}
{<56 ’RAZEM WSZYSTKIE POZYCJE’
} {>{90}.2 sum(’ceny’)}
{OD}
Teraz wykorzystujemy do sumowania dwa sumatory — ceny i licznik. Oba
składają się dwóch podsumatorów — tyle jest użytych fragmentów {TOTAL}
w pętli. W pierwszym sumujemy, jak uprzednio, ceny książek aktualnie wypożyczonych przez jednego czytelnika (w podsumatorze związanym z fragmentem {TOTAL: WYP.CZYT}) oraz globalną sumę cen aktualnie wypożyczonych książek (w podsumatorze związanym z drugim fragmentem {TOTAL}).
W drugim sumujemy liczbę książek wypożyczonych przez czytelnika oraz
globalną liczbę wypożyczeń (w dwóch podsumatorach). Zapisano to w zdaniu {ADD: licznik; #; 1}. Zdanie to dodaje po prostu 1 do sumatora.
Wynik formuły (liczba 1) nie drukuje się z powodu symbolu #, użytego jako drugi argument. Wartość drugiego sumatora odczytujemy funkcją sum(),
podając jako argument nazwę — ’licznik’. Wywołania użyte we fragmencie po {TOTAL: WYP.CZYT} będą się odnosiły do podsumatora związanego z wypożyczeniami pojedynczego czytelnika. W naszym przykładzie
sprawdzamy, czy istnieje więcej niż jedno wypożyczenie książki przez jednego czytelnika (sum(’licznik’)>1) i dopiero wtedy drukujemy sumę częściową ’RAZEM’. Jeśli przy przetwarzaniu grupy była wyprowadzona przynajmniej jedna linia (sum(’licznik’)>0), to oddzielamy ją pustą linią.
Zwróćmy uwagę na użycie WYP.CZYT jako wyrażenia grupującego zamiast
WYP.CZYT().CZYT. W tym przykładzie jedno i drugie wyrażenie właściwie
identyfikuje danego czytelnika (pierwsze wskazuje na unikalny numer rekordu
w danym zbiorze, drugie na pole, zawierające nazwisko i imię czytelnika, rów-
61
I.9. Konstrukcje sterujące
nież zdefiniowane jako unikalne dla tabeli CZYTEL). W wyniku otrzymujemy
wydruk:
Wartość książek wypożyczonych
-----------------------------------------------------------------------------------------|
Książka
Czytelnik
+-------------------------------------------------------------------|
Tytuł
Cena
==========================================================================================
Błaszczyk Stefania
Atlas roślin łąkowych i pastwiskowych
50.00
Jakubowicz Wanda
Wszechświat - maszyna czy myśl?
Grzybowski Wacław
Jeśli zimową nocą podróżny ...
Kazanecka
Kazanecka
Kazanecka
Kazanecka
O miłości
Jaki to kwiat?
Dojrzewać do miłości
Słownik mitów i tradycji kultury
Danuta
Danuta
Danuta
Danuta
Koszykowski Ryszard
Rok na działce
Mrowiński Paweł
Mrowiński Paweł
Mieszkamy wśród kwiatów
Poezje
Ring Ingeborga
Ewolucja kosmosu i kosmologii
Żeromska Danuta
Żeromska Danuta
Wybór literatury do zabaw i zajęć w przedszkolu
Nauka i świat współczesny
1.00
1.00
8.00
5.00
1.00
3.00
----------------RAZEM
17.00
2.00
35.00
1.00
----------------RAZEM
36.00
2.00
8.00
1.00
----------------RAZEM
9.00
==========================================================================================
RAZEM WSZYSTKIE POZYCJE
118.00
Jeśli interesuje nas tylko sumaryczna wartość książek, wypożyczonych
przez każdego czytelnika, napiszemy:
Wartość książek wypożyczonych
-------------------------------------------------Czytelnik
Kwota
==================================================
{FOR: WYP}
{INDEX: ’CZYT’}
{DO}
{IF: WYP.ODDAŁ=’N’}
{ADD: ceny; #; WYP.KSIĄŻKA().CENA
}{ADD: licznik; #; 1}
{FI}
{TOTAL: WYP.CZYT().CZYT}
{IF: sum(’licznik’) > 0}
{grp_fld} {>50.2 sum(’ceny’)}
{FI}
{TOTAL}
==================================================
62
Rozdział I. Konstrukcje języka
RAZEM WSZYSTKIE POZYCJE {>50.2 sum(’ceny’)}
ŚREDNIO NA WYPOŻYCZENIE {>50.2
{? sum(’licznik’)<>0
|| sum(’ceny’)/sum(’licznik’)
|| ’---’
?}
}
{OD}
Tu drukujemy więc jedynie podsumowania pierwszego poziomu: oba zdania
sumujące zawierają # jako argument. Dodatkowo, możemy obliczyć średnią
wartość wypożyczonej książki, sięgając na drugim poziomie zagnieżdżenia
konstrukcji {TOTAL} do rejestru ceny (sum(’ceny’) — suma cen książek)
i licznik (sum(’licznik’) — liczba wypożyczeń), co pokazuje wydruk:
Wartość książek wypożyczonych
-------------------------------------------------Czytelnik
Kwota
==================================================
Błaszczyk Stefania
Grzybowski Wacław
50.00
1.00
Jakubowicz Wanda
1.00
Kazanecka Danuta
17.00
Koszykowski Ryszard
Mrowiński Paweł
2.00
36.00
Ring Ingeborga
2.00
Żeromska Danuta
9.00
==================================================
RAZEM WSZYSTKIE POZYCJE
118.00
ŚREDNIO NA WYPOŻYCZENIE
9.08
Zwróćmy uwagę, na użycie funkcji grp_fld() na pierwszym poziomie konstrukcji {TOTAL}. Zwraca ono wartość grupującą, jaką przyjmowały rekordy z właśnie zakończonej grupy — w naszym przykładzie jest to nazwisko
czytelnika. Należy odnotować, że bezpośrednie odwołanie się do wyrażenia
WYP.CZYT().CZYT będzie zawierać nazwisko czytelnika już nowej grupy,
więc nie tej, dla której zostało dokonane podsumowanie.
Podczas wykonywania fragmentu {TOTAL} z argumentem grupującym,
w buforze wczytany jest (poza przypadkiem ostatniego rekordu w dziedzinie)
rekord z nowej grupy. W podsumatorach są obliczone wartości dla zakończonej grupy, a jej wartość grupująca jest zwracana przez funkcję grp_fld().
I.9. Konstrukcje sterujące
Konstrukcję {TOTAL} z argumentem można umieścić wielokrotnie. Ogólna
postać pętli ({WHILE} lub {FOR}) ma schemat:
{DO}
fragment_body
{TOTAL: group_expression_1}
fragment_1
{TOTAL: group_expression_2}
fragment_2
.......
{TOTAL}
fragment_total
{OD}
wykona się po grupie wykonań fragment_body, na początku których wartość wyrażenia group_expression_1 była identyczna. Analogicznie fragment_2 będzie wykonany po grupie wykonań fragment_body, na początku których wartość wyrażenia group_expression_2 była identyczna (itd.). Jeśli zmieniła się wartość group_expression_1, to wyrażenie group_expression_2 będzie wyliczane
po wykonaniu fragment_1. Wyrażenia grupujące są wyliczane po sprawdzeniu warunku (dla pętli {WHILE}) oraz po odczytaniu rekordu (dla pętli
{FOR}), ale przed wykonaniem ciała pętli. Z kolei fragment_total wykonuje się zawsze po zakończeniu pętli. Jeśli chcemy napisać fragment, który się
wykona na zakończenie pętli, ale pod warunkiem, że miała ona przynajmniej
jeden obrót, to wystarczy użyć w konstrukcji {TOTAL} wyrażenia grupującego
o stałej wartości — np. {TOTAL: 1}.
Można używać tego samego sumatora w zagnieżdżonych pętlach.
fragment_1
Przykłady Rozpatrzmy przykład obrazujący wydatki w latach od rpocz do
rkoń z rozpisaniem na instytuty i działy:
{rok:=rpocz; ˜˜}
{WHILE: rok <= rkoń}{DO}
{WYDATKI.use(’wyd’+$rok); ˜˜}
{<1>80 ’Wydatki na rok ’+$rok}
{FOR: WYDATKI}
{INDEX: ’INST_DZ’}
{DO}
63
64
Rozdział I. Konstrukcje języka
{ADD: suma; #; WYDATKI.KWOTA}
{TOTAL: WYDATKI.DZIAŁ}
Dział {grp_fld}: {>80 sum(’suma’)}
{TOTAL: WYDATKI.INSTYTUT}
Instytut {grp_fld}: {>80 sum(’suma’)}
{TOTAL}
Razem: {sum(’suma’)}
{OD}
{rok+=1; ˜˜}
{TOTAL: 1}
Łączna kwota wydatków w latach {rpocz} - {rkoń}
Razem: {sum(’suma’)}
{OD}
Podsumowanie dla instytutu pojawi się po podsumowaniach dla wszystkich
jego działów — zapewni to indeks INST_DZ o polach INSTYTUT i DZIAŁ
oraz umieszczenie fragmentu grupującego instytuty za fragmentem grupującym działy. Zwróćmy uwagę, że jeśli rok końcowy jest wcześniejszy od początkowego, to nie zostanie wyprowadzona żadna linia. Z kolei, jeśli w danym roku
nie było żadnych wydatków, to informacja o tym znajdzie się na wydruku.
9.7 EXIT
Konstrukcja {EXIT} umożliwia przerwanie wykonywania iteracji lub całego
sprawozdania. Wykonanie instrukcji {EXIT} w pętli ({FOR} lub {WHILE})
powoduje jej zakończenie bez wykonywania dalszych instrukcji (włącznie
z konstrukcją {TOTAL}). Jeśli była wykonana w pętli zagnieżdżonej, to nie powoduje zakończenia pętli zewnętrznej — kończy się tylko pętla wewnętrzna.
Wykonanie instrukcji poza pętlą kończy działanie sprawozdania. Konstrukcję
można wywołać z argumentem:
{EXIT: condition}
gdzie condition jest wyrażeniem numerycznym. W takim przypadku przerwanie (iteracji lub sprawozdania) nastąpi, jeśli spełniony będzie warunek
condition, tzn. wyrażenie będzie miało wartość różną od 0.
I.10. Podprogramy i włączenia
Przykłady Obejrzyjmy wzorzec wydruku:
{<1>60 ’Najdroższe książki w bibliotece’}
{’-’*60}
{<10 ’Książka’} {<45 ’Cena’}
{’-’*60}
{ ilość:=0; ˜˜}
{FOR: KATAL}
{INDEX: ’CENA’}
{DO}
{KATAL.TYTUŁ}{>{54}.2 KATAL.CENA} zł.
{EXIT: (ilość+=1)=10}
{OD}
Na wydruku znajdą się tytuły i ceny książek posortowane według wartości.
Jednak dzięki instrukcji {EXIT} ich ilość nie przekroczy 10.
10 Podprogramy i włączenia
Powtarzalne fragmenty we wzorcu wydruku mogą być zdefiniowane jeden raz,
aby mogły być potem przywołane wielokrotnie w różnych miejscach programu. Niekiedy długie wzorce dzieli się na zamknięte strukturalnie części — odpowiedniki procedur — aby łatwiej zapanować nad skomplikowaną całością.
Innym razem zachodzi potrzeba stworzenia fragmentu wzorca dynamicznie.
10.1 MACRO
Konstrukcja {MACRO} pozwala na zdefiniowanie fragmentu sprawozdania jako podprogram. Ogólna postać definiowania podprogramu wygląda:
{MACRO: name}
fragment
{MACRO-}
gdzie fragment jest dowolną konstrukcją języka, zaś name wyrażeniem typu znakowego, określającym nazwę podprogramu. Nazwa podprogramu może być dowolnym, niepustym ciągiem znaków składającym się z liter, cyfr
i znaku podkreślenia, nie rozpoczynającym się od cyfry. Nie wolno definiować podprogramu wewnątrz pętli, innego podprogramu, ani we fragmencie
65
66
Rozdział I. Konstrukcje języka
{ENTIRE}.
Nie można definiować po raz drugi (w tym samym wzorcu wydruku) podprogramu o tej samej nazwie. Najpierw należy usunąć stary podprogram zdaniem {CLEAR: name}.
10.2 SUBSTITUTE
Podprogram można wywołać konstrukcją:
{SUBSTITUTE: name}
gdzie name jest wyrażeniem typu znakowego, zwracającym nazwę zdefiniowanego wcześniej podprogramu.
Przykłady
Zdefiniujmy następujący podprogram:
{MACRO: ’jeden’}
{<{kolumna} ’’}
O
{<{kolumna} ’’}/-+-\
{<{kolumna} ’’}
|
{<{kolumna} ’’} / \
{<{kolumna} ’’}/
\
{MACRO-}
{MACRO: ’grupa’}
{DIRECT}
{ l:=line; ˜˜}
{WHILE: liczba>0}
{DO}
{ line(l); liczba-=1; ˜˜}
{SUBSTITUTE:
kolumna:=liczba*5+1; ’jeden’}
{OD}
{DIRECT-}
{MACRO-}
{MACRO: ’lud’}
{WHILE: l_wiersz>0}
{DO}
{ l_wiersz-=1; ˜˜}
{SUBSTITUTE: liczba:=l_kol; ’grupa’}
{OD}
67
I.10. Podprogramy i włączenia
{MACRO-}
{SUBSTITUTE: l_wiersz:=3; l_kol:=5; ’lud’}
W kolumnie kolumna, wywołany podprogram ’jeden’ wydrukuje:
O
/-+-\
|
/ \
/
\
Podprogram ten wywoływany jest w treści podprogramu ’grupa’, której pętla jest wykonywana liczba razy. Dzięki użyciu {DIRECT}, ’jeden’ jest
drukowany liczba razy obok siebie. Zaś ’grupa’ jest wywoływana l_wiersz razy w treści podprogramu ’lud’. Motyw ’jeden’ jest drukowany w l_wiersz wierszach i l_kol kolumnach, zgodnie z głównym wywołaniem:
{SUBSTITUTE: l_wiersz:=3; l_kol:=5; ’lud’}
Wynikiem jest następujący wydruk:
O
O
O
O
O
/-+-\/-+-\/-+-\/-+-\/-+-\
|
|
|
|
|
/ \
/ \
/ \
/ \
/ \
/
\/
O
\/
O
\/
O
\/
O
\
O
/-+-\/-+-\/-+-\/-+-\/-+-\
|
|
|
|
|
/ \
/ \
/ \
/ \
/ \
/
\/
O
\/
O
\/
O
\/
O
\
O
/-+-\/-+-\/-+-\/-+-\/-+-\
|
/ \
/
|
/ \
\/
|
/ \
\/
|
/ \
\/
|
/ \
\/
\
68
Rozdział I. Konstrukcje języka
10.3 CLEAR
Instrukcja:
{CLEAR: name}
usuwa definicję podprogramu o nazwie name, w dalszej części sprawozdania
nie będzie można już go wywołać. Od tej chwili nazwa może być użyta do zdefiniowania nowego fragmentu.
10.4 INCLUDE
Drugą możliwością (obok podprogramów) definiowania powtarzalnych fragmentów, jest ich zapisanie do oddzielnych zbiorów tekstowych. W celu wykorzystania takiego fragmentu we wzorcu wydruku wystarczy włączyć zapisany
tam fragment następującą konstrukcją:
{INCLUDE: file_name}
gdzie file_name zastępujemy dowolnym tekstem — nazwą włączanego pliku. Będzie on poszukiwany według deklaracji ścieżek (plik .pth) jeżeli użyjemy funkcji rep_tran() lub konstrukcji {REP} albo w katalogu określonym
przez opcje wywołania kompilatora MacroREPORT (Linux) oraz report.exe
(dla Windows). Użycie konstrukcji {INCLUDE} powoduje zastąpienie zdania
treścią włączanego pliku z pominiętym znakiem końca linii w ostatnim wierszu. Kodowanie pliku określane jest na podstawie pierwszej linii. Jeśli rozpoczyna się od znaków
:!UTF-8
(podane znaki mogą być ewentualnie poprzedzone znacznikiem BOM, czyli
ciągiem znaków o kodach: 0xef 0xbb 0xbf), to zostanie ona zignorowana, zaś
reszta pliku będzie traktowana jako kodowana w UTF-8. W przeciwnym przypadku plik będzie traktowany jako kodowany w standardzie Mazovii.
Dopuszcza się włączanie wielopoziomowe — we włączanych zbiorach może występować konstrukcja {INCLUDE}. Zbiór może być włączany do dowolnej liczby wzorców wydruku.
I.10. Podprogramy i włączenia
Przykłady Obejrzyjmy następujący wzorzec wydruku:
{TITLE: Podsumowanie}
{INCLUDE: printer.rpi}
{INCLUDE: sum.rpi}
W pliku printer.rpi mogą znajdować się konstrukcje opisu strony używane w większości sprawozdań — stosowne zdanie {PRINTER}, definicje nagłówków i stopek, marginesu itp. W pliku sum.rpi — treść samego sprawozdania.
10.5 REP
Konstrukcją umożliwiającą wykonanie fragmentu sprawozdania z wzorca
utworzonego dynamicznie jest {REP}. Ma ona postać:
{REP: report}
gdzie report oznacza dowolne wyrażenie zwracające tekst, będący poprawnym fragmentem języka Report. W konstrukcji {REP} można umieszczać
dowolne znaki. Nie obowiązuje ogrniczenie dla wzorca raportu pozwalające
umieszczać znaki o kodach ASCII nie mniejszych od kodu spacji oraz znak
końca wiersza. Na zwracany fragment nałożone są pewne ograniczenia. Nie
można definiować nagłówków, stopek ani sygnatur. Nie dopuszcza się definiowania nowych podprogramów ({MACRO}), można jednak wykorzystywać wcześniej zdefiniowane. Dozwolone jest ponowne wywołanie konstrukcji
{REP}, jednak poziom zagnieżdżenia tej konstrukcji nie może przekraczać 10
wywołań. Nie można odwoływać się do sumatorów wcześniej zdefiniowanych,
można natomiast tworzyć nowe - będą widocznie tylko w obrębie wykonania konstrukcji. Zabronione jest użycie konstrukcji {TITLE} i {PRINTER}.
Możliwe jest natomiast zdefiniowanie fragmentów {BEGIN} i {END} dla wykonywanego konstrukcją {REP} podprogramu.
Jeśli argument {REP} nie jest poprawnym sprawozdaniem — występują
w nim błędy składniowe, to zostaną zgłoszone w momencie wywołania. Fragment wywoływany poprzez {REP} jest traktowany jako niezależne sprawozdanie. Przy jego wykonaniu obowiązują te same zasady dotyczące odtwarzania
kontekstów i zrywania transakcji co zwykłego sprawozdania (opisane są dla
prologu i epilogu sprawozdania).
Jednym z zastosowań tej konstrukcji jest dynamiczne włączanie fragmentów sprawozdania. Można dzięki temu włączyć różny fragment w zależności
od wartości zmiennych. Pozwala to również na przekroczenie granicy 512KB
69
70
Rozdział I. Konstrukcje języka
dla wzorca sprawozdania, co mogło by mieć miejsce przy włączaniu statycznym.
Przykłady Poniższe wywołanie pozwala na włączenie fragmentu zapisanego
w pliku, którego nazwa jest przechowywana w zmiennej plik:
{REP: ’{INCLUDE: ’ + plik + ’}’ }
11 Prolog i epilog sprawozdania
Wykonywane sprawozdanie może być w dowolnym momencie przerwane
przez operatora. Po przerwaniu sprawozdania wywoływana jest niejawnie
funkcja undo(), odtwarzane są wszystkie konteksty tabel odłożone w trakcie przetwarzania sprawozdania, po czym wykonywane są kolejne instrukcje
po wywołaniu rep_exec(). Zwróćmy jednak uwagę, że końcowe instrukcje
umieszczone we wzorcu sprawozdania mogą się nie wykonywać. Może prowadzić to do następujących problemów:
— pozostawienie nie usuniętych obiektów i zmiennych;
— pozostawienie niewłaściwego kontekstu dla tabel (np. niestosowne ograniczenie dziedziny);
— pozostawienie zablokowanych tabel lub nie zakończonych transakcji;
— pozostawienie tabeli maskowanej związanej z niewłaściwym zbiorem.
Każda rozpoczęta transakcja przy przetwarzaniu wzorca wydruku musi być zamknięta przed zakończeniem tworzenia sprawozdania. W przeciwnym przypadku zostanie zgłoszony błąd, a rozpoczęta transakcja zostanie wycofana i zakończona.
11.1 BEGIN
W celu uniknięcia powyższych problemów można zdefiniować stosowny prolog i epilog sprawozdania. Użycie konstrukcji:
{BEGIN: expression}
I.11. Prolog i epilog sprawozdania
powoduje, że expression — dowolne wyrażenie języka Formula, będzie wyliczone przed realizowaniem właściwego sprawozdania. Jego wyliczanie może
zostać przerwane przez operatora tylko poprzez zakończenie całego programu. Konstrukcję tę we wzorcu sprawozdania mogą poprzedzać jedynie zdania
{TITLE}, {VERSION} oraz {PRINTER}.
Konteksty odłożone w konstrukcji {BEGIN} są traktowane, jak odłożone
przed wywołaniem rep_exec — nie można będzie ich odtworzyć w trakcie
tworzenia sprawozdania. Dostępne będą dopiero w konstrukcji {END}. Dla
przykładu, wykonanie poniższego wzorca sprawozdania zakończy się błędem,
o braku kontekstu do odtworzenia:
{BEGIN:
CZYTEL.cntx_psh
}
{ CZYTEL.cntx_pop}
11.2 END
Do zdefiniowania epilogu sprawozdania służy konstrukcja:
{END: expression}
Wyrażenie expression będzie liczone zawsze po zakończeniu sprawozdania (w sposób normalny — również w wyniku konstrukcji {EXIT}, w wyniku przerwania przez operatora lub na skutek błędu powstałego podczas wykonania sprawozdania). Konstrukcję {END} we wzorcu sprawozdania mogą poprzedzać jedynie zdania {TITLE}, {VERSION}, {PRINTER} oraz
{BEGIN}.
Przed wykonanie konstrukcji {END}:
— zrywana jest transakcja, jeśli została ona rozpoczęta i nie zakończona
w sprawozdaniu (po wykonaniu konstrukcji {BEGIN}),
— odtwarzane są automatycznie wszystkie konteksty odłożone i nie pobrane w sprawozdaniu (po wykonaniu konstrukcji {BEGIN}). Zatem wywołania cntx_pop w konstrukcji {END} odtwarza konteksty odłożone
w konstrukcji {BEGIN} (lub sprzed wywołania rep_exec).
Dodatkowo, po zakończeniu konstrukcji {END} nie może być aktywna
transakcja. Jeśli będzie, to zostanie zgłoszony błąd, zaś transakcja będzie zerwana i zakończona.
71
72
Rozdział I. Konstrukcje języka
Przykłady Prześledźmy, jak w poniższym wzorcu wydruku rozwiązano problemy powstające w wyniku przerwania sprawozdania:
{TITLE: Dochody}
{VERSION: 8.10}
{PRINTER: ’oki’}
{BEGIN:
DOCHODY.cntx_psh;
’przechowywanie sumy częściowej:’;
suma:=0;
’wyliczane dochody w kolejnych miesiącach:’;
Dochody:=obj_new(12)
}
{END:
end;
DOCHODY.unlock;
DOCHODY.cntx_pop;
&suma;
obj_del(Dochody)
}
{COMMENT}
Właściwe sprawozdanie
{COMMENT-}
.......
W prologu wykonywane są następujące operacje:
— odłożenie kontekstu przetwarzanej tabeli;
— powołanie zmiennych i obiektów używanych w sprawozdaniu.
W epilogu wykonują się kolejno następujące operacje:
— zakończenie transakcji, która ewentualnie mogła zostać przerwana;
— zdjęcie ewentualnie pozostawionej blokady na tabeli (zakłada się, że pozostałe zbiory maskowane nie były blokowane w sprawozdaniu);
— odtworzenie kontekstu tabeli;
— usunięcie wszystkich zmiennych i obiektów powołanych w prologu.
I.12. Komentarze
12 Komentarze
12.1 COMMENT
Aby udokumentować wzorzec wydruku stosujemy w jego treści komentarze.
Treść komentarza jest przez program pomijana. Rozpoczyna się on zdaniem
{COMMENT}, a kończy zdaniem {COMMENT-}. Umieszczenie komentarza nie
ma wpływu na wynik działania programu, zwiększa jedynie czytelność wzorca
sprawozdania.
73
74
Rozdział I. Konstrukcje języka
Rozdział II
Kompilacja wydruków
1 Translatory
Translator MacroREPORT (dla systemu Linux) oraz report.exe (dla wersji dla
Windows) służy do przetwarzania zbioru ze wzorcem wydruku do zbioru czytelnego dla programu. W wyniku jego działania na podstawie zbioru tekstowego zawierającego tekst programu w języku Report powstaje zbiór z kodem, który może być wykonywany przez program klienta. Dzięki zastosowaniu kompilacji można bez tworzenia sprawozdania wyeliminować błędy składniowe języka Report. Błędy powstające w czasie wykonywania sprawozdania, takie jak
nie zakończona instrukcja {DIRECT} lub {ENTIRE} , czy błąd w wyrażeniu
języka Formula, nie zostaną oczywiście wykryte.
%MacroREPORT [[-Pnazwa | [-Snazwa] [-Tnazwa]]
%
plik [plik ...]
%
Po uruchomieniu kompilatora bez argumentów otrzymamy krótki opis
sposobu wywołania:
MacroREPORT - Translator języka REPORT - wersja 11.20
Copyright (C) Macrologic SA 1990
wywoĺanie programu:
report.exe [ -Ppath | [-Spath] [-Tpath] ] plik [plik ...]
-P
- path - ścieżka do pliku PTH systemu
-S
- path - katalog zbioru źródłowego
-T
- path - katalog zbioru wynikowego
plik - program w języku REPORT (domniemane rozszerzenie .rpm)
75
76
Rozdział II. Kompilacja wydruków
Jedynym obowiązkowym argumentem jest nazwa (lub maska) zbioru zawierającego wzorzec wydruku. Jeżeli w nazwie nie wystąpił znak . (kropka), to
do nazwy dodawana jest domyślnie końcówka .rpm. Wtedy w wyniku translacji (o ile nie było błędów języka Report) powstaje zbiór o takiej samej nazwie
ze zmienionym rozszerzeniem na .rpt. Można podać listę plików oddzielonych spacją. Jeśli nie podamy pozostałych opcji, to zbiory będą szukane i tworzone w bieżącym katalogu.
Dodanie opcji -P umożliwia wyszukiwanie podanych wzorców i włączanych plików oraz tworzenie skompilowanych sprawozdań zgodnie z deklaracją ścieżek. Bezpośrednio za opcją -P (bez odstępów) należy podać ścieżkę do
pliku .pth systemu, z którego pochodzą kompilowane sprawozdania. Podana
może być ścieżka bezwzględna (rozpoczynająca się od katalogu głównego) lub
względem bieżącego katalogu.
Użycie opcji -S i -T jest możliwe jeżeli nie użyliśmy opcji -P. Dzięki nim
zbiory będą szukane i tworzone w katalogach wskazanych przez użytkownika.
Bezpośrednio po opcjach -S i -T podajemy wtedy ścieżki (bezwzględne lub
względne) do katalogów odpowiednio źródłowego i docelowego.
Przykłady
MacroREPORT raport
kompiluje zbiór raport.rpm, w wyniku tworzy raport.rpt, oba w bieżącym katalogu.
MacroREPORT -Pdemo.pth raport1 raport2
kompiluje zbiory raport1.rpm i raport2.rpm tworząc raport1.rpt
i raport2.rpt, wszystkie względem deklaracji ścieżek demo.pth.
MacroREPORT -Srpm -Trpt *
kompiluje wszystkie zbiory .rpm z katalogu rpm i tworzy odpowiednie zbiory
.rpt w katalogu rpt (względem bieżącego katalogu).
Rozdział III
Tryby drukowania
Aby w pełni można było skorzystać z możliwości jakie daje język wydruków Report jak również uwzględnić możliwości i ograniczenia danej drukarki
lub systemu operacyjnego dostępne są dwa tryby drukowania.
tryb tekstowy
korzystający z tekstowych sterowników drukarek. W trybie tym nie są
dostępne konstrukcje graficzne, a polecenia związane z ustawieniami
czcionki są bardzo ściśle związane z charakterystyką techniczną drukarki. Ze względu na różnice w możliwościach różnych drukarek może się
zdarzyć, że czytelny wydruk otrzymany z jednej drukarki nie będzie wyglądał dobrze drukowany na innej. Dlatego wydruki w tym trybie są definiowane zazwyczaj dla konkretnej klasy drukarek.
tryb graficzny
dostępny w sterownikach graficznych i tekstowych; umożliwiający zmianę marginesów wydruku (w zdaniu {PRINTER} lub panelu) oraz wykorzystanie konstrukcji graficznych (dla parametru graphic różnego
od 0); w trybie tym to, co wyświetli się na ekranie odpowiada dokładnie
temu, co znajdzie się na wydruku.
Mimo większych możliwości trybu graficznego tryb tekstowy może być zalecany w przypadku drukarek igłowych lub atramentowych, dla których tryb
graficzny może być niedostępny albo zbyt wolny. Możemy też w celu uproszczenia i przyspieszenia wydruku zastosować dostępną w obu trybach opcję Tylko tekst (w sterowniku lub podglądzie), która powoduje zamianę znaków ramek na odpowiadające im znaki: ’+-=|’ oraz ustawia parametr graphic
na 0. W panelu wydruku mamy dodatkowo możliwość zmiany drukarki, właściwości drukarki oraz rozmiaru i orientacji papieru.
77
78
Rozdział III. Tryby drukowania
Rozdział IV
Ograniczenia systemu
Podczas tworzenia wzorca sprawozdania należy uwzględnić poniższe ograniczenia systemu:
— rozmiar tekstu formuły (ujętej pomiędzy {}) nie może przekraczać
10KB,
— suma długości wszystkich tekstów oraz treści formuł wpisanych we
wzorcu wydruku (czyli wszystko poza elementami składni języka Report), z uwzględnieniem sum z wszystkich włączanych plików konstrukcją INCLUDE, nie może przekraczać 512KB. Podobne ograniczenie dotyczy wykonywanego fragmentu sprawozdania poprzez REP,
— maksymalna liczba sumatorów — 50,
— maksymalna liczba zagnieżdżeń pętli {FOR} — 30,
— maksymalna liczba zagnieżdżeń pęli {WHILE} — 30,
— maksymalna liczba zagnieżdżeń wywołania konstrukcji {REP} — 10,
— maksymalna liczba zagnieżdżeń wywołania konstrukcji {SUBSTITUTE}
— 29,
— masymalna liczba zdefiniowanych podprogramów ({MACRO}) — 50.
79

Podobne dokumenty