SAS Macro Language w pigułce



Podobne dokumenty
Uwagi dotyczące notacji kodu! Moduły. Struktura modułu. Procedury. Opcje modułu (niektóre)

Skrypty powłoki Skrypty Najcz ciej u ywane polecenia w skryptach:

1 Podstawy c++ w pigułce.

1 Podstawy c++ w pigułce.

ANALIZA DANYCH W STATA 8.0 CZĘŚĆ II

Umieszczanie kodu. kod skryptu

Obiektowy PHP. Czym jest obiekt? Definicja klasy. Składowe klasy pola i metody

ZESTAW 1 SAS 4GL. Język stworzony na potrzeby przetwarzania dużych zbiorów danych. Składają się nań:

WYDZIAŁ ELEKTROTECHNIKI, AUTOMATYKI I INFORMATYKI INSTYTUT AUTOMATYKI I INFORMATYKI KIERUNEK AUTOMATYKA I ROBOTYKA STUDIA STACJONARNE I STOPNIA

Programowanie w Turbo Pascal

Funkcje są prawdopodobnie najważniejszą częścią każdego poważnego programu (w każdym języku programowania).

Wstęp do informatyki. stęp do informatyki Polecenia (cz.2)

Podstawy programowania skrót z wykładów:

Laboratorium Wstawianie skryptu na stroną: 2. Komentarze: 3. Deklaracja zmiennych

Administracja sieciowymi systemami operacyjnymi III Klasa - Linux

Python wprowadzenie. Warszawa, 24 marca PROGRAMOWANIE I SZKOLENIA

Po uruchomieniu programu nasza litera zostanie wyświetlona na ekranie

SAS Podstawowe informacje przed ćwiczeniem 2

Komentarze w PHP (niewykonywane fragmenty tekstowe, będące informacją dla programisty)

LibreOffice Calc VBA

Przykład 1 -->s="hello World!" s = Hello World! -->disp(s) Hello World!

SAS Podstawowe informacje przed ćwiczeniem 1

Skrypty powłoki w systemie Linux

Definicje wyższego poziomu

PL/SQL. Funkcje wbudowane

System operacyjny Linux

Zasady programowania Dokumentacja

Wyrażenie include(sciezka_do_pliku) pozwala na załadowanie (wnętrza) pliku do skryptu php. Plik ten może zawierać wszystko, co może się znaleźć w

Pascal - wprowadzenie

Technologie Informacyjne - Linux 3

Programowanie w języku Python. Grażyna Koba

Składowane procedury i funkcje

Bash - wprowadzenie. Bash - wprowadzenie 1/39

Materiały do laboratorium MS ACCESS BASIC

Funkcje wbudowane PHP

Programowanie Proceduralne

Temat zajęć: Tworzenie skryptów powłoki systemu operacyjnego.

PL/SQL. Część 1 Bloki PL/SQL. Piotr Medoń

Smarty PHP. Leksykon kieszonkowy

Podstawy Programowania C++

ZMIENNE. Podstawy PHP

Bloki anonimowe w PL/SQL

Programowanie obiektowe

Ok. Rozbijmy to na czynniki pierwsze, pomijając fragmenty, które już znamy:

Skrypty i funkcje Zapisywane są w m-plikach Wywoływane są przez nazwę m-pliku, w którym są zapisane (bez rozszerzenia) M-pliki mogą zawierać

Metody numeryczne Laboratorium 2

Tablice (jedno i wielowymiarowe), łańcuchy znaków

Podstawy języka C++ Maciej Trzebiński. Instytut Fizyki Jądrowej Polskiej Akademii Nauk. Praktyki studenckie na LHC IVedycja,2016r.

JAVAScript w dokumentach HTML - przypomnienie

Elementy języka C. ACprogramislikeafastdanceonanewlywaxeddancefloorbypeople carrying razors.

Kiedy i czy konieczne?

Oczywiście plik musi mieć rozszerzenie *.php

Pracownia Komputerowa wykład III

Języki skryptowe w programie Plans

Programowanie strukturalne. Opis ogólny programu w Turbo Pascalu

Podstawowe elementy proceduralne w C++ Program i wyjście. Zmienne i arytmetyka. Wskaźniki i tablice. Testy i pętle. Funkcje.

Wprowadzenie do Scilab: podstawy języka Scilab

