KURZUS: Számítási módszerek

MODUL: Excel programozás

3. lecke: Vezérlőszerkezetek, szubrutinok

Cél: Ebben a leckében a programozás során használt vezérlőszerkezetekkel és a szubrutinokkal fogunk megismerkedni. A hallgató a lecke elsajátítása után már önállóan is meg fog tudni írni kisebb programokat.

Követelmények: Ön akkor sajátította el megfelelően a tananyagot, ha képes

  • a különböző vezérlőszerkezeteket (szekvencia, szelekció, iteráció) felismerni, ill. ezekből építkezve programot készíteni,
  • megkülönböztetni a függvényeket és az eljárásokat,
  • eljárást és függvényt készíteni.

Időszükséglet: A tananyag elsajátításához (az önálló programozási feladatok megoldása nélkül) hozzávetőlegesen 6 órára lesz szüksége.

Kulcsfogalmak

  • Szekvencia
  • Szelekció
    • If
  • Iteráció
    • While
    • For
    • Do
  • Szubrutin
    • Eljárás
    • Függvény
Vezérlőszerkezetek

Az eddigiekben szó volt a változók deklarálásáról, az értékadó utasításról, az adatbekérő és adatkiíró lehetőségekről, így ezekből már összeállíthatunk egy olyan programot, amely bizonyos bemenő adatokból valamilyen eredményadatokat számol és ezeket meg is jeleníti. A megfelelő utasításokat ilyenkor egyszerűen sorban egymás után (szekvenciálisan) megadjuk, illetve végrehajtatjuk.

De mi van akkor, ha egy utasítást csak egy adott feltétel teljesülése esetén kell végrehajtani, vagy ha egy utasítást többször is végre szeretnénk hajtani? Szükségünk van olyan eszközökre, amelyekkel az egyes tevékenységek végrehajtási sorrendje előírható. Ezeket az eszközöket vezérlőszerkezeteknek nevezzük.

A strukturált programozás három vezérlőszerkezet használatát engedi meg, ezek a szekvencia, a szelekció és az iteráció. Bizonyítottan minden algoritmus megadható ezekkel a vezérlőszerkezetekkel, ezért a feladatok megoldásánál mi is csak ezeket fogjuk használni.

Szekvencia:Az utasítások egymás után, a megadásuk sorrendjében hajtódnak végre.
Szelekció:A végrehajtandó utasítás(ok) feltétel(ek)től függően kerül(nek) kiválasztásra.
Iteráció:Egy vagy több utasítás ismételt végrehajtása.

Megjegyzés

  • A strukturáltság és a forrásprogramok ehhez igazodó tagolása áttekinthetőbb, ezáltal könnyebben karbantartható programokat eredményez.
  • A VB megenged nem strukturált programokat eredményező, speciális vezérlésátadó utasításokat (pl. GoTo, Exit) is, de ezekkel nem foglalkozunk.
Szekvencia

A szekvencia vezérlőszerkezetben a program utasításai (algoritmus esetén ez egyes lépések, tevékenységek) egymást követően, az utasítások megadási sorrendjében hajtódnak végre. A VB-ben az egyes utasításokat általában külön sorokba írjuk, de egy sorba több utasítást is írhatunk, ekkor az utasítások közé kettőspontot kell tenni.

Gondolja át, hogy mit csinál a következő programrészlet!

'Utasítások megadása egy sorban (végrehajtás: balról jobbra haladva)
Dim i As Integer: i = 3 * 5: MsgBox (i)
'Utasítások megadása egymást követő sorokban (végrehajtás: fentről lefelé)
Dim i As Integer
i = 3 * 5
MsgBox (i)

Megjegyzés

  • A kétféle megadás (nevezetesen hogy egy sorba egy vagy több utasítást írunk) tetszés szerint, vegyesen is alkalmazható.
  • Ha egy sor olyan hosszú, hogy több sorba írjuk, akkor az alulvonás karaktert (_) kell azon sorok végére tenni, amelyek még folytatódnak.
Szelekció

