Makrosubstituce

 

 

Jazyk FoxPro umožňuje vytvořit v průběhu programu (vypočítat, sejmout z klávesnice) znakový řetězec, obsahující výraz nebo jméno datového objektu nebo seznam, a výsledek učinit součástí příkazu, který se ve vhodném okamžiku provede. Jinými slovy, umožňuje programovat příkazy v době jejich provádění. Vytvářený řetězec je uložen v paměťové proměnné a nazývá se makro. Formule zápisu makra začíná znakem & a má tvar:

 

&<proměnná> [.<výrazC>]

 

Znak & uvedený před jménem proměnné způsobí, že obsah proměnné je interpretován jako součást příkazu FoxPro. Obsah proměnné použité pro makro substituci nesmí přesáhnout délku 1024 znaků.

 

C = 'P' + '2'                 && příklad vypočtení jména proměnné

&C = 4                          && definování proměnné P2 hodnotou 4

 

Použití makrosubstituce umožňuje vytvářet velice flexibilní a při tom jednoduché programové struktury. Nepovinný parametr .<výrazC> (předchází mu tečka) dovoluje připojit k příkazu další znaky z tohoto řetězce jako rozšíření makra. Obvykle se používá na připojování konstantních přípon jmen souborů.

 

program = "EVIDENCE"

? '&program..dbf'

EVIDENCE.dbf

 

Obsah proměnné nemůže rekurzivně volat sebe sama, např.

 

x = "&x"

? &x

 

způsobí chybové hlášení.

Při použití makro substituce v programových strukturách (například DO WHILE ... ENDDO), se vyhodnocuje hodnota proměnné pouze při prvním průchodu cyklem. Změna hodnoty proměnné uvnitř cyklu nezpůsobí změnu příslušného příkazu, kde je makro substituce použita.

FoxPro obsahuje vestavěný generátor výrazů, který je možné použit pro definování libovolného výrazu, sejmutého z klávesnice. Tento výraz lze pak použít jako makro. V praxi se však této možnosti využívá pouze při vývoji aplikací. Uživatel programu nemůže sestavovat výrazy. Mohl by způsobit syntaktickou nebo logickou chybu!

 

GETEXPR [<výrazC1>] TO <proměnná> [TYPE <výrazC2> [;<výrazC3>]] [DEFAULT <výrazC4>]

 

<výrazC1> určuje text zobrazený výsledný typ zadaného výrazu.

<výrazC2> určuje výsledný typ zadaného výrazu.

<výrazC3> určuje výsledný typ zadaného výrazu.

<výrazC4> určuje výsledný typ zadaného výrazu.

Příklad na vyhledání podle zadané podmínky v souboru STUDENTI. Předpokládá znalost struktury souboru.

 

USE studenti                                      && Otevření souboru

GETEXPR "Napište podmínku pro  vyhledání studenta :" TO podminka ;

TYPE "L"

LOCATE FOR & podminka                && Hledání podle podmínky ve tvaru makra

IF FOUND()                                       && Test úspěšnosti hledání

? 'Podmínce odpovídá student :' + student

ELSE

? 'Podmínce ' + podmínka + ' neodpovídá žádný student'

ENDIF

 

Test fungování makra obsahujícího relační operátory při výběru podle věku

 

SET DATE TO GERMAN                               && Nastavení německé interpretace data

datum_narozeni={18.01.33}                         && Zvolený operand testu

a=' '

DO WHILE .not. a$ '><='                         && Z klávesnice povolen pouze

&& vstup relačnímu operátoru

ACCEPT "Zapište požadavek  výběru: = (padesátiletí),;

< (mladší), > (starší) :" TO a

ENDDO

vyraz= 'YEAR(DATE()) - YEAR(datum_narozeni) '+ A + ' 50' && Vypočtení výrazu

 

* Když A = '<', pak vyraz = 'YEAR(DATE()) - YEAR(datum_narozeni) < 50'

 

IF &vyraz                                                       && Použití výrazu

?'ano'                                                  && V našem příkladě správnou odpovědí je NE

else

?'ne'

endif

 

