A Visual Basic programozási nyelv

Típusok, típuskonstrukciók

1. Típusszerkezet

2. Elemi típusok

Visual Basic-ben nem kell a változókat deklarálnunk, azok az első hivatkozásnál jönnek létre. Ez gondot okozhat, mert előfordul, hogy elgépelünk egy változónevet, ami így egy új változót jelent, ami természetesen nem tartalmazza a másik változó értékét. Ennek a problémának a megoldására szolgál az Option Explicit utasítás, ami után minden használt változót explicit módon deklarálnunk kell.

Változókat explicit módon a Dim, Static, Global, Private vagy Public kulcsszóval deklarálhatunk. Ezek a láthatóságban különböznek egymástól. Ha nem adjuk meg a típust, akkor automatikusan Variant lesz).Változó deklaráláskor nem adhatunk meg kezdőértéket.

Többszörös deklaráció is lehetséges, ilyenkor a változók nevét ","-vel kell elválasztani.

Explicit deklarálásnál néhány alaptípus esetén nem feltétlenül kell kiírnunk a típus nevét, bizonyos karakterek a változók végén utalnak a változó típusára. Ezek: %: Integer, &: Long, !: Single, #: Double, @: Currency, $: String

2.1. Diszkrét típusok

A Visual Basicben kétféle egész típus van:

Integer: A legkisebb egész típus, 2 bájtos.

Long: Nagy egész számok ábrázolására használható, 4 bájtos.

String: Karaktersorozat tárolására használható. Alapértelmezésben egy string változó hosszúságú sorozat, azaz a tárolt adattól függően nő vagy csökken a hossza, de deklarálhatunk fix hosszúságú stringet is (String *méret).

Dim nev As String*40

VB-ben a stringek mindig Unicode karaktereket tartalmaznak, ezért lényegében bármilyen szöveg eltárolható bennük. A VB egy Unicode karaktert 2 bájton tárol. A stringek hosszára nincs megkötés. A stringeknek mindig 1 a kezdőindexe, Option Base beállitástól függetlenül.

String műveletek

Függvény Hatás
String$(number, character) Visszaad egy Stringet, amiben az adott karakter adott sokszor ismétlődik
Space$(number)) Visszaad egy Stringet, ami adott számú Space-t tartalmaz
Replace$(exp, what, to) Adott stringben kicseréli a minta előfordulásait.
StrReverse$(string) Visszaad egy stringet, amiben a megadott string karaktereit megfordítja
LTrim$(string) A megadott string elejéről levágja a szóközöket
RTrim$(string) A megadott string végéről levágja a szóközöket
Trim$(string) A megadott string elejéről és végéről levágja a szóközöket
Len(string) Megadja a string hosszát
Mid$(string,start[,len]) Megadja a string substringjét
Left$(string,cnt) Megadja a string adott hosszú kezdőszeletét
Right$(string, cnt) Megadja a string adott hosszú befejezőszeletét
UCase$(string) A kisbetűket nagybetűvé konvertálja
LCase$(string) A nagybetűket kisbetűvé konvertálja
InStr([start,] string1, string2 [, compare]) Megadja a keresett string első előfordulásának indexét. Az elejéről (vagy megadott indextől) keres.
InStrRev([start,] string1, string2 [, compare]) Megadja a keresett string első előfordulásának indexét. A végéről (vagy megadott indextől) keres.
Asc(string) Megadja a string első karakterének ASCII kódját
Chr$(ch) Visszaad egy stringet ami a megadott kódhoz tartozó karakterkódhoz tartozik.

Stringek konkatenációja: Két művelet is rendelkezésünkre áll sztringek konkatenációjához, a + és az & művelet. Biztonságosabb, ha az & műveletet használjuk, mert a + előbb megpróbálja az operandusokat számmá konvertálni, és ez nem elvárt eredményhez vezethet.

Példa

Debug.Print (100 + 100) '200 Debug.Print (100 + "100") '200 Debug.Print (100 & 100) '100100