A szelekció vezérlőszerkezet segítségével a végrehajtandó utasítások között szelektálhatunk, azaz megadhatjuk, hogy mikor melyik utasítás, illetve utasítások hajtódjanak végre. Az alábbiakban azt a szelekciós utasítást ismertetjük, amelyben a végrehajtandó utasítások (statements) logikai kifejezésekkel (condition) választhatók ki.

Az If utasítás szintaktikája:

If condition Then [statements] [Else elsestatements]

vagy

If condition Then
  [statements]
[ElseIf condition-n Then
  [elseifstatements]]
...
[Else
  [elsestatements]]
End If

Az első esetben az egész utasítás egy sorba kerül (ekkor nem kell End If az utasítás végére), míg a második esetben több sorba (ahol az egyes ágakban lévő utasítások beljebb tagolása nem kötelező, de javítja az áttekinthetőséget).

Végrehajtás:

  • Az első teljesülő feltételhez tartozó utasítások kerülnek végrehajtásra.
  • Ha egyik feltétel sem teljesül és az Else ág definiált, akkor ezek az utasítások (elsestatements) kerülnek végrehajtásra.

Gondolja át, hogy mit csinál a következő programrészlet!

If d = 0 Then
  MsgBox ("Nulla")
ElseIf d > 0 Then
  MsgBox ("Pozitív")
Else
  MsgBox ("Negatív")
End If

Megjegyzés

  • Az egyes ágakban újabb If utasítások is lehetnek, azaz az If utasítások egymásba ágyazhatók.
  • A VB másik szelekciós utasítása a Select Case utasítás, amely egy (általában nem logikai, hanem pl. egész, szöveg) kifejezés értéke alapján választja szét az egyes ágakat. Az utasítást nem részletezzük, de megjegyezzük, hogy minden Select Case utasítás felírható If utasítás segítségével is.
Iteráció

Az iteráció vezérlőszerkezet segítségével egy vagy több utasítás ismételt végrehajtása valósítható meg. Azokat az utasításokat, amelyeket az iteráció (vagy más néven ciklus) ismételten végrehajt, ciklusmagnak nevezzük. Három alapvető ciklusfajta létezik: az elöltesztelő, a hátultesztelő és a növekményes ciklus.

Az elöltesztelő ciklus a ciklust vezérlő feltételt a ciklusmag végrehajtása előtt vizsgálja, a hátultesztelő ciklus pedig a ciklusmag végrehajtása után. A növekményes ciklus egy speciális elöltesztelő ciklus, amely a ciklusmagot egy változó adott értékei mellett hajtja végre.

Mivel a ciklusszervezés a programozás egyik alapvető eleme, ezért a magas szintű programozási nyelvek (így a VB is) mind a három ciklusfajtát támogatják. Ez lehetővé teszi, hogy az adott feladathoz legjobban illeszkedő ciklusfajtát válasszuk, amivel a megoldásunk (programunk) érthetőbb és áttekinthetőbb lesz, de megjegyezzük, hogy az elöltesztelő ciklussal a másik két ciklusfajta is megvalósítható.

A VB ciklusszervező utasításait ismertetjük a továbbiakban.

A While ciklus szintaktikája:

While condition
  [statements]
Wend

Végrehajtás:

  • Amíg a ciklust vezérlő feltétel (condition) igaz, addig végrehajtódnak a ciklusmag utasításai (statements).
  • A feltételt mindig a ciklusmag végrehajtása előtt vizsgálja (elöltesztelő ciklus), ezért lehet, hogy a ciklusmag egyszer sem kerül végrehajtásra (ekkor üres ciklusról beszélünk).

Megjegyzés: A ciklusmag utasításainak hatással kell lennie a feltétel igazságértékére (ez a Do ciklusra is érvényes), különben a ciklus üres ciklus, vagy végtelen ciklus (ekkor a Ctrl+Break vagy az Esc billentyűkkel leállítható a programfutás).

Gondolja át, hogy mit csinál a következő programrészlet!

i = 1
While i <= 3
  MsgBox i: i = i + 1
Wend

A For ciklus szintaktikája:

For counter=start To end [Step step]
  [statements]
Next [counter]

