Etusivu Aloitus Kontrollit Metodit Muuttujat Ohjausrakenteet Silmukat Matematiikka Debuggaus Virheenkäsittely Vuorovaikutus Valikot Tiedostonkäsittely Ikkunat Leikepöytä Drag and Drop Tiedostopäätteet Linkkejä Harjoitukset

Johdanto ja tavoite

Tässä osiossa tutustutaan Visual Basic:in debuggausmahdollisuuksiin ja opitaan tuntemaan erilaisia virhetyyppejä. Tämän osion jälkeen opiskelija osaa käyttää Visual Basic:n debuggausominaisuuksia tehokkaasti ja erottaa erityyppiset ohjelmakoodivirheet.

Virhe

Virheitä on monenlaisia ja ohjelmakoodivirheistä puhuttaessa ne voidaan jakaa kolmeen eri tyyppiin. Selkeäsi helpoiten havaittava virhe on syntaksivirhe, jonka VB huomaa viimeistään ohjelmakoodia ajettaessa tai käännettäessä. Tämä tarkoittaa esim. sitä, että yrität kirjoittaa MsgBox:n sijasta msbox:n, tällaista käskyä ei ole ja VB kertoo siitä pyytäen korjaamaan virheen.

Toinen virhetyyppi on ajonaikaiset virheet. Tällainen virhe syntyy, kun ohjelmakoodi on syntaktisesti oikein mutta se yrittää tehdä asiaa, joka on mahdotonta. Yksi tällainen asia on nollalla jakaminen joka synnyttää virheen.

Viimeinen virhetyyppi on looginen virhe. Tällöin ohjelma toimii, ei kaadu ajonaikaiseen virheeseen mutta tulos on väärä.

Syntaksivirhe

Syntaksivirheitä ei käsitellä sen enempää, VB huomaa ne kyllä ja pyytää sinua korjaamaan ne. Ajettaessa ohjelmaa VB:ssä voit varmistaa ohjelmakoodin syntaksin oikeellisuuden ajamalla ohjelma Run (F5 -painike) -komennon sijasta Start with Full Compile (CTRL - F5 -painikkeet) -komennolla joka kääntää ohjelmakoodin ennen sen suoritusta varmistaen, ettei siinä ole syntaksivirheitä. Muutoin ohjelmaa ajettaessa ohjelmakoodin suoritus voi keskeytyä syntaksivirheeseen. Toki virheen voi tietyissä tapauksissa "korjata lennossa" mutta huonolla tuurilla em. korjaus voi kaataa VB:n. Esimerkissämme virhe syntyy kun yritämme kutsua MsgBox -käskyn sijasta msbox -käskyä jota ei ole olemassa.

Syntaksivirhe
Syntaksivirhe.

Ajonaikaiset virheet

Ajonaikaisia virheitä on aina, näitä kutsutaan joskus myös bugeiksi. Ohjelmoija ei voi aina ennustaa mitä tapahtuu, hyvä esimerkki on tiedoston tallennus. Entäpä jos korppu on täynnä? Tai koko korppua ei ole asemassa? Tästä voi syntyä ajonaikainen virhe joka voidaan toki käsitellä käyttämällä ns. virheenkäsittelyä. Esimerkissämme ajonaikainen virhe syntyy, kun yritämme jakaa luvun 50 luvulla 0.

Ajonaikainen virhe
Ajonaikainen virhe.

Looginen virhe

Kaikista pahin virhe on looginen virhe. Ohjelma toimii näennäisesti oikein, ei kaadu virheisiin mutta lopputulos on puutaheinää. Tällainen voi syntyä huolimattomasta ohjelmakoodin kirjoittamisesta. Esimerkissämme looginen virhe syntyy, kun laskemme (ihan oikein) lausekkeen luku 50 jaettuna luvulla 5 tuloksen olla 10. Tallennamme tuloksen oikein muuttujaan Z mutta tulostammekin muuttujan a jota ei ole käytetty ja joka on tyhjä. Tämäkin virhe olisi vältetty, jos meillä olisi käytössä Option Explicit -lause, joka vaatii alustamaan kaikki käytettävät muuttujat.