Date/time: Jan 1, 0000 és dec 31, 9999 közötti érték lehet. Megjelenítési formátuma a Windows alapbeállításokhoz kötődik, de ezt a Format függvénnyel módosíthatjuk. Ez a típus valójában egy lebegőpontos szám, melynek egész szám része meghatározza a dátumot, törtrésze pedig az időpontot. A dátum rész meghatározása úgy történik, hogy a Visual Basic az 1899 december 30. óta eltelt napok számát tárolja a változóban, ami azt jelenti, hogy az ennél korábbi dátumok negatív számként jelennek meg. Az időpont azonosításakor a szám törtrésze a 24 órás nap törtrészét jelenti, azaz 0,0 felel meg éjfélnek, a 0,5 a délnek, a 0,25 pontosan reggel 6 órát jelent, és így tovább.

Boolean: 2 bájtos, de csak True vagy False értéket vehet fel. A VB-ben a True kifejezés számértéke -1!

A nyelvben felsorolási típust az Enum kulcsszó segítségével definiálhatunk.

[Public | Private] Enum name
    membername [= constantexpression]
    membername [= constantexpression]
End Enum

2.2. Valós típusok

Currency: Rögzített tizedespontú szám, melyet leggyakrabban a pénzügyi számításokban használnak. Tizenöt számjegyű lehet az egészrész, a törtrész 4 számjegyű. 8 bájton tárolódik.

Single: 4 bájtos lebegőpontos szám.

Double: 8 bájtos lebegőpontos szám.

A lebegőpontos számok értéke ugyan nagyobb korlátok között mozoghat, mint a Currency, de azokat lehet kerekíteni. A lebegőpontos számokat kifejezhetjük normál formában is.

Byte: 1 bájtos nem előjeles szám. Bináris adatok tárolására javasolt a Byte tömb használata. (Pl. string típusú változókban tárolt bináris értékek az ANSI és Unicode formátumok közötti átalakítás során sérülhentek.) A Byte-típusra is érvényesek a Numerikus típusokra definiált aritmetikai műveletek, kivéve a -1-el való szorzást. (ilyenkor a Byte-ot előjeles Integer-re konvertálja)

Decimal: 12 bájtos, előjel nélküli szám. Megadható, hogy hány darab jegy legyen a tizedespont jobb oldalán (0-28). Exppliciten nem lehet Decimal típusú változót deklarálni, hanem Variant-ként kell létrehoznunk, majd a Cdec függvénnyel készíthetünk belőle Decimal típust.

2.3. Mutató és referencia típusok

Pointerek használata Visual Basicben

Vannak-e a Visual Basicben 'pointerek'? A válasz erre a kérdésre általában 'nem', hiszen nem látunk pointer deklarációkat vagy makrókat a Visual Basicben, mint ahogy a C/C++-ban... A helyes válasz mégis 'igen' lenne. A Visual Basic (mint általában a legtöbb programozási nyelv) használ pointereket. A különbség az, hogy a Visual Basic elrejti őket, amikor csak lehetséges, vagy más néven nevezi, hogy ne terheljen minket a formalitásokkal és a protokollokkal, amik a használatukhoz szükségesek.

A VarPtr (Variable Pointer), StrPtr (String Pointer), és ObjPtr (Object Pointer) nem dokumentált és nem támogatott funkciók, melyeket a Microsoft elérhetővé tett a Visual Basic 5.0-ás és 6.0-ás verzióiban. Ezek a funkciók (sok mással együtt) a Visual Basic.Net-ben már nem találhatók meg. Ezek a funkciók lehetővé teszik a programozónak, hogy elérje azt a memóriacímet, ahol a Visual Basic változói (pointerek) vannak, valamint azt a címet, ahol maga a valódi adat található, amire a változók mutatnak. Az oka annak, hogy ezek a funkciók olyan hasznosak, az, hogy ha ismerjük az adat memóriacímét, akkor módosíthatjuk, másolhatjuk, vagy közvetlenül át is adhatjuk, ahelyett, hogy ezt a Visual Basic tenné meg helyettünk. Ez így gyorsabbá teszi a munkát és némely esetben képessé tesz minket arra, hogy megtegyünk dolgokat, amire a Visual Basic önmagában nem képes.

A Microsoft MSDN leírása a VarPtr-ről:
Ez a funkció arra használható, hogy lekérdezzük egy változó vagy egy tömbelem címét. A változó nevét vagy a tömbelemet paraméterként veszi és visszaadja a címet. De nem szabad megfeledkezni arról, hogy a dinamikus tömböket a Visual Basic újra lefoglalhatja, ezért óvatosan kell használni a VarPtr-t a tömbelem címének lekérdezésénél. Nem használható tömbök címének lekérdezéshez.