Végrehajtás:

  • A ciklusmag (statements) végrehajtási feltétele:
    • counter<=end, ha step>=0
    • counter>=end, ha step<0
  • A feltételt mindig a ciklusmag végrehajtása előtt vizsgálja (elöltesztelő ciklus), ezért lehet, hogy a ciklusmag egyszer sem kerül végrehajtásra.
  • A ciklusváltozó (counter) a ciklusmag minden egyes végrehajtásakor a step értékével megváltozik. A step megadása nem kötelező, ha elhagyjuk, akkor az alapértelmezett értéke 1.

Gondolja át, hogy mit csinál a következő programrészlet!

For i = 1 To 5 Step 2
  MsgBox i
Next

Megjegyzés: A VB-ben létezik egy olyan speciális ciklusszervező utasítás is (For Each), amelyben a ciklusváltozó egy gyűjtemény objektumain "lépdel végig".

A Do ciklus szintaktikája:

Do [{While|Until} condition]
  [statements]
Loop

vagy

Do
  [statements]
Loop [{While|Until} condition]

Végrehajtás:

  • A ciklust vezérlő feltétel (condition) vizsgálata az első esetben a ciklusmag (statements) végrehajtása előtt (előltesztelő ciklus), a második esetben pedig utána (hátultesztelő ciklus) történik meg.
  • While kulcsszó esetén, ha a feltétel igaz, akkor a ciklusmag végrehajtása következik, egyébként a ciklusból való kilépés.
  • Until kulcsszó esetén, ha a feltétel igaz, akkor a ciklusból való kilépés történik, egyébként a ciklusmag végrehajtása.

A Do utasítás tehát egy olyan általános ciklusszervező utasítás, amellyel mind az elöltesztelő, mind a hátultesztelő ciklusfajta megvalósítható, ráadásul úgy, hogy a feltétellel megadhatjuk az ismétlés, illetve a kilépés feltételét is.

Megjegyzés

  • A ciklusmag utasításainak beljebb tagolása nem kötelező, de az áttekinthetőség érdekében célszerű.
  • Az If utasításhoz hasonlóan a ciklusok is egymásba ágyazhatók.
  • Vegyük észre a For ciklus step=0 esetét, valamint a Do ciklust vezérlő feltétel elhagyhatóságát! Ekkor a ciklusokból való kilépés az Exit For, Exit Do utasítások segítségével történhet, amelyeket a strukturáltság megőrzése érdekében nem említettünk (de a VB megengedi a használatukat).
Szubrutinok

Szubrutinon egy jól meghatározott, önálló tevékenységsort megvalósító, formailag is elkülönülő programrészt értünk. A szubrutinok tényleges végrehajtásához általában egy másik, a szubrutint aktivizáló, azt meghívó programrész is szükséges. Egy szubrutin többször is meghívható, így annak szolgáltatásai a program megfelelő helyein egy-egy hívással igénybe vehetők.

A szubrutin a programtervezés, illetve programozás alapszintű, de egyben alapvető fontosságú eszköze. Használatukkal érvényesíthető az egységbezárási elv, miszerint egy adott feladat megoldásához szükséges adatoknak és a "rajtuk dolgozó" algoritmusnak egy olyan egysége valósítható meg, amely csak a szükséges mértékben kommunikál a "külvilággal", a szubrutint hívó programrészekkel, egyébként zárt, "dolgait" saját maga "intézi", azokba "nem enged bepillantást".

Megkülönböztetjük a szubrutin deklarálását, ahol definiáljuk a szubrutin által végrehajtandó tevékenységeket, a külvilággal való kapcsolattartás módját és szabályait, valamint a szubrutin hívását, amikor felhasználjuk a szubrutin szolgáltatásait, vagyis definiálva a kapcsolattartás eszközeit, kiváltjuk a tevékenységsor egy végrehajtását.

A kapcsolattartás legfőbb, de nem kizárólagos (hiszen pl. "mindenhonnan látható" (public) változókon keresztül is történhet a kommunikáció) eszközei a paraméterek.

A helyes programozási stílus a teljes paraméterezésre való törekvés. Ez azt jelenti, hogy egy szubrutin a működéséhez szükséges adatokat a paraméterein keresztül kapja, és az eredményeket (a függvényérték kivételével) ezeken keresztül adja vissza. Ezzel ugyanis elkerülhető egy esetleges módosítás olyan "mellékhatása", amely a program egy "távoli részének" végrehajtásakor, előre nem látott, nem tervezett változást, s ezzel többnyire nehezen felderíthető hibát okoz.