Příklad použití makra jako parametru vnějšího programu (aktivuje se příkazem RUN nebo !), v našem případě zadání pro podpůrný systémový program (výpis souborů typu .prg z adresáře \FOX\DIPLOMKA)

 

a = '\fox\diplomka\*.prg'

run DIR &a

 

Makrosubstituce možno použít v těch příkazech, ve kterých chceme chceme uplatnit proměnné hodnoty, a které povolují pouze řetězec a ne výraz. Například příkaz USE, zapsaný

 

USE soubor TAG index

 

znamená: otevři soubor, který se jmenuje SOUBOR a zvol komponovaný index pojmenovaný INDEX. Příkazy

 

soubor='evidence'

index='prijmeni'

USE &soubor tag &index

 

znamenají: otevři soubor EVIDENCE a zvol komponovaný index pojmenovaný PRIJMENI. Použití makrosubstituce v tomto případě se již dnes pokládá za archaismus. Doporučuje se používat zápisu s kulatými závorkami:

 

soubor='evidence'

index='prijmeni'

USE (soubor) tag (index)

 

Cvičení

 

Použití makrosubstituce v příkazu DOS

 

CLEAR                                            && Výmaz obrazovky

SET TALK OFF                                     && Potlačení zobrazování mezivýsledků

@1,8 SAY ;

'PŘÍKLAD MAKROSUBSTITUCE U SYNTETIZÁTORU'    && Název úlohy

@0,3 TO 2,52 DOUBLE                              && Rámeček

s=SYS(2001,"COLOR")                              && Úschova palety barev

SET COLOR TO W/N                                 && Barvy pro řídící pole

@4,3,11,52 BOX 'ÇÇÇÇÇÇÇÇÇ'                       && Vymezení řídícího pole

SET DATE TO GERMAN

PUBLIC pred,po,aa

p="Dobrý  den.   Dnes je "

D=DTOC(DATE())

dny='neděle  ,pondělí ,úterý   ,středa  ,čtvtek  ,pátek   ,sobota  '

den=TRIM(SUBSTR(dny,(DOW(DATE())-1)*9+1,8))+', '

s=p+den+textdata()+' 1 3'

@6,8 SAY SPACE(40)

@6,8 SAY p+den+D

! syn18 &s

 @8,11 SAY "Napište větu pro čtení, bez číslic:"

 

DO WHILE .T.

v=SPACE(40)

@10,8 SAY v

@10,8 GET v

READ

IF EMPTY(v)

EXIT

ENDIF (empty(v))

! syn18 &v                               && Zde je uplatněna makrosubstituce

ENDDO

 

FUNCTION textdata

d20="dvacátého "

d30="třicátého "

axx='náctého'

poradip= "prv  ,druh ,třet ,čtvrt,pát  ,"+;

"šest ,sedm ,osm  ,devát,desát "

poradid= "jede  ,dva   ,tři   ,čtr   ,"+;

"pat   ,šest  ,sedm  ,osum  ,devate"

mes="ledna    ,února    ,března   ,dubna    ,"+;

"května   ,června   ,července ,srpna    ,"+;

"září     ,října    ,listopadu,prosince  "

cd=DAY(DATE())

cm=MONTH(DATE())

DO CASE

CASE cd<=10

zden=TRIM(SUBSTR(poradip,(cd-1)*6+1,5) ;

IIF(cd=1 OR cd=3,'ího','ého')

CASE cd>10 AND cd<20

zden=TRIM(SUBSTR(poradid,(cd-11)*7+1,6))+axx

CASE cd=20

zden=d20

CASE cd >20 AND cd <30

zden=d20+TRIM(SUBSTR(poradip,(cd-21)*6+1,5))+ ;

IIF(cd=21 OR cd=23,'ího','ého')

CASE cd=30

zden = d30

CASE cd>30

zden = d30+TRIM(SUBSTR(poradip,(cd-31)*6+1,5)) ;

IIF(cd=31 OR cd=33,'ího','ého')

ENDCASE

RETURN zden+' '+TRIM(SUBSTR(mes,(cm-1)*10+1,9))