A következő példában egy változó címét kérdezzük le:

Dim lngVariableAddress As Long Dim dblMyVariable As Double lngVariableAddress = VarPtr(dblMyVariable)

Ebben a példában egy tömb negyedik elemánek a címét kérdezzük le:

Dim lngElementAddress As Long Dim lngArrayOfLongs(9) As Long ' A tomb negyedik elemenek a cimet kerdezzuk le lngElementAddress = VarPtr(lngArrayOfLongs(3))

A Microsoft MSDN leírása az StrPtr-ről:
A Visual Basic a stringeket BSTR-ként tárolja. Ha a VarPtr-t egy string típusú változón használjuk, megkapjuk a BSTR címét, ami egy pointer a string pointeréhez. Hogy megkapjuk a string buffer címét, az StrPtr funkciót kell használni. Ez a funkció visszaadja a string első karakterének címét. Vegyük figyelembe, hogy a Visual Basic a stringeket UNICODE-ban tárolja.

Egy string első karaktere címének lekérdezéséhez a string változót át kell adni az StrPtr funkciónak. Példa:

Dim lngCharAddress As Long Dim strMyVariable As String strMyVariable = "Valami String" lngCharAddress = StrPtr(strMyVariable)

A Microsoft MSDN leírása az ObjPtr-ről:
Az ObjPtr paramétere egy objektum változó, és megadja az interface címét, amire ez az objektum változó mutat. Egyik fontos alkalmazási területe ennek a funkciónak az objektumgyűjtemények készítése. Ha az objektumot úgy indexeljük, hogy a címét használjuk kulcsként, könnyebben hozzáférhetünk az objektumhoz, mintha az Is operátor segítségével végigmennénk a gyűjteményen. Sok esetben csak az objektum címét lehet megbízható kulcsként használni.

Óvatosnak kell lenni a pointerek dinamikus tömbökben való tárolásánál, mert ha a tömböket újra lefoglaljuk, átméretezzük stb., nagyon valószínű, hogy az adat teljesen új memóriacímet kap majd.

Object: 4 bájtos objektumra mutató pointer, a Set függvénnyel rendelhetünk hozzá értéket. (az objektum lehet pl. Form, Button, Control ...)

Variant: ez az adattípus többféle adatot is tartalmazhat, így használhatjuk pl. dátum, string vagy szám tárolására is. Ha Variant típusú változót használunk egy kifejezésben, akkor a Visual Basic automatikusan elvégzi a típuskonverziókat. Ha egy változót nem deklarálunk expliciten, akkor Variant típusú lesz. A Variant változóhoz tartozik egy belső értékkészlet, és amikor hozzárendelünk egy értéket, akkor a Visual Basic feljegyzi, hogy milyen típusú volt ez az érték, és ennek megfelelően kezeli a jövőben a típuskonverziókat. A Vartype függvénnyel lekérdezhető, hogy a Variant változóhoz éppen milyen típusú érték van rendelve, illetve az IsNumeric függvénnyel megvizsgálhatjuk, hogy számmá konvertálható-e. A Variant változónak két speciális értéke van: 1, Empty - ez lesz a változó értéke kezdetben, és csak akkor változik, ha értéket rendelünk hozzá. 2, Null - általában adatbázis-kezelő alkalmazásokban a hiányzó vagy ismeretlen adatra utal.

3. Típuskonstrukciók

3.1. Tömb típusok

Tömbök: Azonos típusú értékekből tömböt hozhatunk létre, amelyben az egyes elemekre az indexekkel hivatkozhatunk. Bár a tömb elemei azonos típusúak, Variant adattípusú tömb esetén az egyes elemek eltérő típusúak is lehetnek. Tömböt készíthetünk saját adattípusból is. A tömb indexe csak Integer lehet, és a tömb számára a memóriaterület a deklaráláskor foglalódik le.