Megjegyzés

  • A VBA-ban megírt összes forrásprogram modulokba, azon belül szubrutinokba szervezett.
  • Az objektumorientált programozás objektumtípusai (osztályai) az adatoknak és a rajtuk dolgozó algoritmusoknak egy még általánosabb egységét valósítják meg azáltal, hogy az adatokhoz nemcsak egy, de tetszőleges számú algoritmus rendelhető. Az algoritmusokat megvalósító szubrutinok (más terminológiával metódusok, tagfüggvények) egyrészt "látják" az objektum adatait, másrészt ők definiálják, írják le, modellezik az objektum viselkedését. Osztályokat nem fogunk definiálni, de az Excel objektumait használni fogjuk (lásd 5. lecke).
Deklaráció és hívás

Kétféle szubrutint különböztetünk meg, az eljárást és a függvényt. Az eljárást általában akkor használjuk, ha valamilyen tevékenységet kell végrehajtanunk, a függvényt pedig akkor, ha valamilyen eredményértéket kell kiszámolnunk.

Mivel mind az eljárás, mind a függvény képes adatokat kapni és eredményadatokat visszaadni, így egy adott szubrutin eljárás, illetve függvény alakban is programozható. Az, hogy egy szubrutint eljárás vagy függvény formájában írunk meg, nem elvi kérdés, inkább programozói stílus kérdése. A két forma egymással ekvivalens módon mindig helyettesíthető. Az eljárások és függvények deklarálása és hívása, ha kicsit is, de eltérő.

Deklarálás

Eljárás deklarálásának (egyszerűsített) szintaktikája:

[Private|Public] Sub name[(arglist)]
  [statements]
End Sub

Függvény deklarálásának (egyszerűsített) szintaktikája:

[Private|Public] Function name[(arglist)] [As type]
  [statements]
  [name=expression]
End Function
PrivateA szubrutin csak abból a modulból hívható, amelyikben deklaráltuk.
PublicA szubrutin minden modulból meghívható (ez az alapértelmezés).
nameA szubrutin azonosítója.
arglistA szubrutin formális paraméterei (opcionális).
typeA függvény eredményértékének a típusa.

Vegyük észre, hogy a függvény utasításai között szerepel egy olyan értékadó utasítás is, amivel a függvény nevének (name) mint változónak adunk értéket. Ez az utasítás szolgál a függvény eredményének a beállítására. Több ilyen utasítás is elhelyezhető a függvény utasításai között, de célszerű egyet elhelyezni, azt is a függvény végén, azaz az End Function utasítás előtt.

A formális paraméterek megadásának szintaktikája:

[Optional][ByVal|ByRef][ParamArray]varname[()][As type][=defaultvalue]
OptionalA paraméter elhagyható.
ByValA paraméter átadása érték szerinti.
ByRefA paraméter átadása cím szerinti (ez az alapértelmezés).
ParamArrayTetszőleges számú Variant típusú paraméter átadásához.
varnameA paraméter azonosítója.
typeA paraméter típusa.
defaultvalueAz opcionális paraméter alapértelmezett értéke.

A paraméterek neve előtt álló kulcsszavakkal a paraméterek elhagyhatósága, valamint a paraméterek átadási módja definiálható. Az érték szerinti (ByVal) paramétereken keresztül a szubrutin csak kaphat adatokat, míg a cím szerinti átadású (ByRef) paramétereken keresztül kaphat is adatokat, és vissza is adhat eredményeket. Ezért a ByVal paramétereket a szubrutin bemenő (input) adatainak megadásához, a ByRef paramétereket pedig a szubrutin bemenő és/vagy kimenő (output) adatainak megadásához használhatjuk.