Programowanie w języku C++ Grażyna Koba

Języki i metodyka programowania. Typy, operatory, wyrażenia. Wejście i wyjście.

1 Przygotował: mgr inż. Maciej Lasota

Powłoka bash. Kurs systemu Unix 1

PODSTAWY BAZ DANYCH 13. PL/SQL

Utworzenie pliku. Dowiesz się:

PAKIETY STATYSTYCZNE

Podstawy języka C++ Maciej Trzebiński. Praktyki studenckie na LHC IFJ PAN. Instytut Fizyki Jądrowej Polskiej Akademii Nauk. M. Trzebiński C++ 1/16

Serwer WWW Apache. Plik konfiguracyjny httpd.conf Definiujemy m.in.: Aktualne wersje 2.4.6, , zakończony projekt

Laboratorium 3: Preprocesor i funkcje ze zmienną liczbą argumentów. mgr inż. Arkadiusz Chrobot

1 Programowanie w matlabie - skrypty i funkcje

Formuły formułom funkcji adresowania odwoływania nazwy Funkcja SUMA argumentami SUMA

Warsztaty dla nauczycieli

AHDL - Język opisu projektu. Podstawowe struktury języka. Komentarz rozpoczyna znak i kończy znak %. SUBDESIGN

INSTRUKCJA INSTALACJI APLIKACJI PROF- EAN 2

Tytuł: PRZETWARZANIE DANYCH W SAS Autor: Wioletta Grzenda, Aneta Ptak-Chmielewska, Karol Przanowski, Urszula Zwierz. Wstęp

Lekcja 1. Składnia języka zmienne i podstawowe instrukcje PHP. Do wyświetlania tekstu służy instrukcja echo echo Hello world ;

SAS 4GL Podsumowanie.

Powtórka algorytmów. Wprowadzenie do języka Java.

Widoczność zmiennych Czy wartości każdej zmiennej można zmieniać w dowolnym miejscu kodu? Czy można zadeklarować dwie zmienne o takich samych nazwach?

JAVAScript w dokumentach HTML (1) JavaScript jest to interpretowany, zorientowany obiektowo, skryptowy język programowania.

Stałe, znaki, łańcuchy znaków, wejście i wyjście sformatowane

Instrukcje cykliczne (pętle) WHILE...END WHILE

4. Funkcje. Przykłady

Podstawy programowania. Wykład: 9. Łańcuchy znaków. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD

Cw.12 JAVAScript w dokumentach HTML

Informatyzacja Przedsiębiorstw

Maxima i Visual Basic w Excelu

KOTLIN. Język programowania dla Androida

Zmienne powłoki. Wywołanie wartości następuje poprzez umieszczenie przed nazwą zmiennej znaku dolara ($ZMIENNA), np. ZMIENNA=wartosc.

Wprowadzenie do programowania w VBA

Mikrokontroler ATmega32. Język symboliczny

Ćwiczenie 7 z Podstaw programowania. Język C++, programy pisane w nieobiektowym stylu programowania. Zofia Kruczkiewicz

Podstawy Programowania Podstawowa składnia języka C++

ForPascal Interpreter języka Pascal

Zajęcia nr 2 Programowanie strukturalne. dr inż. Łukasz Graczykowski mgr inż. Leszek Kosarzewski Wydział Fizyki Politechniki Warszawskiej

Cwiczenie nr 1 Pierwszy program w języku C na mikrokontroler AVR

Podstawy Pythona. Krzysztof Gdawiec. Instytut Informatyki Uniwersytet Śląski

Programowanie. Projektowanie funkcje programu tworzenie algorytmu i struktur danych. Programowanie implementacja algorytmu kompilacja programu

Trochę o plikach wsadowych (Windows)

Algorytmika i Programowanie VBA 1 - podstawy

JAVASCRIPT PODSTAWY. opracowanie: by Arkadiusz Gawełek, Łódź

7. Pętle for. Przykłady

Transkrypt:

SAS Macro Language w pigułce Wstęp DEFINICJA MAKR Język makr to język, który rozszerza możliwości standardowego 4GL. Dzięki umiejętności pisania makr, użytkownik może zautomatyzowad wiele procesów, uruchamiad programy warunkowo (np. kod generujący raport tygodniowy co piątek, a raport miesięczny w ostatni dzieo miesiąca), czy też dynamicznie tworzyd kod SAS-owy. CELE UŻYTKOWANIA Automatyzacja procesu pisania kodu SAS-owego Dynamiczne generowanie kodu Warunkowe uruchamianie kodu Parametryzacja kodu CHARAKTERYSTYKA MAKROPROGRAMÓW Makra rozpoczynają się znakiem procenta (%), po którym występuje nazwa wyrażenia Kooczą się średnikiem (;) Wykonywane są przez procesor makr, a nie zwykły procesor 4GL Makrozmienne rozpoczynają się znakiem ampersand (&), po którym występuje ich nazwa Proces kompilacji Zanim skaner słów przekaże kod do procesora 4GL sprawdzi, czy nie zawiera on makrowyrażeo. Jeżeli takie napotka, to przekaże je do procesora makr, który je rozwinie i zwróci z powrotem do skanera. Dopiero wtedy uruchomiony zostanie procesor 4GL. W praktyce oznacza to, że makra wykonują się na samym początku procesu kompilacji. %LET temp = 0; %MACRO test; DATA test; DO i = 1 to 5; %LET temp = %eval(&temp + 1); temp = &temp; OUTPUT; END; DROP i; RUN; %MEND; %test; Po przetworzeniu makra zwróci do skanera kod: Strona 1 z 14

DATA test; DO i = 1 to 5; temp = 1; OUTPUT; END; DROP i; RUN; Makrozmienne Przed utworzeniem makrozmiennej należy zaznaczyd, że kompilator traktuje wszystkie wartości jako tekst i nie można wymusid, aby było inaczej. Jednak nie oznacza to, że na makrozmiennych nie można wykonywad operacji arytmetycznych odpowiada za to funkcja eval opisana w rozdziale Funkcje makro. DEFINIOWANIE Makrozmienne można definiowad na kilka różnych sposobów. Jednym z nich jest instrukcja %LET. Można z niej korzystad w dowolnym miejscu programu. Aby utworzyd makrozmienną test o wartości Hello, World! należy uruchomid poniższy kod: %LET test = Hello, World!; Znaki cudzysłowu nie są potrzebne wszystkie znaki (za wyjątkiem początkowych i kooczących spacji) występujące do średnika są traktowane jako wartośd zmiennej. Utworzona w taki sposób zmienna w dowolnym miejscu poza ciałem makra jest globalna, a tym samym dostępna w dowolnym miejscu programu. Aby utworzyd makrozmienną w DATA STEP należy skorzystad z funkcji symput lub symputx opisanych w rozdziale Dostęp do makrozmiennych w DATA STEP. USUWANIE Aby usunąd makrozmienną należy skorzystad z funkcji %SYMDEL. %SYMDEL makrozmienna <makrozmienna2 makrozmienna3>; ODWOŁYWANIE Do makrozmiennych odwołuje się za pomocą znaku ampersand (&) i nazwy zmiennej. istnieje globalna makrozmienna &temp i chcemy wyświetlid ją w logu. Aby to zrobid należy uruchomid poniższy kod: %PUT &temp; Strona 2 z 14

Aby odwoład się do makrozmiennej w DATA STEP należy skorzystad z funkcji symget opisanej w rozdziale Dostęp do makrozmiennych w DATA STEP. CHARAKTERYSTYKA Dzielą się na globalne lub lokalne o Makrozmienne lokalne to takie, które są dostępne wyłącznie w makrze, w którym zostały one zdefiniowane o Makrozmienne globalne są dostępne w dowolnym miejscu programu, definiowane są poza ciałem makra, w ciele makra za pomocą wyrażenia %GLOBAL nazwa_zmiennej lub za pomocą funkcji symputx z opcją G. Mają minimalną długośd 0 znaków (wtedy przyjmują wartośd null) Mają maksymalną długośd 65 534 znaków (64K) Przechowują wartości numeryczne jako tekst Domyślne makrozmienne &SYSDATE* Data w krótkim formacie DDMONYY, np. 26APR11 &SYSDATE9* Data w długim formacie DDMONYYYY, np. 26APR2011 &SYSDAY* Dzieo tygodnia w języku angielskim, np. Tuesday &SYSTIME* Godzina systemowa, np. 16:01 * - data/czas rozpoczęcia sesji SAS jeżeli SAS został uruchomiony we wtorek, a z makra odwołującego się do zmiennych zawierających datę lub czas skorzystamy w środę, to zmienne będą zwracały dane wtorkowe. &SYSSCP Skrócona nazwa systemu operacyjnego, np. WIN &SYSLAST Ostatnio utworzony zbiór &SYSPARM Wartośd argumentu -sysparm, który został przekazany przy uruchomieniu sesji SAS. Przykład (uruchomienia SAS z poziomu Windows): Strona 3 z 14