Fix méretű tömök: Globális tömböt a kód modul deklarációs részében a Global tömb(n) As typename utasítással hozhatunk létre. Modul szintű tömböt a Dim utasítással az adott modul deklarációs részében hozhatunk létre. Lokális tömböt a Static vagy Dim utasítással az eljárás deklarációs részében hozhatunk létre. A tömbök sorszámozása alapértelmezésben nullától kezdődik, de ez az Option Base utasítással megváltoztatható (a modul deklarációs részében). A tömb indexében intervallum is megadható a To kulcsszóval.

Többdimenziós tömbök: A Visual Basicben maximum 60 dimenziós tömböket hozhatunk létre, de ez általában bőven elég.

Példa:

Dim tomb(n,m) As Integer Dim tomb(n To m, f To g) As Integer

Dinamikus tömbök: Olyan tömbök, amelyeknek futási időben változtatható a méretük, ezzel hatékonyabban kezelhető a memória. Deklarálásuk hasonló a fix méretű tömbökéhez, de a dimenziós listát üresen kell hagyni (pl. Dim tomb() ).A későbbiekben a Redim utasítással adhatjuk meg a dimenziókat illetve az elemek számát. A Redim utasítással változtathatjuk a meglévő dimenziók határait, de adatvesztés nélkül csak a felsőt. Alapértelmezésben a dimenziók számának változtatása adatvesztéssel jár, de a Preserve kulcsszó használatával elérhetjük, hogy megmaradjanak az adataink. Ekkor azonban csak az utolsó dimenzió felső határa módosítható, a többinél hibát kapunk. Bármely tömb törlésére használható az Erase utasitás.

A tömbök indexhatárának lekérdezésére a nyelv az Ubound és LBound függvényeket bocsátja a programozók rendelkezésére. Ezek használatával a tömb adott indexének alsó és felső határa kérdezhető le. Komoly hiányossága a nyelvnek, hogy üres tömb esetén a függvények használata futás idejű hibát eredményez. További kellemetlenség a tömbök használatával kapcsolatban, hogy egy dinamikus tömb a Redim utasítással nem állítható vissza üres tömbbé. Ennek ellenére van lehetőségünk annak lekérdezésére, hogy a tömbnek vannak-e elemei.

Példa: Dinamikus tömb inicializálva van-e

Dim my_array() As String If (Not my_array) = -1 Then MsgBox "A tömb nincs inicializálva." End If

Ez a módszer a C nyelvben szokványos, de VB-ben is műkidik.

Példa: Dinamikus tömb feltöltése előre ismeretlen számú értékkel:

Dim I As Integer Dim MyArr() As Integer For i = 1 to X On Error Resume Next Redim Preserve MyArr(Lbound(MyArr) To UBound(MyArr)+1) If Err.Number <> 0 Then Redim MyArr(0 To 0) End If On Error Goto err_handler MyArr(Ubound(MyArr))=i Next i

Variáns tömbök: A dinamikus tömbök fent említett hiányosságát tudjuk kezelni a variáns tömbök alkalmazásával. Ezek lényegében ugyanúgy dinamikus tömbök variant értéktípussal létrehozva. A fő különbség az, hogy ilyen tömbök esetén az LBound és az UBound műveletek inicializálatlan tömbök esetében is működnek, nem vezetnek futási idejű hibához. Ilyenkor az UBound érték eggyel kisebb mint az LBound, alapbeállítások mellett -1 illetve 0 értékeket adnak.

Variáns tömbök használatával létrehozhatunk tömbök tömbjét, ami azért „tud többet”, mint a sima több-dimenziós tömb, mert elemei nem szükségszerűen azonos hosszúságúak. Ekkor azonban az újradimenzionálás nem használható, helyette másolatot kell késziteni az átméretezni kívánt részről:

Dim varray() As Variant varray = Array() ReDim varray(1) As Variant varray(0) = Array(1,2,3) varray(1) = Array(4,5,6) Dim vtemp As Variant vtemp = varray(0) ReDim vtemp(1+UBound(vtemp)) As Variant vtemp(UBound(vtemp)) = 7 varray(0) = vtemp

Nagyon nagy elemszámú tömbök esetén mégsem célszerű a variáns tömbök használata, mert az lassabb programhoz vezet.

