VaxNt/ProDB.PGuide.Příklady
Začneme několika příklady z praxe. Jazyk skriptů se vyvinul z původně pouze pomocného nástroje na plnohodnotný
programovací jazyk. Primárně je ovšem určen k řešení jednoduchých záležitostí, jak bude vidět z následujících
příkladů.
Naplánování mobilního přenosu. V jednoduchém scénáři chceme sejmout formulář (v naší terminologii wizard),
zkosntruovat pár pomocných proměnných a výsledek uložit do odpovídající databázové tabulky. Reálný skript
v ČRa je následující:
    clear
    set                 Datum,$(Today),WizCaption,Nový mobilní přenos
    ?wizard             mobilniprenosy/form.wiz
    randomize+random
    set                 MobilId,$(DateTime)$(Random),KdoZapsal,$(User),KdyZapsal,$(DateTime),Stav,Nový,Color,Blue
    insert              MobPrenosy
    dump                mobilniprenosy_new
    exit
Nyní si pěkně řádek po řádku probereme použité obraty:
	
	Příkaz clear pro jistotu vyčistí úplně kontext volání. Kontext je jedna sada rovnic (multirovnice, TStringList).
	V tomto případě je příkaz nadbytečný, protože skript volaný na základní úrovní začíná s vyprázdněným kontextem.
	Pokud by ale tento skript byl náhodou volán jiným skriptem jako podřízený (podprogram), je použití _clear na místě,
	protože se jím vynulují ev. proměnné přicházející z nadřízeného skriptu. Většina skriptů začíná jedním z příkazů
	clear nebo _use. Příkaz _use slouží k propagování kontextu akce do proměnných skriptu. Skripty jsou totiž
	volány obvykle nad nějakou zobrazenou tabulkou / gridem. Přirozeným kontextem akce je pak obsah aktuálního
	řádku gridu - to je sada hodnot, která se pomocí _use dostane do skriptu.
	
	Příkaz set bere jako argumenty seznam dvojic, první je vždy jméno proměnné a druhá je hodnota, kterou jí
	chceme dát. Jak vidno, součástí hodnoty mohou být konstanty, ale i systémové proměnné (Today,Tomorrow,...)
	a také i hodnoty jiných proměnných. K detailnímu popisu vyhodnocování proměnných se dostaneme v dalším.
	Vedle normálních proměnných existují i některé "smluvené", jejichž význam je důležitý spíše pro vzhled
	nebo chod akce než pro skutečné zpracování hodnot. Zde je to WizCaption, což je jméno titulku nad snímaným
	wizardem. To je typicky prázdné, ale je možno ho explicitně nastavit, jako se děje v našem případě.
	Protože jak volaný wizard převezme kompletní sadu proměnných, nastavením proměnné Datum rovnou ve
	wizardu přednastavíme hodnotu na nejběžnější případ, tedy dnes.
	
	Dalším příkazem je volání wizarda. Zde má jediný parametr a sice jméno souboru, kde je definován wizard/formulář.
	Dalšími nepovinnými parametry by ještě mohlo být jméno proměnné, kde se má začít skenovat a ev. i mod zobrazení
	(přes celý desktop nebo menší, ...). Pokud je skenování hodnot operátorem ukončeno příkazem Storno, pak příkaz
	?wizard rovnou ukončí interpretaci celého skriptu.
	
	Poznámka: Jak uvidíme v dalším, wizardy mohou volat vedle interních funkcí na kontrolu dat i skripty a je tedy
	možné a často se to používá, že skript rozjede volaná wizarda a v něm zprostředkovaně dochází k volání jiného
	skriptu atd. Níže to je ilustrováno na příchodu pacienta na recepci PET centra.
	