sas -sysparm work.test; Kod w SAS: %PUT &SYSPARM; work.test _AUTOMATIC_** Lista wszystkich automatycznych makrozmiennych _USER_** Lista makrozmiennych zdefiniowanych przez użytkownika _ALL_** Lista wszystkich makrozmiennych ** - z tych wyrażeo należy korzystad z funkcją %PUT, np. %PUT _USER_ wyświetli w logu wszystkie makrozmienne zdefiniowane przez użytkownika. Makra DEFINIOWANIE MAKRA Aby móc korzystad z wyrażeo makr, najpierw należy utworzyd ciało makra. Ogólna definicja makra wygląda następująco: %MACRO nazwa; /* kod makra */ %MEND <nazwa>; MAKRA A MAKROZMIENNE Różnica pomiędzy makrami a makrozmiennymi polega na tym, że makra można rozumied jako małe programy, podczas gdy makrozmienne to po prostu wyrażenia, które mają przypisaną jakąś wartośd tekstową i poza tym nie pełnią żadnej innej roli. CO MAKRO MOŻE ZAWIERAĆ? Dowolny tekst Wyrażenia SAS-owe lub STEP-y Zmienne, funkcje, wyrażenia lub odwołania makro Strona 4 z 14

MAKRA PARAMETRYZOWANE Makra mają możliwośd posiadania parametrów. Definiuje się je w nawiasach funkcyjnych za nazwą makra. Parametry są traktowane jako makrozmienne lokalne. Odwołujemy się do nich w sposób standardowy za pomocą znaku ampersand (&) i ich nazwy. W przypadku, gdy chcemy, aby nasze makro posiadało kilka parametrów, to oddzielamy je przecinkami: %MACRO parametryzowane(p1, p2); %PUT &p1 * &p2; %MEND; %parametryzowane(a, b); a * b DATA test; INPUT imie $ wiek $; CARDS; Kamil 22 Jan 33 Ania 44 Magda 22 ; RUN; %MACRO znajdz(wiek); PROC PRINT DATA=work.test(WHERE=(wiek="&wiek")); RUN; %MEND; %znajdz(22); Przykład utworzy zbiór danych test z 4 wierszami. Makro %znajdz będzie wymagało parametru wiek, który później zostanie przekazany do procedury PRINT za pomocą makrozmiennej &wiek. Wynik działania programu (procedura PRINT): Obs imie wiek 1 Kamil 22 4 Magda 22 Instrukcje warunkowe Język makr ma możliwośd warunkowego uruchamiania kodu. Są to standardowe instrukcje typu if/else, za wyjątkiem tego, że przed słowem kluczowym zawierają znak procenta. Instrukcja %else jest opcjonalna. Strona 5 z 14

W przypadku, gdy chcemy aby po if/else występował ciąg instrukcji (a nie pojedyncza instrukcja), to deklarujemy go pomiędzy %DO a %END. %MACRO czyweekend; %IF &sysday = Friday OR &sysday = Saturday OR &sysday = Sunday %THEN %DO; %INCLUDE c:\raportweekendowy.sas ; %PUT Uruchomiono raport weekendowy; %END; %ELSE %PUT Normalny dzien tygodnia; %MEND; %czyweekend; W piątek, sobotę oraz niedzielę makro uruchomi program z pliku C:\raportWeekendowy.sas i zwróci w logu: Uruchomiono raport weekendowy W pozostałe dni tygodnia zwróci: Normalny dzien tygodnia Pętle %DO %WHILE %DO %WHILE(wyrazenie); /* kod */ %END; Pętla WHILE przed wykonaniem kodu w niej zawartego sprawdza wyrażenie. Kod zawarty w tej pętli wykonuje się do momentu, gdy wyrażenie zwróci wartośd false. %MACRO wyrazy(tekst, separator=*); %LET i = 1; %LET wyraz = %SCAN(&tekst, &i, &separator); %IF &wyraz = %THEN %PUT Tekst jest pusty.; %ELSE %DO %WHILE(&wyraz ne ); %PUT wyraz &i to: &wyraz; %LET i = %EVAL(&i+1); %LET wyraz = %SCAN(&tekst, &i, &separator); %end; %MEND; %wyrazy(to*jest*przykladowy*tekst); Strona 6 z 14