Megjegyzés:

  • Ha egy szubrutinnak több paramétere van, akkor a paramétereket vesszővel kell elválasztani.
  • Egy Optional paramétert csak Optional paraméterek követhetnek, azaz egy elhagyható paramétert nem követhet kötelezően megadandó paraméter.
  • A ParamArray paraméter csak a paraméterlista utolsó eleme lehet. Ilyen paraméter esetén nem használhatunk Optional paramétereket.
  • Ha egy paraméternek nem adjuk meg a típusát, akkor a paraméter Variant típusú lesz.
  • A paraméter neve (varname) mögötti üres zárójelpár azt jelzi, hogy az átadott paraméter egy tömb (lásd később). A tömböket csak cím szerinti paraméterátadással lehet átadni.

Próbálja ki a Vezérlőszerkezetek fejezetben bemutatott példákat egy teszt szubrutin segítségével! Gépelje be a következő szubrutin keretet a kódszerkesztő ablakba, majd a kód felirat helyére másolja be az egyes vezérlőszerkezeteknél bemutatott példákat. Végül futtassa a (teszt) szubrutint az 1. leckében leírt módon!

Sub teszt()
'kód
End Sub
Eljárás hívása
[Call] name[argumentlist]
nameA meghívott eljárás azonosítója.
argumentlistAz aktuális paraméterek.

Az eljárás hívásának kulcsszava (Call) elhagyható. Megadásakor az argumentumlistát zárójelbe kell tenni, ha elhagyjuk, akkor a zárójelet is el kell hagyni.

Függvény hívása

A függvények kifejezések részeként hívhatók (hasonlóan, mint a VB függvényei), azaz a függvényhívás bárhol állhat, ahol egy, a függvény eredményének megfelelő érték állhat (pl. egy értékadó utasítás jobb oldalán). Az aktuális paraméterek zárójelei nem hagyhatók el.

Egy szubrutin hívásakor megtörténik az aktuális és formális paraméterek megfeleltetése (a paraméterek átadása), majd a végrehajtás a hívott szubrutin utasításaival folytatódik. A hívott szubrutin befejeztével a végrehajtás a hívást követő utasítással folytatódik.

Hívás megnevezett paraméterekkel

Ez a fajta szubrutinhívás kényelmes hívást biztosít olyan szubrutinok esetén, amelyeknek sok opcionális paramétere van. Elegendő csak azokat a paramétereket és aktuális értékeiket felsorolni, amelyeket át akarunk adni, a többinek meghagyjuk az alapértelmezett értékét.

Pl.

ActiveWorkbook.SaveAs FileName:="Mentes.xls"

A példában egy objektum egy metódusát hívtuk meg, ami az aktív munkafüzetet menti el a megadott névvel. Az objektumokról és a metódusokról későbbi leckékben lesz szó.

Megjegyzés

  • Általában a programnyelvekben kötött a szubrutinok deklarálásának és hívásának sorrendje, nevezetesen a deklarálásnak meg kell előznie (forráskód szinten) a hívást, de a VB megengedi, hogy egy szubrutint a hívó szubrutin után deklaráljunk.
  • Egy függvény eljárásként is meghívható (pl. ha a függvény eredményére nincs szükségünk). Ekkor az eljárás hívási szabályai érvényesek. A példáinkban szereplő MsgBox függvényt is eljárásként hívtuk meg a Call szó elhagyásával. Az egyetlen paramétert néhol zárójelbe raktuk, de ekkor a zárójelek nem a MsgBox függvény zárójelei, hanem a paraméter egy felesleges zárójelezése.
  • Ha egy szubrutint eljárásként hívunk meg egyetlen paraméterrel és elhagyjuk a Call szót, akkor a paraméter esetleges (felesleges) zárójelezésével a paraméter átadása érték szerinti lesz.
  • A metódushívásokra a szubrutinok hívási szabályai érvényesek.
  • A megnevezett paraméterek tetszőleges sorrendben megadhatók. A paraméterek neve és értéke közé a legyen egyenlő (:=) jelet, míg a paraméterek közé vesszőt kell tenni.
Mintafeladat

A szubrutinok deklarálását és hívását az alábbi feladat segítségével szemléltetjük.

Fordítsunk meg egy adott sztringet!
Pl."Réti pipitér" "rétipip itéR"

