Kirjautuminen

Haku

Tehtävät

Opasarkisto: Visual Basic -opas: Osa 4 - Ehdot ja silmukat

  1. Osa 1 - Johdanto
  2. Osa 2 - Käyttöliittymä
  3. Osa 3 - Muuttujat ja taulukot
  4. Osa 4 - Ehdot ja silmukat
  5. Osa 5 - Aliohjelmat ja funktiot
  6. Osa 6 - Hiiri ja näppäimistö
  7. Osa 7 - VB:n grafiikkakomennot
  8. Osa 8 - Tiedostot
  9. Osa 9 - WinAPIn käyttö

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.

Todet ja epätodet lausekkeet

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.

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

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

Haarautuminen

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

Silmukka

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

Lukujen läpikäynti

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...

Tietojen näyttäminen (MsgBox)

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 MsgBoxia 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

Tietojen lukeminen (InputBox)

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ä.

Rivien yhdistys ja jakaminen

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.


Kommentit

Jaqqo [25.06.2003 19:57:22]

Lainaa #

Kiva laskin

Graphic [20.09.2003 23:44:32]

Lainaa #

tuosta laskimesta voisi olla hyötyäkin. tosin sellasen voi tehä paremmankin :)

Jen0va [22.12.2003 14:24:48]

Lainaa #

Ja helpomminkin :)

Kirjoita kommentti

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.

Muista lukea kirjoitusohjeet.
Tietoa sivustosta