Pomocí randomize+random se inicializuje
	generátor náhodných čísel a hnedka se jedno takové číslo vygeneruje. Dostane se do globální a po dobu běhu
	interpreteru stále existující proměnné Random. Náhodná čísla se generují v intervalu 0-4095 a používají se
	na vytváření unikátních databázových klíčů obvykle v podobě kompletního DateTime a nějakého suffixu.
	
	Následuje zase přiřazovací příkaz set, kterým
	se zrovna konstruuje databázový klíč MobilId, nastavují evidenční proměnné KdoZapsal a KdyZapsal a pak ještě pár dalších.
	
	Posléze se pomocí příkazu insert zapíše do databázové tabulky MobPrenosy. Jelikož mobilní přenosy plánuje
	právě jeden operátor, je vygenerovaný databázový klíč unikátní (i kdyby pracovalo více lidí, musli by
	v jedné vteříně vkládat mnoho záznamů, aby pravděpodobnost kolize byla nezanedbatelná). Zásadně důležité je ale
	to, že neuvádíme explicitně hodnoty proměnných, které chceme uložit. Ty jsou možná deklarovány ve wizardu,
	pokud ano, jednoduše jsme hodnoty i s jejich jmény získali voláním wizarda. Příkaz insert je implementován
	tak, že si sám již zjistí strukturu tabulky a sestaví vhodný "insert into MobPrenosy values ...." automaticky.
	Probere tedy VŠECHNY proměnné kontextu skriptu, vybere relevantní a nabídne je tabulce ke skutečné operaci
	insert. Pokud bychom chtěli ošetřit ev. výjimku jinak než standardním chybovým dialogem, pak bychom použili
	příkaz try.insert.
	
	Příkaz dump slouží k logování událostí. V adresáři data/log se logují události ve formě textových souborů se
	jménem odvozeným od DateTime a parametru dump. Tyto logové soubory "požírá" noční běh daemonů na straně
	serveru. Typicky jsou logy ukládány na jiném diskové svazku než databáze a jsou produkovány tak, že v případě
	kolapsu systému je možno snadno sestavit ze souborů stejné třídy "dump" importní soubory na korekci
	databáze. Typicky se ale logy používají pro vzdálené monitorování systému a řešení chyb operátorů.
	
	Příkaz exit ukončuje běh skriptu. Vedle toho je možno používat i příkaz return, kterým se ukončují podřízené
	skripty. Ukončí-li se podřízený skript returnem, vezmou se NEPRÁZDNÉ hodnoty jeho kontextu a propagují se
	do stejnojmenných proměnných volajícího skriptu. Prázdné hodnoty se ignorují. Později se k tomu dostaneme
	ještě detailněji. Teď sdělíme jenom tolik, že podřízený skript  získává při startu automaticky kompletní kopii
	kontextu volajícího skriptu. Teprve při návratu se může rohodnout, jaké proměnné vlastně vrátí "o patro výše".
	Dobrým zvykem je pro jistotu před návratem přes return vyprázdnit hodnoty všelijakých pomocných proměnných tak,
	aby se zbytečně nevracely volajícímu skriptu...
Wizard z předchozího příkladu. Následuje wizard, který byl volán v předešlém příkladě. Jedná se o statickou
definici formuláře a vlastností každého jeho řádku.
Datum
    Caption = Datum 
    Comment = Datum přenosu
    Type = Calendar
    Definition
        Default = today
        Format = YYYYMMDD
    Check = !void  
Nazev
    Caption = Název
    Check = max(24)
Zvuk
    Caption = Zvuk
    Check = upper & list(||MONO|STEREO|)
KBod
    Caption = K-bod
    Check = max(40)
Uzivatel
    Caption = Uživatel
    Comment = Uživatel, pro kterého se přenos uskutečňuje
    Type = Lookup
    Definition
        Database = DefaultVaxNtDb
        Key = Uzivatel
        Sql = select Uzivatel from MobUzivatele order by Uzivatel
        Fields = Uzivatel
Kategorie
    Caption = Kategorie
    Comment = Kategorie
    Type = Lookup
    Definition
        Database = DefaultVaxNtDb
        Key = Kategorie
        Sql = select Kategorie,Popis,PoradiVMenu from Mobkategorie order by PoradiVMenu
        Fields = Kategorie;Popis