Zwróci Wyraz 1 to: To Wyraz 2 to: jest Wyraz 3 to: przykladowy Wyraz 4 to: tekst %DO %UNTIL %DO %UNTIL(wyrazenie); /* kod */ %END; Pętla UNTIL najpierw wykonuje kod w niej zawarty, a później sprawdza wyrażenie. Oznacza to, że bez względu na to, czy wyrażenie jest prawdziwe, pętla wykona kod co najmniej raz. Dodatkową różnicą pomiędzy WHILE a UNTIL jest to, że pierwsza z nich kooczy się w przypadku, gdy wyrażenie zwraca wartośd false, a druga, gdy zwraca true. Dostęp do makrozmiennych w DATA STEP SYMPUT CALL SYMPUT( makrozmienna, wartość ); Ustawia wartośd makrozmienna na wartośd. Dodatkowo, w funkcji SYMPUT można zagnieżdżad inne funkcje, np: CALL SYMPUT( temp, put(100, binary8.)); SYMPUTX CALL SYMPUTX( makrozmienna, wartość <, L G>); Ustawia wartośd makrozmienna na wartośd i dodatkowo usuwa spacje na początku i na koocu łaocucha znaków. Opcjonalny trzeci argument przyjmuje wartości L lub G i tworzy odpowiednio lokalną lub globalną makrozmienną. SYMGET x = SYMGET( makrozmienna ); Pobiera wartośd makrozmienna i przypisuje ją do zmiennej x. Strona 7 z 14

Funkcje makro LENGTH %LENGTH(lancuch_znakow); Zwraca długośd lancuch_znakow. Przykład %PUT %LENGTH(test); 4 EVAL %EVAL(lancuch_znakow); W języku makr wszystkie zmienne traktowane są jako łaocuch znaków, dlatego też nie działają operacje arytmetyczne. Aby wymusid na kompilatorze traktowanie znaków specjalnych (np. +, czy *) standardowo należy skorzystad z funkcji %EVAL. %LET a = 2+2; %LET b = 2; %PUT %EVAL(&a); %PUT %EVAL((&a-1)*&b); 4 6 SCAN %SCAN(lancuch_znakow, n <, separator>); Zwraca n-wyraz z lancuch_znakow, oddzielony przez separatory (domyślnie: spacja ( ) &! $ * ; - /,. %) %LET temp = *a*b*c*wyraz1*wyraz2; Strona 8 z 14

%PUT %SCAN(&temp, 4); wyraz1 SUBSTR %SUBSTR(lancuch_znakow, poczatek <, n>); Zwraca n kolejnych znaków od poczatek z lancuch_znakow lub wszystkie znaki od poczatek do kooca łaocucha, jeżeli n nie zostało podane. %LET dzisiaj = &sysdate9; %LET temp = qwerty; %PUT dzisiaj; %PUT %SUBSTR(&dzisiaj, 3); %PUT %SUBSTR(&dzisiaj, 3, 5); %PUT %SUBSTR(&temp, 5, 1); Zwróci 26APR2011 APR2011 APR t SYSFUNC %SYSFUNC(funkcja_sasowa <, format>) Uruchamia podaną funkcję SAS-ową i opcjonalnie nakłada na nią format. %PUT %SYSFUNC(today(), date11.); 26-APR-2011 UPCASE %UPCASE(lancuch_znakow); Strona 9 z 14

Przekształca lancuch_znakow zamienia małe litery na wielkie %LET temp = abc; %PUT %UPCASE(&temp); ABC Opcje makr MCOMPILENOTE OPTIONS MCOMPILENOTE=ALL NONE; Opcja MCOMPILENOTE odpowiada za wyświetlanie noty po skompilowaniu makra. Domyślnie opcja ma ustawioną wartośd na NONE. OPTIONS MCOMPILENOTE=ALL; %MACRO test; %PUT Hello, World!; %MEND test; NOTE: The macro TEST completed compilation without errors. 3 instructions 36 bytes. MLOGIC OPTIONS MLOGIC NOMLOGIC; Opcja MLOGIC odpowiada za wyświetlanie informacji w logu na temat uruchamiania makr. Domyślnie jest ustawiona opcja NOMLOGIC. OPTIONS MLOGIC; %MACRO test; %PUT Hello, World!; %MEND test; %test; Strona 10 z 14

