E42-101 – Segédletek IV.
Visual Basic alapok
Visual Basic alapok Bevezetés Viszonylag könnyű egy VBA kódot létrehozni. Talán az egyik legegyszerűbb mód, ha rögzítünk egy makrót (ami valami hasonlót csinál, mint amit elvégeztetni szeretnénk), majd ez a kódot manuálisan módosítjuk (hogy a kód pontosan azt tegye, amit szeretnénk. Persze nem szabad megfeledkeznünk Murphy azon törvényéről, mely szerint a programjaink sosem óhajaink, hanem mindig utasításaink szerint működnek. A gyakorlatokon a programok írását mindig egy makró rögzítésével fogják kezdeni. Az Excel felől tekintve a makró egy, a felhasználó által végrehajtott műveletsorozat, amit a későbbi megismétlés céljára eltárolunk. Ezeket a műveleteket az Excel a rögzítés során VBA utasítások formájában tárolja. Informatikai szempontból az Excel makrói tulajdonképpen programok, amelyek az őket felépítő utasítások sorrendjében hajtódnak végre. Mivel az VBA-t az Excelen keresztül érjük el, ezért a táblázatok celláit fel tudjuk használni a feldolgozandó adatok bevitelére, és a kiszámított adatokat könnyedén el tudjuk helyezni valamelyik táblázati mezőbe. A programozási képességet, a strukturált gondolkodást csak gyakorlattal lehet megszerezni. A számítógép (általában) a hibákat nem tűri, de a hibák helyének és jellegének felderítéséhez segítséget ad. Ez a nyomkövetési funkció az Excel VBA esetében különösen erős. A nyelv története A BASIC (Beginner's All-purpose Symbolic Instruction Code) programozási nyelvet 1964-ben készítette Kemény János és Thomas Kurtz a Dartmouth College-ben, oktatási céllal. A nyelvet a Fortran programozási nyelv alapján tervezték meg. Elterjedésében nagyban közrejátszottak az 1980-as években kifejlesztett számítógépek, melyeknél gyakran a számítógéppel egybeépítve adták a BASIC értelmezőt. Ezekben a különböző számítógépeken futó BASIC programok szinte mindig inkompatibilisek voltak egymással: az egyik géptípusra írt programot más számítógéptípusokon nem lehetett futtatni. Nagy lökést jelentett a nyelv elterjedésében 1. ábra: Kemény János a DOS operációs rendszer elterjedése, melynek újabb verzióiba beépítették a Qbasic nevű BASIC változatot. A Qbasic szoros rokonságban állt a Microsoft QuickBasic fejlesztőeszközével, de nem tudott futtatható fájlt készíteni. A 1990-es évek elejére sokan leírták a Basicet, mivel a Basic alapú mikroszámítógépek kora lejárt, PC-n a C/C++ és a Pascal nyelvek vívtak ki dominanciát. A Microsoft 1991-ben kiadta a Visual Basic-et, ami a legnagyobb megújítása lett a nyelvnek: a QuickBasic strukturált Basic nyelvjárása eseményvezéreltté vált, megjelentek benne objektumorientált vonások, így hatékony és egyszerűen használható Windows fejlesztőeszközzé vált. Tovább segítette a nyelv terjedését két variánsa: Visual Basic for Applications (VBA) az Office programcsomag makrónyelvévé, a Visual Basic Script a Windows operációs rendszer scriptnyelvévé vált. A Visual Basic 2002-ben jelentős átalakításon esett át: megjelent a Visual Basic.NET, ami teljesen objektumorientálttá tette a nyelvet, a .NET keretrendszerhez igazodva. A Visual Basic.NET-ben gyakorlatilag csak a kulcsszavak emlékeztetnek a klasszikus Basic-re, a változások
E42-101 – Segédletek IV.
Visual Basic alapok
olyan mélyrehatóak voltak, hogy még a klasszikus Visual Basic-kel sem kompatibilis visszafele. Emiatt több kritika érte és éri, sokak szerint csak nevében Basic, a legközelebbi rokonságban a C# nyelvvel van. Noha a Microsoft féle irányvonal a legelterjedtebb a nyelv fejlesztésében, a Basic-nek rengeteg nyelvjárása és értelmezőprogramja van. Könnyű tanulhatósága miatt sokan kezdik a programozást vele. Több speciális célú Basic változat létezik, pl. mikrovezérlők programozására vagy játékfejlesztésre.
Áttekintés A VBA egy objektumokat kezelő eljárás-orientált programozási nyelv. Az objektumorientáltság abból adódik, hogy a nyelv képes kezelni azon objektumokat, amelyek a Windows által generált eseményekre reagálnak (ilyen esemény lehet például egy egérkattintás). Az eljárásorientáltság pedig azt jelenti, hogy a VBA programokban az utasítások blokkokba és listákba vannak szervezve. Bár sok hasonló vonás van az Excel és a VBA között, de azért néhány alapvető eltérést meg kell említenünk. Az első dolog teljesen nyilvánvaló. A VBA nyelvben nincsenek cellák, ahova értékeket, számítási képleteket, függvényeket írhatunk. A következmény nyilvánvaló. Nem a cellákat fogjuk a számítások elvégzéséhez fölhasználni, hanem a központi memóriát. Ahhoz, hogy a programjaink minél kevesebb hibával működjenek, ezeket a memóriaterületeket előre lefoglaljuk (deklaráljuk) a VBA programunk számára. Ha az Excel táblázata „mögé nézünk”, akkor azt tapasztaljuk, hogy maga az Excel sem igazi táblázatot használ, hanem egy hosszú listát kezel, ahol minden elem megfeleltethető a táblázat egy cellájának. Memória-takarékossági okok miatt nem rendel az üres cellákhoz semmit, csak azokról a mezőkről tárol adatokat, amelyek ténylegesen tartalmaznak valamilyen karaktert vagy valamilyen egyéb jellemzőt hozzárendeltünk. Minden alkalommal, amikor valamelyik cella tartalmát módosítjuk, akkor egy rutin megvizsgálja, hogy ennek milyen következményei lehetnek a többi cellára nézve, és a szükséges változtatásokat át is vezeti. Ezek a karbantartó rutinok nem „nyilvánosak”, az Excel használói nem láthatják, nem módosíthatják őket. A VBA alkalmazások által generált rutinok (programok) a felhasználók által menedzselhetők. A programjaink utasításokból épülnek fül. Az utasítás egy „elemi” műveletre való felszólítás. Egy programblokk (röviden: blokk) utasítások sorozata. Az első és az utolsó utasítás ebben az esetben azonosítja a blokk kezdetét és végét, valamint megfogalmazza azt, hogy milyen feltételek fennállta esetén kell a blokk belsejében lévő utasításokat végrehajtani. Ha analógiával szeretnénk élni, akkor azt mondhatjuk, hogy az utasítások mondatoknak felelnek meg például egy számítógép kézikönyvében. Ezeket a mondatokat szakaszokba szervezzük, és a szakaszokat egyegy fejléccel látjuk el. A kézikönyvet kinyomtatjuk, és ha használni szeretnénk, akkor nem olvassuk végig az összes szakaszt, csak azt amelyik az adott problémánk megoldását segíti. Az egyes szakaszok használatának feltételeit az első mondat tartalmazza – ez felel meg a programblokkok kezdő utasításának. VBA utasítások A Visual Basic nem ismer sok utasítást. Kevesebb, mint egy tucatnyi utasítással már hatékony alkalmazásokat tudunk készíteni. Ráadásul ezek az utasítások nem is bonyolultak. Az utasítások mindig egy kulcsszóval kezdődnek, ami megmondja a számítógépnek, hogy mit kell csinálnia. Ezt követheti az objektumnak a megnevezése, amin a műveletet el kell végezni, és esetleg valamilyen bővítmények, amelyek pontosítják, egyértelművé teszik az elvégzendő műveletet.
2
E42-101 – Segédletek IV.
Visual Basic alapok
Értékadó utasítás Az Excelben, ha egy kifejezés értékét szeretnénk kiszámoltatni, akkor kiválasztjuk a cellát, ahol az eredményt megjelentetni kívánjuk, majd beírjuk a képletet, például: =2*KITEVŐ(Hatvany)-Osszeg
A képlet az Excelben mindig az = jellel kezdődik, azt követi a (példánkban numerikus) kifejezés, ami tartalmazhat konstans értéket (2), függvényt (KITEVŐ), aritmetikai operátort (*, -), hivatkozást másik cellákra (Hatvany, Osszeg). Az Excel kiszámítja a cella értékét, és megjeleníti a megfelelő táblázati cellában. A VBA értékadó utasítása nagyon hasonlít a fenti formulához: Eredmeny = 2 * EXP(Hatvany) - Osszeg Az első szembetűnő különbség, hogy az = jel bal oldalán van valami, mégpedig egy memóriahivatkozás, amely mutatja azt, hogy a képlet értékét hova kell tennie a VBA-nak. Az Eredmeny egy úgynevezett változónév, ami a RAM egy meghatározott részét jelképezi. Az Excelben az = jel bal oldalára nem kell írnunk semmit, a táblázatkezelőnk az aktuális cellát fogja érteni alatta. A VBA-ban szükségünk van rá, mert a VBA-ban nincsenek cellák, a VBA nem táblázatkezelő. Hogy milyen fizikai címen van ez az érték nem érdekes, ha a programunkban megadjuk azt, hogy az Eredmeny nevű értékre van szükségünk, a VBA mindig helyesen fogja prezentálni nekünk. A másik szembetűnő különbség, hogy a KITEVŐ függvény helyett az EXP-et használtuk. Az Excelnek létezik magyarított verziója (ezt használjuk), ahol a teljes környezetet a magyar nyelvhez illesztették, így az eredetileg EXP függvénynek is adtak magyar nevet. A VBA esetében, mint ahogy az a programozási nyelveknél megszokott, a nyelvi elemeket nem tették át a nemzeti nyelvekre, megmaradtak az eredeti (angol) szintaktikai elemek. A kezdeti Basic nyelvekben a fenti utasítás a következőképpen nézett ki: LET Eredmeny = 2 * EXP(Hatvany) - Osszeg Az értékadó utasítás kulcsszava a teremtő LET (LEGYEN) ige. Ezt a kulcsszót a „modern” Basicek is megengedik, de nem követelik meg. A kulcszóval az értékadó utasítás majdnem egy nyelvtanilag is helyes angol mondatnak felel meg: „Let Eredmeny be equal to… ” („Legyen az Eredmeny egyenlő a …”).
Változók deklarációja A VBA egy programozási nyelv, amely az adatokat a RAM-ban tárolja. A változónevek hivatkozások, amelynek segítségével el tudjuk érni a megfelelő memóriarekeszeket. Nem kell megjegyeznünk a fizikai címeket, ahol az értékek vannak (az első programozási nyelvekben meg kellett jegyezni ezeket!). Ha megfelelő változónevet választunk, ami például utal a tartalomra, akkor csökken a hibák előfordulásának valószínűsége. A RAM az adatok tárolására bináris értékeket, nullák és egyesek sorozatát használja. Minden ilyen jelsorozatot dekódolni kell, mielőtt meg akarjuk tudni, hogy milyen értéket reprezentál. Van amikor egy karaktert tárolunk el a memóriában – ebben az esetben a bináris érték célszerűen egy ASCII kód. Egy decimális értéket is eltárolhatunk a biteken. Ebben az esetben a bináris jelsorozat egyik része a decimális egészet, egy másik része egy másik egészet, mint kitevőt jelképez, ha a számot normál alakban tároltuk el. A programozási nyelveknek – mielőtt használatba vesznek egy bináris jelsorozatot – tudniuk kell, hogy mit is jelképez az. A VBA esetében – mint sok más programozási nyelvnél – a változóneveket explicit módon deklarálnunk kell az úgynevezett deklarációs utasításban. Ennél az utasításnál meg kell adnunk, hogy milyen karaktersorozatot tekintünk majd azonosítónak, és azt is meg kell adnunk, hogy milyen típusú adatot helyezünk el a változónév „mögött”. A VBA deklarációs utasításának szintaktikája:
3
E42-101 – Segédletek IV.
Visual Basic alapok
DIM VáltozóNév AS típus Vagyis az utasítás mindig a DIM szóval kezdődik; ezt követően meg kell adnunk a változó nevét (maximum 255 karakter hosszban), amit használni szeretnénk; utána az AS szócska jön; végül az adattípust leíró jelsorozat. A DIM és az AS szavak kötelező részei a parancsnak. Ezeket változatlanul kell mindig leírnunk. Az persze mindegy, hogy kis- vagy nagybetűvel írjuk. A változónevet mi találjuk ki, célszerű, ha nem túl hosszú, és utal a tartalmára. A név nem kezdődhet számjeggyel, hanem csak betűvel, de a folytatás lehet számjegy is. Az angol betűkön és számjegyeken kívül csak a _ jel használható egy változónévben. Tiltott minden más karakter! Tehát például a szóköz sem használható!!! A változónévben a kis- és nagybetűk azonos jelentéssel szerepelnek, de a kisés nagybetűk megfelelő használatával tagolhatjuk a hosszú változóneveket, és a nagybetűt is tartalmazó változónevek használatával a VBA bizonyos hibákat automatikusan kiszűrhet. Típusként csak a VBA által ismert értékek jöhetnek számításba. Például a DIM Szam AS LONG lefoglal a memóriában egy 32 bit hosszúságú területet Szam névvel azonosítva, amelyben el tud majd helyezni egy úgynevezett hosszú egész (-2 147 483 648; -2 147 483 647; …; 2 147 483 647) számot; a DIM Ertek AS SINGLE lefoglal a memóriában egy 32 bit hosszúságú területet Ertek névvel azonosítva, amelyben el tud majd helyezni egy úgynevezett egyszeres pontosságú decimális {(3,402823⋅1038; -1,401298⋅10-45); 0; (1,401298⋅10-45; 3,402823⋅1038)} számot; a DIM Szoveg AS STRING lefoglal a memóriában egy területet, ahol egy maximum 231 karakter hosszúságú szöveg ASCII kódjai tárolódhatnak. A VBA más típusokat is ismer, de ez a három a leggyakoribb. Már megismertünk két utasítást a LET-et és a DIM-et. Az értékadó utasítás az úgynevezett végrehajtható utasítások közé tartozik. Ha egy ilyen utasítást a számítógép végrehajt, akkor ezzel egy lépést tett az algoritmusban a végeredmény előállításának útján. A DIM úgynevezett leíró utasítás. Egy ilyen utasítás kiértékelése és végrehajtása nem juttat közelebb a megoldáshoz, de fontos információkat ad meg a számítógépnek a program helyes futására, az adatok elhelyezkedésére, típusára stb. vonatkozóan.
Eljárások Mint fentebb említésre került a VBA egy eljárásorientált nyelv. A Visual Basicben a parancsok blokkjait eljárásokba szervezzük. A VBA két csoportját ismeri az eljárásoknak. Az egyik típus a subprocedúra. Az Excelben rögzített makrók tulajdonképpen ilyen subprocedúrák. A másik típus a függvény. Az Excel megengedi az úgynevezett saját függvények „gyártását”, amelyek a táblázatkezelőből is elérhetők. Ezek a függvények is VBA utasítások formájában tárolódnak a háttérben. Subprocedúra A subprocedúra az utasítások egy sorozata, amely a SUB paranccsal kezdődik és az END SUB paranccsal végződik. A SUB szócska után meg kell adni az eljárás nevét majd ezt követően zárójelek között az esetleges futási paramétereket. SUB Demo() DIM I AS Integer DIM Sum AS Single Sum = 3.5 + 7.2 I = MsgBox("A válasz =" & sngSum, vbDefaultButton1) END SUB A blokk-kontroll utasítások között lévő utasítások csak akkor hajtódnak végre, ha az eljárást önmagában futtatjuk vagy másik eljárásból meghívjuk.
4
E42-101 – Segédletek IV.
Visual Basic alapok
Függvény A subprocedúra az utasítások egy sorozata, amely a FUNCTION paranccsal kezdődik és az END FUNCTION paranccsal végződik. A FUNCTION szó után meg kell adni az eljárás nevét majd ezt követően zárójelek között az esetleges paramétereket majd az AS szócskát követően a függvény visszatérési értékét. FUNCTION EnOsszeadom(ElsoSzam AS Single, MasodikSzam AS Single) AS Single EnOsszeadom = ElsoSzam + MasodikSzam END FUNCTION A függvény neve: EnOsszeadom. Két paramétere van, az ElsoSzam és a MasodikSzam. Mindkettő SINGLE típusú. Az AS Single mutatja, hogy a függvény által kiszámított érték is egyszeres pontosságú szám lesz. A függvény értékét akkor állítja elő az Excel, ha valamelyik cellába helyezett kifejezésben szerepel a függvényhivatkozásunk. Tehát a függvényeket arra használjuk, hogy egy konkrét értéket állítsunk elő a segítségükkel. Ahhoz, hogy a függvény által generált érték felhasználható legyen, a FUNCTION – END FUNCTION blokkon belül kell szerepelnie egy olyan értékadó utasításnak, amelyben az egyenlőségjel bal oldalán a függvény neve szerepel. Programblokkok Hosszasan beszéltünk a SUB/END SUB és a FUNCTION/END FUNCTION utasítás-párról. Mindkettő a blokk-szervező utasítások közé tartozik. A blokkon belül elhelyezett utasítások csak akkor hajtódnak végre, ha a blokkot meghívjuk. Például a subprocedúrát meghívjuk mint egy makrót, a függvény-hivatkozást pedig elhelyezzük egy kifejezésben. Blokk-kontroll parancsokat használhatunk a programjainkban elágazások létrehozásához és ciklusok szervezéséhez is. A blokk-szervező utasítások mindig párosával fordulnak elő. Az első jelzi, hogy hol kezdődik a blokk, a második a végét jelzi. Valamelyik közülük azt is tartalmazza, hogy milyen feltételek megléte esetén kell a blokkban elhelyezett utasításokat végrehajtani. Elágazás (IF/END IF) Ha a makrórögzítőt használjuk az Excelben, akkor az Excel (mintegy átnézve a vállunk fölött) csak eltárolja az általunk végrehajtott műveleteket, de arra képtelen, hogy (a gondolatainkat letapogatva) értelmezze, hogy milyen okból döntöttünk azon műveletek mellett, amiket aktivizáltunk. Olyan esetekben, amikor valamilyen esemény bekövetkeztétől, valamilyen objektum állapotától függ, hogy egyik vagy másik műveletet kell végrehajtani, ki kell egészítenünk a makrónk kódját a feltételkezelő utasítással. Ha a blokk fejében elhelyezett logikai kifejezés IGAZ értéket ad, akkor a blokk végrehajtásra kerül, egyéb esetben figyelmen kívül hagyja a számítógép. IF LogikaiKifejezés THEN Parancsblokk END IF A logikai kifejezés egy olyan kifejezés, amely eredményként csak IGAZ vagy HAMIS értéket adhat. Hasonló, mint az Excel HA függvénye. A HA függvény két érték valamelyikével tér vissza, az IF parancs pedig a feltétel igazságtartalmától függően hajtja végre az utasításblokkot. A logikai kifejezés két oldalán egy-egy képlet, kifejezés van, amelyeket összehasonlító operátorokkal kötünk össze. Összetett feltételek esetén a logikai kifejezéseket matematikai logikai műveletekkel kötjük össze. Egy példa egy egyszerű logikai kifejezésre: ActiveCell < 0 Ahol az összehasonlító operátor a < (határozottan kisebb). A logikai kifejezés értéke IGAZ, ha az ActiveCell (az Excel aktív cellája) negatív. Példa összetett logikai kifejezésre: (Ar < 500) OR (Ar > 1000) Ami akkor szolgáltat IGAZ értéket, ha az Ar kisebb mint 500 vagy nagyobb mint 1000. 5
E42-101 – Segédletek IV.
Visual Basic alapok
Az összehasonlító operátorok teljes skálája: < (határozottan kisebb), <= (kisebb vagy egyenlő), = (egyenlő), <> (nem egyenlő), >= (nagyobb vagy egyenlő), > (határozottan nagyobb). A Visual Basicben az = jelnek két szerepe is van. Jelentése a környezettől függ. Az értékadó utasításban értékadó operátorként, logikai kifejezésekben egyenlőségvizsgáló operátorként funkcionál. Az OR logikai művelet mellett a VBA ismeri az AND és a NOT műveleteket is. Gyakran előfordul, hogy két lehetséges műveletsort közül kell választanunk attól függően, hogy a feltételünk IGAZnak vagy HAMISnak bizonyul. Erre a célra szolgál az IF/END IF kiterjesztett lehetősége: IF LogikaiFeltétel THEN ParancsblokkAmitAkkorKellVégregajtaniHaAfeltételIGAZ ELSE ParancsblokkAmitAkkorKellVégregajtaniHaAfeltételHAMIS END IF Egy példa: FUNCTION Negyzetgyok(Szam AS SINGLE) AS SINGLE ‘Függvény a négyzetgyök kiszámítására. A függvény negatív számok esetében ‘nulla értékkel és hibaüzenettel tér vissza. DIM I AS Integer IF Szam < 0 THEN Negyzetgyok = 0 I = MsgBox(Szam & " nincs érték negatív szám esetén") ' A & összekapcsolja a karaktersorozatokat ELSE Negyzetgyok = SQR(Szam) END IF END FUNCTION MsgBox és SQR VBA függvények. Az SQR nem negatív számok négyzetgyökét számítja. Az MsgBox egy üzenetablakot állít elő.
Többszörös elágazás (SELECT/END SELECT) Az IF/END IF utasításpár csak két alternatív blokk közötti választást teszi lehetővé. Sokszor előfordul azonban, hogy ennél több esetet is meg kell különböztetnünk. Ezen lehetséges eset kezelésére szolgál a SELECT/END SELECT utasításpár. SELECT CASE Tesztkifejezés [CASE Értéklista [Utasítások]] ... [CASE ELSE [Utasítások]] END SELECT A Tesztkifejezés bármilyen numerikus vagy szöveges kifejezés lehet. Az Értéklista bármilyen értéksorozat lehet a következők szerint: Értéksorozat – értékek egymástól vesszővel elválasztva; tartomány – Érték TO Érték formában (a TO előtt kell lenni a kisebb értéknek); konkrét érték – előtte az IS szócskával, ha ez elmarad, a VBA automatikusan elhelyezi. Az Utasítások akkor hajtódnak végre, ha a Tesztkifejezés felveszi az Értéklistában felsorolt egyik értéket. A CASE-sor tetszőlegesen sokszor ismételhető. A CASE ELSE rész opcionális, elhagyható – ezt jelzi a [ ]. Akkor hajtódik végre, az itt megadott utasítássorozat, ha fenti esetek egyike sem teljesül. A CASE-esetek kiértékelése a felírásuk sorrendjében történik. Ha az egyik ágba befutott a VBA, akkor a többit már nem vizsgálja.
6
E42-101 – Segédletek IV.
Visual Basic alapok
Egy Értéklista többféle formájú megadást is tartalmazhat. Tehát igaz a következő megadás: Case 1 To 4, 7 To 9, 11, 13, Is > MaxNumber
Ismétlődő utasítások Ha van egy utasítássorozatunk, amit többször, ugyanúgy meg kell ismételnünk, akkor azok végrehajtására ciklusokat (programhurkokat) szervezünk. Kétféle ciklust tudunk megkülönböztetni. Az elsőfajú ciklusnál előre tudjuk, hogy hányszor kell az utasítássorozatot végrehajtani. A másodfajú ciklusnál ez előre nem eldönthető, csak a program futása közben derül ki. Elsőfajú ciklus (FOR/NEXT) Az elsőfajú ciklust a következő példával illusztráljuk: FOR I = 1 TO 10 Utasításblokk NEXT I I egy változónév. A FOR/NEXT ciklusokban hagyományosan az I, J és K egész típusú változókat szokták használni úgynevezett ciklusváltozóként. Ez tulajdonképpen egy számláló. Az értéke a FOR utasításban értékek között változik (nő) egyesével. A fenti példában az I értéke a ciklus első végrehajtása közben 1. Amint a program elér a NEXT utasításhoz növeli a ciklusváltozó értékét 1-gyel, és megvizsgálja, hogy meghaladta-e a TO szócska mögött megadott értéket. Ha ez nem történt meg, akkor megismétli a blokkban (ciklusmagban) lévő utasításokat; ha megtörtént, akkor a ciklus nem hajtódik többet végre. A fenti példában a ciklusmagban lévő utasítássorozat tízszer hajtódik végre. Ha nem egyesével akarjuk növelni a ciklusváltozó értékét, vagy nem növelni, hanem csökkenteni szeretnénk azt, akkor a ciklusfejet ki kell egészítenünk egy STEP résszel is: FOR I = 10 TO 1 STEP -2 Utasításblokk NEXT I Ezen ciklus esetén az I értéke 10-ről indul, és minden végrehajtáskor 2-vel csökken. A fenti kondíciókkal a ciklus négyszer hajtódik végre. Másodfajú ciklus (DO/LOOP) A másodfajú ciklust a DO/LOOP utasításpár különböző szerkezetű használatával szervezhetjük meg. Ezek a struktúrák: 1. DO WHILE LogikaiKifejezés Utasításblokk LOOP 2. DO UNTIL LogikaiKifejezés Utasításblokk LOOP 3. DO Utasításblokk LOOP WHILE LogikaiKifejezés 4. DO Utasításblokk LOOP UNTIL LogikaiKifejezés Az első két megoldás úgynevezett elöltesztelő, míg második kettő hátultesztelő ciklus. Az elöltesztelő ciklusok a ciklusfejben ellenőrzik a ciklusba lépés, ciklusban maradás (WHILE), vagy a ciklus átlépésének, ciklusból való kilépésnek (UNTIL) a feltételét. A hátultesztelő ciklusoknál ez az ellenőrzés a cikluszáró utasításnál történik meg. Az elöltesztelő ciklusoknál elképzelhető olyan eset is, hogy egyáltalán nem lép be a ciklusba a program, míg a hátultesztelőknél legalább egyszer végrehajtódik a ciklus. A WHILE után a ciklusba lépés/ciklusban maradás, az UNTIL után a
7
E42-101 – Segédletek IV.
Visual Basic alapok
ciklus átlépésének/ciklusból történő kilépésnek a feltételét kell megadni. A következő két DO/LOOP ugyanarra az eredményre vezet: DO WHILE ActiveCell > 10 … LOOP DO UNTIL ActiveCell <= 10 … LOOP Figyeljen arra, hogy az algebrában a > ellentettje nem a <, hanem a ≤.
Hibakeresés a Visual Basic kódokban Murphy egyik törvénye kimondja, hogy minden program tartalmaz legalább egy bugot. A bug szó eredetileg rovart jelent, de a programozói szlengben hiba szóval egyenértékű. A bug = hiba keletkezése az informatikai legendárium szerint úgy született, hogy egy programozó kézzel leírta a kódot, majd leadta az adatrögzítőknek, hogy lyukasszák lyukkártyára, és táplálják be a számítógépbe. Igenám, de egy apró rovar a papírlapok közé keveredett, és az ívekre helyezett könyvek(?), egyéb irodai eszközök(?) összenyomták szegényt, és egy ovális forma nyom lett a lepréselt állatkából. Nos ezt az oválist nullának nézte az adatrögzítő, és ezt is betáplálta a számítógépbe – ami persze hibás programfutást eredményezett. Azóta hívják a programhibát bugnak, és a programhibák megtalálását és kijavítását debuggingnak. Az informatika már túllépett a kézzel programot író programozók és az adatrögzítő rabszolgák korszakán, de az önök által megírt kódok is tartalmazni fognak hibákat – remélhetőleg az idő előre haladtával egyre kevesebbet. Természetesen önök is tehetnek a hibák ellen egyrészt a helyes programozási stílus betartásával, másrészt azzal, hogy kihasználják a VBA nyomkövetési lehetőséget, valamint figyelmesen tanulmányozzák a VBA hibaüzeneteit. A helyes programozási stílus pár egyszerű szabály szem előtt tartását jelenti. Ezek közül a legfontosabbak: helyes (beszédes) változónevek; explicit változódeklaráció; logikai szerkezet tükröztetése a kód látványában; megjegyzésekkel világossá tett programlépések; egyszerű logika, szabványos megoldások, algoritmusok. Helyes programozási stílus Változók deklarációja A jól megválasztott, úgynevezett beszédes változónevek nagyban segítik a program logikájának áttekinthetőségét, de persze utalnak a programozó személyes stílusára is. Rengeteg programozó használja ugyanazt a nevet a programjaiban különböző adatok tárolására. Például hagyományosan az I, J, K nevek jelölik az indexeket, számlálókat; mégpedig az I az elsőt, a J a másodikat, a K pedig a harmadikat. Ez a számítógépes korszak előtti időkre vezethető vissza, amikor az algebrai képletekben ezeket a betűket használták alsó indexként. Gyakran az Osszeg, Szumma, Total valamilyen összegzés eredményeként előálló értékre utal; az Ar valaminek az árát; Nev valakinek vagy valaminek a nevét; a Jelszo jelszót takar. Javaslom, és elvárom, hogy az Informatika (E42-101) gyakorlatokon a VBA kódokban a változónevek mindig nagybetűvel kezdődjenek, és ne legyen bennük ékezetes betű. Ha a változónév több szóból állna (Vigyázat! A változónévben nem lehet szóköz!!!), akkor minden „új szó” szintén nagybetűvel kezdődjön. Az ékezetes betűket pedig az ékezet nélküli alapbetűjükkel helyettesítsék.
8
E42-101 – Segédletek IV.
Visual Basic alapok
Az Informatika (E42-101) gyakorlatokon leadott kódokban minden, a programban használt változót deklaráljanak! Ez nem Visual Basic alapkövetelmény. A programozási környezet csak akkor figyeli, hogy explicit módon minden változót deklaráltunk-e, ha a modulunk első utasítása az Option Explicit. Vagyis kezdjék minden kódjukat ezzel az utasítással, és akkor biztos, hogy nem marad el egyetlen változó deklarációja sem, mert a VBA fel fogja hívni a figyelmüket erre a mulasztásukra. Három dolog miatt is érdemes ezt a megoldást használni: 1. Ez az opció nagyon hasznos akkor, ha például elnézünk, elütünk egy karaktert a program begépelése közben. Ha például gyorsan olvassa ezt a két változónevet: Sum1 és Suml, akkor nem biztos, hogy észreveszi a különbséget. Az első végén egy egyes található, a második végén pedig egy kis L betű. Betűtípusa válogatja, hogy bizonyos karakterek mennyire hasonlítanak egymásra. A gyakorlatokhoz adott segédletekben azért is használom az OCR A Extended betűtípust, mert ebben a készletben minden karakter a többitől határozottan különbözik. 2. A következő dolog, ami miatt hasznos a változók deklarációja, hogy a Visual Basic szerkesztője objektumként tárolja el a deklarált változókat, és az Object Browserben rá tudunk keresni ezekre az objektumokra, és minden fontos információt megkapunk róluk. 3. A harmadik előnyt akkor tapasztaljuk meg, amikor kis- és nagybetűket vegyesen használunk a változónevekben. (A VBA nem tesz különbséget a kis- és nagybetűk között. Például a Nev, NEV, nev stb. ugyanazt a változót takarja.) Ha a deklarációban vegyesen használtuk a karaktereket, akkor a programkódban – csupa kis betűvel beírva – automatikusan helyes állásra konvertálódnak a megfelelő karakterek. Ha ez a váltás elmarad, akkor valamit elgépeltünk.
Programkód látványa A helyesen megírt kód látványának szerkezete utal a program logikai struktúrájára. A szabály az, hogy a blokk belsejében lévő utasítások kezdődjenek egy tabulátorhellyel beljebb, mint a blokk feje. A blokk záró utasítása a blokk fejével legyen egy vonalban. Ezen szabály betartásával elkerülhetjük, hogy elmaradjon a blokk lezárása, vagy azt, hogy az egymásba ágyazott ciklusok keresztezzék egymást. A helyes látvány nemcsak a külső szemlélőt segíti a program logikájának megértésében, de a program írójának is hasznos lehet egy későbbi alkalommal való olvasáskor. Megjegyzések, kommentárok A jó program jó kommentárokat tartalmaz. Egy megjegyzéssort a REM utasítással kezdtek a régi Basic programokban. A Visual Basic is megérti ezt az utasítást, tehát használhatjuk, de rövidebben is kezdhetjük a kommentárjainkat, a kulcsszót helyettesíthetjük egy aposztróffal (’). Sőt ez az aposztróffal kezdett kommentár nem csak önálló sor lehet, hanem bármelyik utasítást érdemi része után is elhelyezhetünk így kommentárokat. Célszerű minél több, és minél részletesebb megjegyzést elhelyezni a programkódban, még akkor is, ha a kód egyszerűnek és szabványosnak tűnik. Pár nap szünet után újra elővéve és átnézve a kódot már nem is annyira nyilvánvalóak a dolgok… Egyszerűség Alapszabály, hogy legyen minden egyszerű. Az összetett problémát a lehető legegyszerűbb, elemi részekre kell bontani, ezt önállóan megoldani, és ezekből az apró építőelemekből öszszerakni a bonyolult probléma megoldását. Mint a LEGO építőkockáknál. Talán jó ökölszabály az, ha egy probléma megoldásának kódja hosszabb, mint egy oldal, akkor azt már érdemes két-három kisebb egységre bontani. Az egyszerű problémákat egyszerű megoldani. Sok olyan probléma, ami szinte megoldhatatlannak tűnik egy bonyolult esetben, eltűnik, ha egyszerű részekre bontjuk. Az egyszerű problémák megoldásához rövidebb kódot kell írnunk, és minél rövidebb egy kód, annál kisebb a bugok 9
E42-101 – Segédletek IV.
Visual Basic alapok
keletkezésének valószínűsége. Ha viszont mégis hiba van a programban, akkor azt jóval gyorsabban megtaláljuk. Az ilyen apró, jól elkészített kódot több probléma megoldásánál is felhasználhatjuk. Ha egy problémára megoldására létezik már „szabványos” algoritmus, akkor azt kell használni, és nem szabad újat kitalálni.
Fejlesztőkörnyezet A Visual Basic fejlesztőkörnyezet több módon is segíti a programírót a hibátlan kód elkészítésében, és a hibás működés okának felderítésében. Ezek: helyzetérzékeny súgó; futtatás; lépésenkénti programvégrehajtás; töréspontok elhelyezése; figyelés ablak; próba ablak.
Helyzetérzékeny súgó A VBA szerkesztője felismeri az utasítások kulcsszavát, és az -et használva segítséget nyújt nekünk. Ha például elfelejtettem az IF utasítás szintaktikáját, akkor csak annyit kell tennem, hogy az IF szócskát leírva megnyomom az billentyűt. A Visual Basic súgója kinyitja a kézikönyvet az IF utasításnál. A VBA helpje egy valódi kézikönyv. Tartalmazza a parancs szintaktikáját, megmagyarázza a használatát, példákat mutat be, és kapcsolatokat ad egyéb, a paranccsal összefüggő egyéb információkhoz. Fontos hangsúlyozni, hogy a kézikönyv nem tankönyv. Egy kezdő nem tudja megtanulni belőle a Basic programozást, bár a bemutatott példák sok tanulsággal szolgálhatnak. Egy gyakorlottabb felhasználónak viszont nagy segítséget jelent, ha nem emlékezik egy parancs pontos használatára. A help sajnos angol nyelven áll rendelkezésre a magyar nyelvű Excel estében is.
Futtatás Egy makró normál esetben egy billentyűkombináció lenyomásával indítható el, és a háttérben lefut. Az excel-táblában csak a végeredményt látjuk. Egy makró azonban végrehajtható a Visual Basic modulban is a Indítás Makró indítása parancson keresztül vagy futtatás nyomógombbal () vagy az billentyű lenyomásával. Tipikusan paraméter nélküli eljárások (subprocedúra, függvény) futnak le helyesen, hibaüzenet nélkül. Szintén használható ez a lehetőség akkor, ha a kódban töréspontokat helyeztünk el.
Lépésenkénti programvégrehajtás A programozás közben elkövetett szintaktikai hibákra a szerkesztő rögtön felhívja a figyelmet, illetve az automatikusan felajánlott választási lehetőségek ki is zárják ezen hibák elkövetésének lehetőségét. Sokkal nehezebben találhatók meg, és javíthatók ki a szemantikai (logikai, algoritmusbeli) hibák. A lépésenkénti végrehajtás és a következő lehetőségek segítségével minimalizálni lehet ezeket a hibákat. Az üzemmódot az lehet kiválasztani. A lépésenkénti végrehajtás kiválasztása után a VBA fejlesztő környezet folyamatosan mutatja azt (a háttér színezésével), hogy hol áll a program végrehajtása. A futtatás elindítása után az első végrehajtható parancsra lép, és vár a továbblépés engedélyére. Figyelem! Csak a végrehajtható utasításokon áll meg a nyomkövetés. A deklarációkon, megjegyzéseken nem áll meg a VBA. A kód további végrehajtását (a következő végrehajtható parancsra lépés) a nyomógombbal engedélyezhetjük.
F
10
E42-101 – Segédletek IV.
Visual Basic alapok
A program „várakozó” állapotában lekérdezhetjük az egyes objektumok állapotát. Például egy változó neve fölé húzva a kurzort a szerkesztő egy buborékban kiírja a változó értékét.
Töréspontok elhelyezése Tulajdonképpen a lépésenkénti végrehajtás egy felgyorsított üzemmódja. Egy hosszabb kód esetén az előző üzemmóddal végigkövetni egy programot sok időt vehet igénybe. Egyébként is egy kódban vannak érzékenyebb és kevésbé „veszélyes” utasítások. Nem célszerű időt vesztegetni az egyszerű, elhibázhatatlan utasításoknál megállni. Elegendő, ha csak a bonyolultabb soroknál „parkoltatjuk” a programfuttatást. A programkódban megjelölve ezeket a sorokat a futtatás csak ezeknél, a kiemelt soroknál áll meg. A töréspontokat többféle módon be- és kikapcsolhatjuk: ráállunk a kívánt sorra és Hibakeresés Töréspont ki/be menüpontot kiválasztjuk; ráállunk a kívánt sorra és lenyomjuk az billentyűt; az egérrel kattintunk a szerkesztőpanelben a sor előtt a szürke lécen. Egy programban több töréspont is elhelyezhető. A program várakozó állapotában ugyanúgy lekérdezhetjük az objektumok állapotát, mint a lépésenkénti végrehajtáskor.
Figyelés ablak A vizsgáló ablak egy újabb lehetőség az ellenőrzésre, hibák kiszűrésére. A segédablak a Nézet Figyelés ablak menüponton keresztül nyitható meg. A vizsgálandó változókat, kifejezéseket a kijelölésük után a húzd és dobd módszerrel tudjuk az ablakba áthelyezni. A programkódban elhelyezett töréspontokon történő megállásnál vagy a lépésenkénti végrehajtáskor ellenőrizhetjük az értékeket és a változásokat. Próba ablak Az eljárások, amelyek paramétereket tartalmaznak nem hajtódnak végre közvetlenül a szerkesztőablakban a Makró indítása parancs kiadásakor, és a végeredmény sem biztos, hogy látszik a vizsgáló ablakban. A köztes ablakban bármilyen végrehajtható basic-utasítás kiadható, futatható. Felfüggesztett programfutásnál (töréspontoknál megálló basic-program) óvatosnak kell lenni a köztes ablak használatával, ugyanis az itt végrehajtott műveletek visszahatnak a kódban lévő változók, kifejezések értékére. A köztes ablakban használható a PRINT utasítás is. Az utasítás a megadott változók, kifejezések értékét írja ki, szintén a köztes ablakot felhasználva. Szintaktikája egyszerű. A PRINT szócskát követően, amely helyettesíthető a kérdőjellel is (?) egymástól vesszővel elválasztva meg kell adni a kiíratni kívánt változók neveit, vagy a kifejezéseket. Például, ha az Elso értéke 3, a Harmadik értéke 5, akkor a PRINT Elso, Harmadik, 3*Elso+Harmadik vagy ? Elso, Harmadik, 3*Elso+Harmadik parancs a következő sorba a 3 5 28 értéksorozatot fogja kiírni. A köztes ablak eredményesen felhasználható a kódban használt kifejezések „felépítésére”, kódba helyezés előtti tesztelésére.
11
E42-101 – Segédletek IV.
Visual Basic alapok
Összefoglalás Az előző oldalakon rengeteg új információt olvasott. Valószínűleg ezeket elsőre nem értette meg, ezért erősen javasolt az anyag újbóli és újbóli elolvasása, és a gyakorlás, gyakorlás, gyakorlás. Természetesen a Visual Basic ennél jóval több lehetőséget ad a programozóknak, de kezdő szinten elegendőek ezek az ismeretek. Alapfokon önnek ismernie kell az adattípusokat (LONG, SINGLE, STRING); a változódeklarációt (DIM); az értékadó utasítást (OPTION EXPLICIT + [LET]); a blokkszervező utasításokat (SUB, FUNCTION); a feltételes utasításokat (IF, SELECT); a ciklusszervező utasításokat (FOR, DO); a megjegyzések elhelyezésének technikáját (REM|’); a köztes ablakban használt kiírató utasítást (PRINT|?). Ahogy az elején ígértem. Kevesebb, mint egy tucat (összesen tizenegy) utasítás! ☺
12