Looginen virhe
Looginen virhe.

Debuggaus

Joskus (etenkin ajonaikaisen virheen syntyessä tai ohjelman toimiessa eri tavalla kuten pitäisi) on hyvä pystyä keskeyttämään ohjelmakoodin suoritus ja seurata suoritusta rivi riviltä tai esim. funktio funktiolta.

Ohjelman keskeyttäminen

Voit keskeyttää ohjelman suorituksen parilla eri tavalla. Yksi tapa on lisätä ohjelmakoodiriville harmaalle alueelle punainen täplä, ns. keskeytyskohta johon tultaessa ohjelmakoodin suoritus keskeytetään automaattisesti. Toinen tapa on painaa CTRL-BREAK -näppäintä. Tämä on tarpeen silloin, kun haluat pysäyttää ohjelmakoodin suorituksen spontaanisti, esim. jos ajaudut ikuiseen silmukkaan.

Keskeytyskohta koodiin määrittäen
Kuvassa olemme määrittäneet keskeytyskohdaksi haluamme rivin suoraan ohjelmakoodiin.

Keskeytyskohta painamalla CTRL ja BREAK
Kuvassa olemme keskeyttäneet ohjelman suorituksen painamalla CTRL ja BREAK -näppäimiä.

Ohjelmakoodin suorittaminen

Kun olemme saaneet ohjelmakoodimme pysäytettyä, on hyvä alkaa tutkimaan mikä siinä mahdollisesti on vikana (tai ihan muuten vain tutkailla ohjelman suoritusta). Voit suorittaa ohjelmakoodirivin napsauttamalla F8 -näppäintä tai valitsemalla Debug -valikosta Step Into -toiminnon. Muista, että näet nykyisen (ei vielä suoritetun) ohjelmakoodirivisi keltaisen vilkkuvan nuolen kohdalla. Jos ohjelmakoodirivillä on esim. funktiokutsu ja haluat seurata ohjelman suoritusta em. funktioon, napsauta F8 -näppäintä. Jos taasen haluat, että em. funktio suoritetaan mutta et halua seurata sen suoritusta, napsauta CTRL- ja F8 -näppäimiä jolloin VB suorittaa em. rivin (ja funktion) ja kohdistus palaa seuraavalle koodiriville.

Huom! Muuttujamäärittelyihin ja vastaaviin määrittelykohtiin ei voi "pysähtyä" rivi kerrallaan toiminnolla.

Tarkemmat tiedot debuggausvalikon toiminnoista löydät täältä.

Välitön ikkuna

Ohjelman ollessa keskeytettynä on hyvä tutkia muuttujien arvoja. Yksi tapa on laittaa hiiren kursori muuttujan päälle, arvo ilmaantuu pikaohjeeseen.

Pikaohje
Pikaohje.

Toinen tapa nähdä muuttujien arvo on tulostaa ne Immediate -ikkunassa. Jos em. ikkuna ei näy, saat sen esiin View -valikon Immediate Window -toiminnolla. Tähän ikkunaan voit kirjoittaa ohjelmakoodia joka suoritetaan kun painat Enter:iä. Voit tulostaa esim. muuttujien arvoja kirjoittamalla print -komennon (tai pelkästään ?) ja muuttujan nimen:

Muuttujan arvon tulostus
Muuttujan arvon tulostus.

Kuvassa on esitetty kuinka muuttujan arvo voidaan tulostaa kirjoittamalla Print (tai ?) ja muuttujan nimi.

Ohjelmakoodin suorittaminen
Ohjelmakoodin suorittaminen.

Toisessa esimerkissä asetamme muuttujan X arvoksi 5 ja tulostamme muuttujan arvon MsgBox -käskyä käyttäen.

Instant Watch

Toinen tapa tutkailla muuttujan arvoja on ns. Watch:n käyttäminen. Tällöin määrittelemme "seurattavat" muuttujat. Nopea tapa lisätä muuttuja seurattavien muuttujien listaan on pysäyttää ohjelmakoodin suoritus, laittaa hiiren kursori sen muuttujan päälle jota haluaa seurattavan, napsauttaa oikeaa painiketta ja valita aukeavasta valikosta Add Watch -toiminto.