Az alábbiakban mind függvénnyel, mind eljárással megoldjuk a feladatot, és mindkét esetben egy hívó, tesztelő szubrutint is készítünk. Erre azért van szükség, mert a paraméterekkel rendelkező szubrutinok nem futtathatók közvetlenül, márpedig a megoldó függvénynek, illetve eljárásnak lesz paramétere. A paramétert a megfordítandó sztring átadására, az eljárással történő megoldás esetén még az eredmény visszaadására is használjuk.

Az első megoldásban (Fordit függvény) a kezdetben üres eredménysztringhez (er) jobbról hozzáfűzzük a sztring karaktereit fordított sorrendben, azaz először a legutolsót, majd az utolsó előttit, legvégül az elsőt. Amikor az eredménysztring előállt, akkor a megfelelő értékadással (amikor is a függvény neve értéket kap) gondoskodunk az eredmény beállításáról.

A második megoldásban (MegFordit eljárás) a kezdetben üres eredménysztringhez (er) balról hozzáfűzzük a sztring karaktereit eredeti sorrendben, aminek eredményeként a sztring első karaktere kerül az eredménysztring legvégére, a második karaktere lesz az utolsó előtti, végül az utolsó karaktere kerül az eredménysztring legelejére.

Természetesen a megoldások lényegét adó ciklusok lehetnének egyformák is, de a kétfajta megközelítéssel azt szerettük volna érzékeltetni, hogy még egy ilyen egyszerű feladatnak is létezhet többféle megoldása.

Megjegyzés: Olyan megoldás is elképzelhető, amelyben a sztring megfelelő karakterpárjait cserélgetjük fel. Az első karaktert az utolsóval kell kicserélni, a másodikat az utolsó előttivel, és így tovább.

'Sztring megfordítása függvénnyel
Function Fordit(st As String) As String
  Dim i As Integer
  Dim er As String
  er = ""
  For i = Len(st) To 1 Step -1
    er = er + Mid(st, i, 1)
  Next
  Fordit = er
End Function
'A Fordit tesztjéhez ez indítandó
Sub Teszt1()
  'Híváskor a cím szerinti (ByRef) paraméter (st) helyén állhat érték is
  MsgBox Fordit("Kitűnő vőt rokonok orrtövön ütik")
End Sub
'Sztring megfordítása eljárással
Sub MegFordit(st As String)
  Dim i As Integer, er As String
  er = ""
  For i = 1 To Len(st)
    er = Mid(st, i, 1) + er
  Next
  'A cím szerinti (ByRef) paraméterben (st) adjuk vissza az eredményt
  st = er
End Sub
'A MegFordit tesztjéhez ez indítandó
Sub Teszt2()
  Dim s As String
  'Call esetén kell a zárójel
  s = "Indul a görög aludni": Call MegFordit(s): MsgBox s
  'Call nélkül nem kell a zárójel
  s = "Géza kék az ég": MegFordit s: MsgBox s
End Sub

A lecke lezárásaként megjegyezzük, hogy a VB nem engedi meg a szubrutinok egymáson belüli deklarálását, de a rekurziót (amikor is egy szubrutin önmagát hívja meg, vagy több szubrutin hívja egymást kölcsönösen) igen. A rekurzív algoritmusok iránt érdeklődőknek a szakirodalmat - pl. (Pusztai 2008) vagy (Cormen et al. 2003) - ajánljuk.

Önálló programozási feladatok

Készítsen Visual Basic szubrutinokat az alábbi feladatokra! A bemenő adatokat az InputBox függvénnyel kérje be, az eredményeket a MsgBox függvénnyel írja ki! Feltehető, hogy a felhasználó jó adatot ad meg!

Pl. Kérjünk be egy egész számot és írjuk ki a négyzetét!

Sub Negyzet()
  Dim i As Integer
  i = InputBox("Adj egy egész számot!")
  MsgBox "A szám négyzete: " & i ^ 2
End Sub

1. Kérjük be egy kör sugarát, majd írjuk ki a kör területét és kerületét! (Tipp: A bekérést, a számolást és a kiírást egymás után (szekvencia) hajtsuk végre!)

2. Kérjünk be két egész számot, majd írjuk ki a nagyobbik szám értékét! (Tipp: A bekérés után a megfelelő eredmény kiírása szelekció segítségével történhet.)