Huge tömbök: Olyan tömbök, amelyeknek a mérete 64Kbyte-nál nagyobb. Ezeket a tömböket azonban nem használhatjuk bárhogy, vannak megszorítások, melyeket be kell tartanunk:

3.4. Halmaz típus

Collection: ennek segítségével elemek rendezett halmazát hozhatjuk létre, melyekre ezután egy egységként hivatkozhatunk. A halmazhoz tartozó elemek típusa lehet különböző (Deklarálása: pl. Dim x As New Collection). Ezután a halmazhoz az Add utasítással vehetünk hozzá új elemeket, a Remove-val pedig törölhetünk belőle. A halmaz elemein a For Each ... Next utasítással lépkedhetünk végig. Az elemeket az indexükkel is elérhetjük, az indexelés 1-től kezdődik. Egy elemhez hozzárendelhetünk kulcsot is, ekkor kulcson keresztül is elérhetjük, nem csak indexszel. Collection objektum nem tartalmazhat saját típust.

4. Típuskonverziók

Bármilyen valós kifejezést átkonvertálhatunk valamilyen általunk kívánt típusra a konverziós függvények segítségével.

Függvény neveMilyen típusra konvertál
CboolBoolean
CbyteByte
CcurCurrency
CdateDate
CdblDouble
CintInteger
ClngLong
CsngSingle
CstrString
CvarVariant
CVErrError

5. Konstansok

Konstansokat a változók deklarálásához hasonlóan hozhatunk létre azzal a különbséggel, hogy a sor elejére ki kell írni a const kulcsszót.

6. Kifejezések, operátorok

A Visual Basicben található műveletek:

= értékadás
& karakterláncok összeadása
* két numerikus kifejezés szorzása
+ két kifejezést ad össze, az eredménye a kifejezésektől függően lehet szám, karakterlánc vagy egyéb
- két numerikus kifejezés különbsége
/ két numerikus kifejezés hányadosa. Egészeknél az eredmény single lesz, számtartomány túllépése hibát okoz
\ két numerikus kifejezés hányadosának egészrésze
^ hatványozás
AND két tetszőleges kifejezés közötti logikai ÉS
EQV két tetszőleges kifejezés közötti logikai azonosság (bitenkénti összehasonlításra is jó)
IMP két kifejezés közötti logikai implikáció
Is két objektumhivatkozás összehasonlítására
Like két karaktersorozat összehasonlítására
MOD két numerikus kifejezés osztása utáni maradékot adja
NOT negáció
OR két tetszőleges kifejezés közötti logikai VAGY
XOR két tetszőleges kifejezés közötti kizáró VAGY

Beépitett aritmetikai függvények:

Abs(x) Megadja az x változó abszolút értékét.
Exp(x) Megadja az exponenciális függvény értékét az x helyen
Log(x) Megadja az x szám természetes logaritmusát.
Randomize(x) Beindítja a véletlenszám generátort az x seed értékkel. Nem kötelező x-et megadni, akkor az időt választja seedként.
Rnd(x) Megadja a következő 0 és 1 közötti pszeudo-véletlen számot.
Round(x,n) Visszaadja az x szám n tizedes jegyig kerekített értékét. A kerekítéshez a hétköznapi kerekítést használja, azaz 5-től felfelé kerekít.
Sgn(x) Szignum függvény. Negatív x-nél (-1)-et, pozitív x-nél 1-et, 0-nál 0-t ad vissza.
Sqr(x) Megadja x szám négyzetgyökét ( nem a négyzetét). Negatív argumentum esetén hibát dob.
Sin(x) Megadja x szinuszát
Cos(x) Megadja x koszinuszát
Tan(x) Megadja x tangensét

Relációs műveletek: <, <=, >, >=, =, <>

Műveletek precedneciája:

AritmetikaiÖsszehasonlításiLogikai
^=NOT
-<>AND
*, /<OR
\>XOR
MOD<=EQV
+, ->=IMP
&Like, Is 

Kiértékelés:

A Visual Basic a logikai kifejezések teljes kiértékelését elvégzi. Ez azt jelenti hogy például az alábbi kifejezés futás idejű hibát ad, amennyiben az f file nincs megnyitva (és a ReadFirstByte függvény nem nyeli el a fellépő hibát):

if FileIsOpen(f) AND (ReadFirstByte(f) <> 1) Then ...