Pasmo
    Caption = Pásmo
    Comment = Pásmo podle číselníku 1-5
    Type = Lookup
    Definition
        Database = DefaultVaxNtDb
        Key = Pasmo
        Sql = select Pasmo,Popis,PoradiVMenu from MobPasma order by PoradiVMenu
        Fields = Pasmo;Popis
PocetVozu
    Caption = Počet vozů
    Check = default(PocetVozu,1) & number(1,10)
Planovano
    Caption = Plán
    Comment = Plánovaný čas přenosu ve formátu HHMM-HHMM, tedy například 1800-1935
Skutecnost
    Caption = Skutečnost
    Comment = Skutečný čas přenosu ve formátu HHMM-HHMM, tedy například 1810-1955
Trasa
    Caption = Trasa
    Comment = Trasa
SpojeniPP
    Caption = Spojení PP
Byrokracie
    Caption = Byrokracie
    Comment = Sem můžete psát běžný text popisující postup vyřízení výluky od A až do Z. Tedy položky, které databáze nemá. Všimněte si, že text se vždycky sám od sebe poznačí, kdo a kdy s ním dělal.
    Type = MEMO
    Definition
        WantReturns = 1
        WordWrap = 1
        WantTabs = 0
        AutoDate = yyyymmdd hh:nn
        Autosign = 1
Hotovo
    Caption = Hotovo
	Popis wizardů sleduje indentací stromovou strukturu. Na nejnižším patře jsou jména položek, jsou buď
	známa již volajícímu skriptu (Datum) nebo se do něj teprve dostanou po ukončení běhu wizarda.
	Vedle jména má položka i popisek ("lidské" jméno) - Caption a popis - Comment. Položky mohou být různých
	datových typů a mohou být podrobeny různým kontrolám. Reprezentativní položky si nyní rozebereme pěkně
	jednu po druhé.
Zobrazení textového souboru s novinkami v systému Chceme z distribuce vytáhnout nějaký soubor s popisem
nově implementovaných funkcí a zobrazit jej pomocí WordPadu. Napřed ale vytvoříme lokální kopii, aby někdo
originál nepokazil, kdyby náhodou měl právo zápisu na síťový disk...
    set              Par,$(Param)
    cp               !!$(Par)prg/jlabs/novinky.txt,c:\tmp\novinky.txt
    viewer           c:\tmp\novinky.txt
    exit
Komentář:
	
	První příkaz set je použit pro vyřešení technického detailu. Používáním znaku backslash ve jménech
	souborů totiž firma Microsoft úspěšně zadělala na nekončící problémy. Původně v unixu, ale hlavně i v C-čku
	je backslash určen na kódování řídících znaků. Globální proměnná Param je nastavena při startu VaxNt
	na domovský adresář aplikace - bude tedy určitě obsahovat backslashe v situaci, kdy VaxNt běží jako klient
	ve Windows. Substituce za výrazy  tvaru $(X) se řídí určitými předpisy a zde si jenom pomáháme je oblafnout.
	Naším příkazem dostaneme do lokální proměnné skriptu Par obsah globální proměnné Param.
	
	Pomocí příkazu cp uděláme lokální kopii souboru. Vidíme, že argument je prefixován hned dvěma vykřičníky.
	V dalším to bude vysvětleno detailně, tady dva vykřičníky značí pokyn, aby interpret ponechal "na pokoji"
	backslashe a nesnažil se jejich hodnotu dekódovat. Vezme se tedy slepě hodnota teď už lokální proměnné Par
	a dosadí se do výrazu. Používání znaků \ a / je pro jména souborů uvnitř VaxNt možné obojí. Pozor ale: některé
	utility Windows to snášejí také a jiné zase ne. Kupříkladu WordPadu nevadí slashová jména, ale Wordu ano.
	
	Pomocí viever se zavolá nová instance WordPadu a nasaje se do ní zobrazovaný text. Skript pak dalším příkazem
	exit končí.
	
Aktualizováno dne 20000704. Komentář: info@jlabs.cz