Instant Watch
Instant Watch:n aktivoiminen.

Avautuvasta ikkunasta voi määritellä haluttu lauseke joka muuttujaan kohdistuu, missä aliohjelmassa, moduuleissa ja projektissa muuttujaa seurataan ja katkaistaanko ohjelman suoritus kun lauseke toteutuu vai näytetäänkö vain muuttujan arvo.

Watch Expression
Watch:in määrittely.

Napsauttamalla OK -painiketta muuttujaa seurataan vain nykyisessä aliohjelmassa nykyisessä lomakkeessa nykyisessä projektissa ja näytetään pelkästään muuttujan arvo.

Muuttujan arvon seuraaminen
Kuvassa seuraamme muuttujan arvon muuttumista ohjelman suorituksen aikana.

Jos haluat, voit lisätä Watch:iin myös monimutkaisempiakin lausekkeita. Lisäämme nyt lausekkeen, joka pysäyttää ohjelman suorituksen kun muuttuja X saa arvon 5. Määrittelemme lausekkeeksi siis: X=5. Context -kehyksen asetukset kelpaavat suoraan, meille riittää oletusasetukset. Watch Type -kehyksessä on kolme vaihtoehtoa: Watch Expression joka vain näyttää muuttujan arvon, Break When Value Is True joka keskeyttää ohjelman suorituksen kun em. lauseke on tosi (eli X:n arvo on 5) ja Break When Value Changes joka pysäyttää ohjelman suorituksen aina kun valitun muuttujan (tässä tapauksessa tietysti muuttujan X) arvo muuttuu.

Instant Watch -lauseke
Määrittelemme Instant Watch:in lausekkeeen.

Kun suoritamme ohjelmakoodia, suoritus pysähtyy automaattisesti kun muuttuja X saa arvon viisi tässä metodissa tässä lomakkeessa ja tässä projektissa.

Debug

Voit halutessasi käyttää ohjelmakoodissa ns. väliarvojen tulostamiseen Debug -oliota. Debug -oliolla on kaksi metodia, Print ja Assert. Käyttämällä Print -metodia tulostat ns. Immediate Window:iin. Alla olevassa esimerkissä tulostamme muuttujan X arvon käyttämällä Debug -olion Print -metodia:

Debug -olion Print -metodi
Debug -olion Print -metodin käyttäminen.

Assert -metodilla ohjelmakoodin suoritus pysähtyy jos ehto on epätosi. Jos ehto on tosi, Assert -lause "ohitetaan". Assert -lause toimii vain VB:ssä, kun ohjelmakoodi käännetään EXE:ksi, Assert -lauseita ei oteta mukaan.

Virheen korjaaminen

Käytimme em. debuggausmahdollisuuksia ja löysimme ohjelmakoodistamme ainakin kaksi virhettä. Ensimmäinen virhe liittyy Do Loop While -silmukan ehtoon, jossa määritellään, että silmukassa pysytään niin kauan kun muuttujan X arvo on pienempi kuin 10 (X < 10). Ongelmana tässä on se, että muuttujan X arvo on aloitettaessa 10 joten suoritettuamme yhden kierroksen ohjelmakoodimme hyppää silmukasta pois.

Korjaamme siis virheen, muutamme silmukan ehdoksi seuraavan: X < 10. Nyt huomaamme pian toisen ongelman, muuttujan X arvo ei muutu joten olemme ns. ikuisessa silmukassa!

Korjaamme taas ongelman, lisäämme lausekkeen, joka vähentää muuttujan X arvoa yhdellä jokaisella kierroksella.

Nyt ohjelmakoodimme on toimiva!

Dim X As Long

X = 10

Do
	MsgBox "Kierros " & X
	X = X - 1
Loop While (X > 0)
Yllä on esitelty korjattu ohjelmakoodi.
Tehtävä 17