MLOGIC(TEST): Początek wykonywania. MLOGIC(TEST): %PUT Hello, World! Hello, World! MLOGIC(TEST): Koniec wykonywania. MPRINT OPTIONS MPRINT NOMPRINT; Wyświetlanie kodu wysyłanego do kompilatora SAS (nie makrokompilatora) po wykonaniu makra. Domyślnie opcja ma ustawioną wartośd NOMPRINT. OPTIONS MPRINT; %MACRO test; DATA test; DO i = 1 TO 3; PUT i; END; RUN; %MEND test; %test; MPRINT(TEST): DATA test; MPRINT(TEST): DO i = 1 TO 3; MPRINT(TEST): PUT i; MPRINT(TEST): END; MPRINT(TEST): RUN; 1 2 3 SYMBOLGEN OPTIONS SYMBOLGEN NOSYMBOLGEN; Opcja SYMBOLGEN odpowiada za rozwijanie wartości makrozmiennych, gdy program się do nich odwołuje. Domyślnie ustawiona jest opcja NOSYMBOLGEN. OPTIONS SYMBOLGEN; %PUT &sysdate; Strona 11 z 14

SYMBOLGEN: Makrozmienną SYSDATE rozwinięto do postaci 27APR11 27APR11 Sztuczki i kruczki WSKAZYWANIE ZAKOŃCZENIA REFERENCJI DO MAKROZMIENNEJ Gdy w ciągu znaków odwołujemy się do makrozmiennej i nie ma po niej spacji, to kompilator makr nie wie, gdzie kooczy się jej referencja. Możemy wskazad zakooczenie ręcznie, za pomocą znaku kropki. %LET temp = 123; %PUT ZmiennaTempMaWartosc=&temp.ATutajJestDalszyCiag; ZmiennaTempMaWartosc=123ATutajJestDalszyCiag POŚREDNIE REFERENCJE DO MAKROZMIENNYCH Gdy chcemy odwoład się do makrozmiennej za pomocą kombinacji makrozmiennych, to korzystamy z podwójnego znaku ampersand (&). W zrozumieniu przydatna jest opcja symbolgen. %LET test1 = Hello, World!; %LET numer = 1; %PUT &&test&numer; SYMBOLGEN: && rozwinięto do &. SYMBOLGEN: Makrozmienną NUMER rozwinięto do postaci 1 SYMBOLGEN: Makrozmienną TEST1 rozwinięto do postaci Hello, World! Hello, World! Strona 12 z 14

Spis treści Wstęp... 1 Definicja makr... 1 Cele użytkowania... 1 Charakterystyka makroprogramów... 1 Proces kompilacji... 1 Makrozmienne... 2 Definiowanie... 2 Usuwanie... 2 Odwoływanie... 2 Charakterystyka... 3 Domyślne makrozmienne... 3 &sysdate*... 3 &sysdate9*... 3 &sysday*... 3 &systime*... 3 &sysscp... 3 &syslast... 3 &sysparm... 3 _automatic_**... 4 _user_**... 4 _all_**... 4 Makra... 4 Definiowanie makra... 4 Makra a makrozmienne... 4 Co makro może zawierad?... 4 Makra parametryzowane... 5 Instrukcje warunkowe... 5 Pętle... 6 %DO %WHILE... 6 %DO %UNTIL... 7 Dostęp do makrozmiennych w DATA STEP... 7 symput... 7 symputx... 7 Strona 13 z 14

symget... 7 Funkcje makro... 8 length... 8 eval... 8 scan... 8 substr... 9 sysfunc... 9 upcase... 9 Opcje makr... 10 mcompilenote... 10 mlogic... 10 mprint... 11 symbolgen... 11 Sztuczki i kruczki... 12 Wskazywanie zakooczenia referencji do makrozmiennej... 12 Pośrednie referencje do makrozmiennych... 12 Strona 14 z 14