3. Adott három szám esetén mondjuk meg azt, hogy lehet-e a három szám egy síkbeli háromszög három oldalának a hossza vagy sem! (Tipp: Ha bármelyik két oldal hosszának összege nagyobb, mint a harmadik oldal hossza, akkor "lehet", egyébként "nem".)

4. Adott két kör a síkon a középpontjának koordinátáival és a sugarával. Mondjuk meg azt, hogy van-e a köröknek közös pontja vagy sem! (Tipp: Ha a középpontok (Pitagorasz-tétellel kiszámolt) távolsága nagyobb, mint a két sugár összege, akkor "nincs", egyébként "van".)

5. Oldjuk meg az ax2+bx+c=0 másodfokú egyenletet a valós számok körében, ahol az a, b és c együtthatók értékei valós számok! (Tipp: A feladat teljes megoldása kezeli az elsőfokú és a másodfokú eseteket (0, 1, illetve 2 db valós gyök) is!)

6. Egy sztringben egy olyan név szerepel, amely két részből áll (családnév, keresztnév), a két részt pontosan egy szóköz választja el. Cseréljük fel a név két részét! (Tipp: Használjuk az InStr, Left és Right függvényeket!)

Pl. "Makk Marci" "Marci Makk"

7. Állítsunk elő adott karakterből álló, adott hosszúságú sztringet! (Tipp: Egy For ciklus segítségével egy kezdetben üres sztringhez fűzzük hozzá a megadott karaktert!)

Pl. "*", 3 "***"

8. Soroljunk be egy adott, legalább két karakterből álló sztringet az alábbi 4 osztály valamelyikébe! Egy sztring

  • növekvő, ha jelei (szigorúan) növekvő sorrendben vannak;
  • csökkenő, ha jelei (szigorúan) csökkenő sorrendben vannak;
  • konstans, ha jelei azonosak;
  • egyéb, minden más esetben.

