Kirjoittaja: Antti Laaksonen
⚠ Huomio! Tämä opas on vanhentunut. Oppaan sisältöön ei voi enää luottaa. Opas on säilytetty vain sen historiallisen arvon vuoksi. ⚠
Ehdot aiheuttavat muutoksia ohjelman suoritukseen: niiden kohdalla ohjelma voi haarautua tai myös pysähtyä. Silmukoita käytetään silloin, kun samaa koodia pitää toistaa tietyn ehdon toteutumiseen asti tai kun käydään esimerkiksi läpi kaikki taulukossa olevat tiedot. Sekä ehdot että silmukat perustuvat lausekkeisiin, joiden arvo on tosi tai epätosi. Niiden avulla päätetään, mikä koodiosuus suoritetaan tai milloin silmukasta siirrytään pois. Ehdot ja silmukat eivät ole hankalia, mutta yhdessä käytettynä niistä pystyy muodostamaan monimutkaisen ohjelman.
Ohjelmaan kuuluvilla luvuilla, merkkijonoilla ja muuttujilla on kullakin oma arvonsa. Lauseke on yksi tällainen arvo yksinään tai useamman arvon yhdistelmä esimerkiksi laskutoimituksena. Kun lausekkeita vertaillaan keskenään, saadaan tuloksena totuusarvo, joka on joko tosi (True
) tai epätosi (False
). Vertailut ovat =
(yhtä suuri), >
(suurempi), >=
(suurempi tai yhtä suuri), <
(pienempi), <=
(pienempi tai yhtä suuri) sekä <>
(eri suuri). Lisäksi useampia totuusarvoja voidaan yhdistää merkinnöillä And
(ja) ja Or
(tai), arvon edessä oleva Not
taas tarkoittaa vastakkaisuutta.
Seuraavassa listassa on muutamia (ehto)lausekkeita Visual Basicin ymmärtämässä muodossa sekä käännettynä suomen kielelle.
x > 3
nimi = "Juhani"
ika >= 18 And ika <= 65
"jänis" > "aasi"
nimi = "Juhani" Or ika < 20
ika <> 20
tai Not ika = 20
Myös yksittäinen luku tai laskutoimitus voi toimia ehtolausekkena. Tällöin ehtolauseke on aina tosi, kunhan luku ei ole 0. Moniosaisen ehtolausekkeen esittämisessä on hyvä käyttää apuna sulkuja. Esimerkki: (ika >= 18 And ika <= 65) Or nimi = "Juhani"
.
Ehtorakenne alkaa sanalla If
ja päättyy merkintään End If
. Tämän lisäksi ehtorakenteeseen voi kuulua ElseIf
-osia, jotka määrittävät useampia ehtoja, sekä loppuun tuleva Else
-lause, jonka perässä oleva koodi suoritetaan silloin, kun yksikään aiemmista ehdoista ei ole tosi. Seuraava esimerkki tervehtii käyttäjää, jos nimi-muuttujan arvo on "Sakari".
If nimi = "Sakari" Then MsgBox "Moikka, Sakke!" End If
Tässä tulee pidempi ehtorakenne, joka ilmoittaa kuukaudessa olevien päivien määrän. Yleisin päivien lukumäärä on 31, minkä vuoksi se on laitettu Else
-vaihtoehtoon.
If kuukausi = 4 Or kuukausi = 6 Or kuukausi = 9 Or kuukausi = 11 Then MsgBox "30 päivää" ElseIf kuukausi = 2 Then MsgBox "28 tai 29 päivää" Else MsgBox "31 päivää" End If
Seuraavassa esimerkissä käyttäjä saa painaa napista kaksi kertaa, mutta kolmannella kerralla ohjelma sulkeutuu.
Private Sub Command1_Click() Static kerrat As Integer kerrat = kerrat + 1 If kerrat > 2 Then End End If End Sub
Jos jokaisessa ehtorakenteen osassa esiintyy sama muuttuja, oikean vaihtoehdon valitsemisen voi toteuttaa paremmin Select Case
-rakenteen avulla. Tutkittava muuttuja ilmoitetaan vain kerran, ja sen jälkeen tulee joukko Case
-haaroja, joiden perässä olevia arvoja verrataan muuttujan arvoon. Yhteen haaraan voi kuulua useampia arvoja, jotka on erotettu pilkuilla. Tässä on toteutettuna edellä ollut esimerkki lyhyemmällä koodilla:
Select Case kuukausi Case 4, 6, 9, 11 MsgBox "30 päivää" Case 2 MsgBox "28 tai 29 päivää" Case Else MsgBox "31 päivää" End Select
Seuraavassa esimerkissä lomakkeella on ohjaintaulukko Command1, johon kuuluu kolme painonappia indekseillä 0 – 2. Tapahtumankäsittelyyn on ilmestynyt Index
-parametri, josta selviää napin indeksi. Jokaisesta nappulasta painettaessa tulee eri ilmoitus Select Case
-rakenteen avulla.
Private Sub Command1_Click(Index As Integer) Select Case Index Case 0 MsgBox "Eka nappi" Case 1 MsgBox "Toka nappi" Case 2 MsgBox "Kolmas nappi" End Select End Sub
Silmukan sisällä olevaa koodia toistetaan, kunnes silmukkaan liitetty lopetusehto täyttyy tai silmukasta poistutaan muuten. Silmukan aloitussana on Do
, ja se loppuu sanaan Loop
. Alussa tai lopussa oleva While
tarkoittaa, että silmukka jatkuu niin kauan kuin ehtolauseke on tosi. Jos taas käytetään sanaa Until
, silmukka jatkuu kunnes ehtolauseke on tosi. Kun ehto laitetaan alkuun, silmukkaan ei välttämättä mennä ollenkaan. Lopussa oleva ehto takaa, että silmukka suoritetaan ainakin kerran.
Seuraavassa esimerkissä silmukka toistuu niin kauan kuin i:n arvo on viittä pienempi. Joka kierroksella i kasvaa yhdellä, joten kierroksia tulee yhteensä viisi: niissä i:n arvo on 0, 1, 2, 3 ja 4. Nämä luvut näytetään myös viesti-ikkunassa.
Dim i As Integer Do While i < 5 MsgBox i i = i + 1 Loop
Saman voi toteuttaa myös Until
-ehdon avulla, jolloin toinen rivi on:
Do Until i >= 5
Ohjelmassa kannattaa valita While
tai Until
sen mukaan, kumpi kuulostaa luonnollisemmalta, jos ehtoa ajattelee suomen kielellä. Toista niin kauan kuin i on pienempi kuin viisi tuntuu selvemmältä kuin toista kunnes i on suurempi tai yhtä suuri kuin viisi. Siksi While
sopii ehkä tähän silmukkaan paremmin. Ohjelman suoritukseen ei tietenkään vaikuta, kummin päin ehdon muodostaa. Jos silmukassa ei ole ehtoa kummallakaan puolella, lopetuksesta täytyy huolehtia itse Exit Do
-komennolla. Muuten ohjelma jumiutuu.
Tavallisesti Do...Loop
-rakennetta käytetään silloin, kun silmukan kierrosten määrää ei ole valmiiksi tiedossa. Seuraava ohjelma kertoo, kuinka monta kertaa 100 euroa maksavan tavaran hinnasta voidaan vähentää 10 prosenttia, ennen kuin tavaran hinta laskee puoleen. Ensimmäisen vähennyksen jälkeen hinta on siis 90 euroa, toisen jälkeen 81 euroa jne. Muuttujassa hinta on tavaran kulloinenkin hinta, kerrat pitää kirjaa alennuskerroista.
Dim hinta As Integer, kerrat As Integer hinta = 100 Do While hinta > 50 hinta = hinta * 0.9 kerrat = kerrat + 1 Loop MsgBox "Hintaa voidaan alentaa " & kerrat & " kertaa."
Jos silmukka kestää kauan, sen sisään on syytä laittaa DoEvents
-komento, jotta koko käyttöjärjestelmä ei jumiudu ohjelman suorituksen ajaksi. Seuraavassa esimerkissä koko ohjelman suorituksen ajan taustalla on silmukka, joka jatkuvasti muuttaa otsikkorivin tekstiksi kellonajan. Kellonaika näkyy värisevänä, koska sen päivitys tapahtuu hyvin tiuhaan. Tällaisessa ohjelmassa täytyy muistaa panna lomakkeen Unload
-tapahtumaan komento End
, jotta silmukka päättyy ja ohjelma sulkeutuu kunnollisesti.
Private Sub Form_Activate() Do Caption = Time DoEvents Loop End Sub Private Sub Form_Unload(Cancel As Integer) End End Sub
For
-silmukan avulla on helppo käydä läpi joukko lukuja, jotka kasvavat tai vähenevät säännöllisesti. Silmukkaan liittyy muuttuja, jonka arvo kullakin silmukan kierroksella on vuorossa oleva luku. Silmukasta voi poistua myös kesken Exit For
-lauseella. Tässä on koodinpätkä, joka näyttää luvut 0, 1, 2, 3 ja 4. Ohjelman toiminta on sama kuin edellisen kappaleen esimerkissä, mutta koodi on nyt lyhyempi ja selkeämpi.
Dim i As Integer For i = 0 To 4 MsgBox i Next
Lukuvälin perään voidaan laittaa askel, jolloin muuttujan arvo kasvaa tai laskee suuremmissa tai pienemmissä erissä. Jos aloitusarvo on lopetusarvoa suurempi, myös askeleen täytyy olla negatiivinen. Seuraavassa on esimerkkinä lukusarjojen (0, 2, 4, 6, 8) ja (4, 3, 2, 1, 0) läpikäynti.
For i = 0 To 8 Step 2 MsgBox i Next For i = 4 To 0 Step -1 MsgBox i Next
Lukujen listaamisen lisäksi For
-silmukan avulla voidaan helposti käsitellä kaikkia taulukkoon kuuluvia alkioita. Seuraavassa esimerkissä luvut on taulukko, jossa on kymmenen alkiota. Muutamia alkioita muutetaan, lopuille jää oletusarvo eli 0. Sitten käydään koko taulukko läpi For
-silmukan avulla ja näytetään kunkin alkion sisältö.
Dim luvut(1 To 10) As Integer, i As Integer luvut(1) = 7 luvut(2) = 3 luvut(7) = 6 For i = 1 To 10 MsgBox "Alkio " & i & ": " & luvut(i) Next
Näin on käyty läpi Visual Basicin tavalliset ehto- ja silmukkarakenteet. Näillä pääsee jo pitkälle...
Viesti-ikkunan näyttävä MsgBox
-komento tuntee viestin lisäksi muita parametreja, joita voidaan käyttää tarvittaessa:
MsgBox viesti, tiedot, otsikko
Viesti ja otsikko ovat kummatkin tavallisia merkkijonoja. Toinen parametri, joka määrittää ikkunassa näkyvät painikkeet ja kuvakkeen, voi olla useamman luvun tai vakion summa. Nappeihin liittyvät vakiot ovat vbOKOnly
, vbOKCancel
, vbAbortRetryIgnore
, vbYesNoCancel
, vbYesNo
ja vbRetryCancel
, ja ne vastaavat melkein suoraan painikkeiden tekstejä englanninkielisessä Windowsissa. Kuvakkeisiin liittyvät vakiot ovat vbCritical
(punainen ruksi), vbQuestion
(kysymysmerkki), vbExclamation
(huutomerkki) ja vbInformation
(tiedotus). Viesti-ikkunassa voidaan käyttää ainoastaan edellä olleita painikkeita ja kuvakkeita. Esimerkkejä:
MsgBox "Kopiointi päättyi.", vbInformation, "Tiedotus" MsgBox "Asemassa ei ole levykettä.", vbAbortRetryIgnore + vbExclamation MsgBox "Haluatko tallentaa tiedoston?", vbYesNo, "Varmistus"
Jos MsgBox
sisältää kysymyksen, käyttäjän painama nappi pitää tietenkin saada jotenkin selville. Silloin käytetään MsgBox
ia funktiona, jonka palautusarvo kertoo painetun napin: vbOk
, vbCancel
, vbAbort
, vbRetry
, vbIgnore
, vbYes
tai vbNo
. Seuraavassa esimerkissä kommentin tilalle kuuluisi tiedoston tallennus, joka tehdään vain silloin, kun käyttäjä vastaa kysymykseen myöntävästi.
If MsgBox("Haluatko tallentaa tiedoston?", vbYesNo) = vbYes Then 'tiedoston tallennus MsgBox "Tiedosto tallennettu." End If
Kysymysikkuna eli InputBox
kysyy käyttäjältä tietoa tekstikentän kautta. Tärkeimmät parametrit ovat:
InputBox(kysymys, otsikko, oletus)
Ainoastaan ensimmäinen parametri on pakollinen. Seuraavassa esimerkissä kysytään käyttäjän nimi merkkijonomuuttujaan ja pelaajien määrä lukumuuttujaan.
Dim nimi As String, maara As Integer nimi = InputBox("Kirjoita nimesi:", "Asetukset") maara = InputBox("Kuinka monta pelaajaa?", "Asetukset", 2)
Pelaajamäärän kysymiseen liittyy kuitenkin ongelma. Jos käyttäjä kirjoittaa luvun sijasta merkkijonon tai liian suuren luvun, tulee virheilmoitus ja ohjelma keskeytyy. Seuraavassa on paranneltu – mutta huomattavasti pitempi – ohjelma, joka kysyy pelaajien määrän ensin merkkijonomuuttujaan ja vasta tarkastusten jälkeen kopioi sen lopulliseen lukumuuttujaan. IsNumeric
-funktio kertoo, onko muuttujan sisältö luku. Jos käyttäjän ilmoittama luku ei ole kelvollinen, kysymysikkuna tulee uudestaan.
Dim tieto As String, maara As Integer Do tieto = InputBox("Kuinka monta pelaajaa?", "Asetukset", 2) If IsNumeric(tieto) Then If Val(tieto) > 0 And Val(tieto) < 5 Then maara = Val(tieto) Exit Do Else MsgBox "Pelaajamäärän täytyy olla välillä 1 - 4!" End If Else MsgBox "Virheellinen pelaajamäärä!" End If Loop MsgBox "Pelaajien määräksi tuli " & maara
Desimaaliosan sisältävien lukujen kysymiseen liittyy omat vaikeutensa, jotka johtuvat siitä, että englannin kielessä desimaalipilkun tilalla on desimaalipiste. Paras tapa on toteuttaa ohjelma niin, että se hyväksyy luvussa sekä pilkun että pisteen. Seuraavassa ohjelmassa käyttäjän kirjoittamassa tekstissä mahdollisesti olevat pilkut muutetaan pisteiksi Replace
-funktion avulla. Sitten tulos muutetaan luvuksi Val
-funktiolla, joka käyttää pistettä desimaalierottimena.
Dim luku As Single luku = Val(Replace(InputBox("Kirjoita luku:"), ",", "."))
Samoja tarkistuksia ja muunnoksia voi tietenkin käyttää myös lomakkeella olevan tekstikentän yhteydessä.
Tavallisesti yksi ohjelmalause kirjoitetaan yhdelle riville. On kuitenkin mahdollista sekä kirjoittaa monta lausetta samalle riville että jakaa pitkä lause useammalle riville. Lauseiden yhdistämiseen käytetään merkkiä :
ja jakamiseen merkkiä _
. Esimerkkejä:
a = 1: b = 2: c = 3 MsgBox "Tiedostoa ei löytynyt hakemistosta. Haluatko jatkaa?", _ vbYesNo + vbQuestion, "Tiedostovirhe"
Tavallisesti rivejä ei kannata yhdistää, koska se monesti tekee ohjelmasta vaikeammin luettavan. Sen sijaan pitkät rivit on hyvä jakaa, jotta ne näkee yhdellä kertaa koodi-ikkunassa.
Kiva laskin
tuosta laskimesta voisi olla hyötyäkin. tosin sellasen voi tehä paremmankin :)
Ja helpomminkin :)
Huomio! Kommentoi tässä ainoastaan tämän oppaan hyviä ja huonoja puolia. Älä kirjoita muita kysymyksiä tähän. Jos koodisi ei toimi tai tarvitset muuten vain apua ohjelmoinnissa, lähetä viesti keskusteluun.