(Tipp: Az első három esethez vegyünk fel egy-egy logikai változót és állítsuk őket igaz (True) kezdőértékre, majd egy ciklussal vizsgáljuk meg a sztring szomszédos karaktereit (először az elsőt és a másodikat, azután a másodikat és a harmadikat, ..., legvégül az utolsó előttit és az utolsót)! A vizsgálat állítsa hamisra (False) azokat a logikai változókat, amelyek nem teljesülnek (pl. ha a két karakter különböző, akkor a sztring jelei már nem lehetnek azonosak)! A ciklus befejeztével írjuk ki a besorolás eredményét a logikai változók értékei alapján (pl. ha a három logikai változó egyike sem igaz, akkor a sztring az "egyéb" kategóriába tartozik)!

9. Adott n pozitív egész számra írjuk ki a Fibonacci-sorozat első n elemét! A képzés módszere: az első két elem értéke 1, ezután minden következő az előző kettő összege (Pl. n=6: 1, 1, 2, 3, 5, 8). (Tipp: Az n<=2 esetek külön kezelendők, egyébként meg használjunk három változót és egy ciklust a feladat megoldására!)

10. Határozzuk meg két pozitív egész szám legkisebb közös többszörösét! (Tipp: Jelölje a kisebbik számot a, a másikat b. Vizsgáljuk a többszöröseit (a, 2*a, 3*a, ...) egészen addig, amíg b egy többszörösét nem kapjuk. Ilyen szám előbb utóbb lesz, ha más nem, akkor a*b. Egy c szám b többszöröse, ha b megvan benne maradék nélkül, azaz c Mod b=0.)

11. Számítsuk ki két adott, egy napon belüli időpont között eltelt időt! Az időpont óra, perc, másodperc értékekkel adottak, az eredményt is így adjuk meg! (Tipp: Alakítsuk "napon belüli" másodperccé a két időpontot, vegyük ezek különbségét, majd alakítsuk óra, perc, másodperc alakra!)

12. Döntsük el három egész számról azt, hogy Pitagoraszi számhármast alkotnak-e vagy sem! Ha a három szám éppen egy síkbeli, derékszögű háromszög három oldalának a hossza, akkor ilyen számokról van szó, egyébként nem. (Tipp: Ha valamelyik két oldal négyzetének összege éppen a harmadik oldal négyzetét adja, akkor "igen", egyébként "nem".)

13. Adott két zárt intervallum a valós számegyenesen. Mondjuk meg, hogy van-e közös pontjuk vagy sem! (Tipp: Ha valamelyik intervallum bal széle bent van a másik intervallumban, akkor "van", egyébként "nincs".)

14. Határozzuk meg az X és Y koordinátáját egy polárkoordinátákkal adott P(r, φ) síkbeli pontnak! A φ szög fokban adott. (Tipp: A Sin és Cos függvények használatához előbb számoljuk át radiánba a fokban adott szöget!)

15. Adott n és k pozitív egész számokra határozzuk meg a binomiális együttható értékét! (Tipp: A képletet (n!/(k!*(n-k)!)) ne a számláló és a nevező kiszámolása utáni osztással számoljuk ki (a nagy számok miatti pontatlanság/túlcsordulás miatt), hanem előbb egyszerűsítsük a képletet k!-sal, majd a kapott törtet bontsuk n-k db tört szorzatára, és ezt számoljuk ki!)

Önellenőrző kérdések
1. Az alábbi állítások közül melyek igazak a VB vezérlőszerkezetekkel kapcsolatosan?
Egy If utasításban lehet olyan eset is, amikor egyik feltétel sem teljesül.
Az elöltesztelő ciklusban a ciklusmag legalább egyszer végrehajtódik.
A While ciklus hátultesztelő ciklus.
A For ciklus elöltesztelő ciklus.
A Do utasítással mind elöl-, mind hátultesztelő ciklus programozható.
2. Az alábbi állítások közül melyek igazak a VB szubrutinokkal kapcsolatosan?
Egy szubrutin pontosan annyi paraméterrel hívható meg, ahány paraméterét deklaráltuk.
Egy ByVal kulcsszóval deklarált paraméterben a szubrutin eredményt tud visszaadni.
Ha egy szubrutinnak egynél több eredménye van, akkor csak eljárásként programozható.
Egy függvénynek nem lehet elhagyható (opcionális) paramétere.
Egy függvény meghívható eljárásként is.
A megnevezett paraméterek tetszőleges sorrendben megadhatók.
3. A strukturált programozás mely vezérlőszerkezetei "találhatóak meg" az alábbi programkódban?
Do While i Mod 2 = 0: i = i\2: Loop
szekvencia
szelekció
iteráció
felsorolt lehetőségek egyike sem
4. Mit írjunk a ? helyére, ha a számokat 1-től 10-ig szeretnénk kilistázni?

FONTOS: A megoldást a fejlesztőkörnyezet használata nélkül adja meg!

i = 1
Do While i ? 10
  Debug.Print i
  i = i + 1
Loop

?:

5. Milyen eredményt kapunk, ha lefuttatjuk a Teszt szubrutint?

FONTOS: A megoldást a fejlesztőkörnyezet használata nélkül adja meg!

Function Darab(a As Byte, b As Byte, c As Byte, _
    d As Byte) As Byte
  Dim i As Byte, db As Byte
  db = 0
  For i = a To b
    If i Mod c = 0 Or i Mod d = 0 Then
      db = db + 1
    End If
  Next
  Darab = db
End Function

Sub Teszt()
  MsgBox Darab(33, 44, 2, 3)
End Sub

Eredmény:

6. Milyen eredményt kapunk, ha lefuttatjuk a Teszt szubrutint?

FONTOS: A megoldást a fejlesztőkörnyezet használata nélkül adja meg!

Function Valami(st As String) As Long
  Dim i As Long, er As Long
  er = 1
  For i = 2 To Len(st)
    If Mid(st, i, 1) <= Mid(st, er, 1) Then er = i
  Next
  Valami = er
End Function

Sub Teszt()
  MsgBox Valami("DBCDCBE")
End Sub

Eredmény:

Ha az előző feladatok megoldását nem tudta meghatározni a VBA fejlesztőkörnyezet használata nélkül, akkor futtassa le őket lépésenkénti nyomkövetéssel (lásd 1. lecke )! Figyelje meg az egyes változók értékeinek alakulását is!