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 virheenkäsittelyominaisuuksiin. Tämän osion jälkeen opiskelija osaa huomioida ohjelmissaan mahdollisia virhetilanteita.

Virheenkäsittely

Kuten aikaisemmasta tiedämme, virheitä on kolmenlaisia. Keskitymme nyt ns. ajonaikaisiin virheisiin, joita on ja aina tulee olemaan ohjelmissamme. Pyrimme oppimaan menetelmät em. virheiden huomioimiseksi, jotta ne eivät estäisi käyttäjää käyttämästä ohjelmaamme tehokkaasti ja turvallisesti pelkäämättä mahdollista tietojen hukkumista esim. tallennustilanteessa. Tätä kutsutaan virheenkäsittelyksi.

Virheenkäsittelyssä opetamme ohjelmamme huomaamaan syntyneen virheen ja hoitamaan tilanteen jollain tavalla. Yleisin tapa on kertoa käyttäjälle esim. viestilaatikon avulla syntyneestä virhetilanteesta ja antaa käyttäjälle mahdollisuus korjata tilanne. Jos käyttäjä on esim. tallentamassa tietoa kovalevylle tai korpulle ja levytila on lopussa, kerrotaan siitä käyttäjälle jolle jää mahdollisuus poistaa joitain tiedostoja ja yrittää tallennusta uudestaan sen sijasta, että ohjelma vain kaatuu ja kaikki käyttäjän tekemät tuotokset häviävät.

Virhekäsittelylauseet

VB:ssä on muutama lause virheiden käsittelyyn. Lauseet on listattu alla olevassa taulukossa, jokaisen lauseen yhteydessä on lyhyt kommentti miten virhekäsittelylausetta käytetään.
VirhekäsittelylauseSelite
On Error Goto xxxLause aloittaa virheenkäsittelyn. Virheen tullessa siirrytään kohtaan xxx:
On Error ResumeLause palaa suorittamaan uudestaan riviä, jossa virhe tapahtui
On Error Resume NextLause palaa suorittamaan virheriviä seuraavaa riviä
On Error Goto 0Lause päättää virheenkäsittelyn, tämän jälkeen tulevat virheet "kaatavat" ohjelman

Err

Virheen syntyessä Err -olio sisältää tiedot virheestä. Oliota voi käyttää esim. kun kerrotaan käyttäjälle syntyneestä virheestä tarkemmin:
MsgBox "Virhe: " & Err.Description & ", virhekoodi: " & Err.Number
Virheen syntyessä (esim. nollalla jako) lauseke tulostaa (jos virheenkäsittely on asetettu päälle) tekstin "Virhe: Division by zero, virhekoodi: 11". Lisätietoja virhenumeroista ja virheistä on lueteltu täällä. Tämän esimerkin "ongelma" on se, että virheilmoitus on englanninkielinen. Voit tehdä suomenkielisiä virheilmoituksia esim. seuraavasti
On Error Resume Next
    MsgBox 1 / 0

    Select Case Err.Number
        Case 11 ' Division by zero
            MsgBox "Nollalla jako!", vbCritical
    End Select
Monesti helpoin tapa löytää virhenumerot (eli syntyvät virheet) on testata ohjelmaa ja ottaa syntyvä virhenumero talteen. Tämän jälkeen voit lisätä sopivan virhekäsittelyn virheestä riippuen. Alla on esimerkki ohjelmasta, jossa on rakennettu virhekäsittely useammalle eri virheelle.
Private Sub Command1_Click()
On Error GoTo Virhekasittely

    Dim Luku1, Luku2 As Long

    Luku1 = CLng(InputBox("Syötä luku", "Luku 1"))
    Luku2 = CLng(InputBox("Syötä luku", "Luku 2"))

    MsgBox "Luku " & Luku1 & " jaettuna luvulla " & Luku2 & " on " & (Luku1 / Luku2), vbInformation

Exit Sub
Virhekasittely:
    Select Case Err.Number
        Case 11 ' Division by zero
            MsgBox "Nollalla jako!", vbCritical
        Case 13 ' Type mismatch
            MsgBox "Vain numeroita, kiitos!", vbCritical
            ' Yritetään uudestaan
            Resume
        Case Else
            MsgBox "Muu virhe: " & Err.Description & ", " & Err.Number, vbCritical
    End Select
End Sub
Esimerkissämme luomme kaksi muuttujaa (Luku1 ja Luku2) joihin pyydämme käyttäjältä Long -tyyppiset arvot. Yritämme muuntaa InputBox:lla saadun arvon käyttäen Clng -metodia. Jos käyttäjä syöttää muuta kuin numeerista tietoa, syntyy virhe numerolla 13 (Type Mismatch). Tällöin kerromme käyttäjälle, että syöte on oltava numeerista ja yritämme suorittaa käskyn uudestaan (Resume). Seuraavaksi yritämme laskea lukujen 1 ja 2 välisen jakolaskun. Jos luku 2 on nolla, syntyy virhe numerolla 11 (Division by Zero) eli nollalla jako. Tällöin kerromme käyttäjälle virhetilanteesta. Muussa mahdollisessa virhetilanteessa kerromme käyttäjälle virheen englanninkielisen nimen ja virhekoodin.

Huomaa Exit Sub -komento "normaalin" ohjelmakoodin perässä. Tämä on sen takia, että ohjelmakoodin suoritus ei menisi virhekäsittelijään jos ohjelmakoodi on kyetty suorittamaan normaalisti.

On Error Goto Virhekasittely -lauseke ohjelmakoodin alussa kertoo VB:lle, että virheen sattuessa hyppää käsittelemään virhettä kohtaan, jossa on Virhekasittely: -lauseke.

Virhekoodit

Virhekoodi Virheviesti
3 Return without GoSub
5 Invalid procedure call
6 Overflow
7 Out of memory
9 Subscript out of range
10 This array is fixed or temporarily locked
11 Division by zero
13 Type mismatch
14 Out of string space
16 Expression too complex
17 Can't perform requested operation
18 User interrupt occurred
20 Resume without error
28 Out of stack space
35 Sub, Function, or Property not defined
47 Too many DLL application clients
48 Error in loading DLL
49 Bad DLL calling convention
51 Internal error
52 Bad file name or number
53 File not found
54 Bad file mode
55 File already open
57 Device I/O error
58 File already exists
59 Bad record length
61 Disk full
62 Input past end of file
63 Bad record number
67 Too many files
68 Device unavailable
70 Permission denied
71 Disk not ready
74 Can't rename with different drive
75 Path/File access error
76 Path not found
91 Object variable or With block variable not set
92 For loop not initialized
93 Invalid pattern string
94 Invalid use of Null
97 Can't call Friend procedure on an object that is not an instance of the defining class
98 A property or method call cannot include a reference to a private object, either as an argument or as a return value
298 System DLL could not be loaded
320 Can't use character device names in specified file names
321 Invalid file format
322 Can’t create necessary temporary file
325 Invalid format in resource file
327 Data value named not found
328 Illegal parameter; can't write arrays
335 Could not access system registry
336 Component not correctly registered
337 Component not found
338 Component did not run correctly
360 Object already loaded
361 Can't load or unload this object
363 Control specified not found
364 Object was unloaded
365 Unable to unload within this context
368 The specified file is out of date. This program requires a later version
371 The specified object can't be used as an owner form for Show
380 Invalid property value
381 Invalid property-array index
382 Property Set can't be executed at run time
383 Property Set can't be used with a read-only property
385 Need property-array index
387 Property Set not permitted
393 Property Get can't be executed at run time
394 Property Get can't be executed on write-only property
400 Form already displayed; can't show modally
402 Code must close topmost modal form first
419 Permission to use object denied
422 Property not found
423 Property or method not found
424 Object required
425 Invalid object use
429 Component can't create object or return reference to this object
430 Class doesn't support Automation
432 File name or class name not found during Automation operation
438 Object doesn't support this property or method
440 Automation error
442 Connection to type library or object library for remote process has been lost
443 Automation object doesn't have a default value
445 Object doesn't support this action
446 Object doesn't support named arguments
447 Object doesn't support current locale setting
448 Named argument not found
449 Argument not optional or invalid property assignment
450 Wrong number of arguments or invalid property assignment
451 Object not a collection
452 Invalid ordinal
453 Specified not found
454 Code resource not found
455 Code resource lock error
457 This key is already associated with an element of this collection
458 Variable uses a type not supported in Visual Basic
459 This component doesn't support the set of events
460 Invalid Clipboard format
461 Method or data member not found
462 The remote server machine does not exist or is unavailable
463 Class not registered on local machine
480 Can't create AutoRedraw image
481 Invalid picture
482 Printer error
483 Printer driver does not support specified property
484 Problem getting printer information from the system. Make sure the printer is set up correctly
485 Invalid picture type
486 Can't print form image to this type of printer
520 Can't empty Clipboard
521 Can't open Clipboard
735 Can't save file to TEMP directory
744 Search text not found
746 Replacements too long
31001 Out of memory
31004 No object
31018 Class is not set
31027 Unable to activate object
31032 Unable to create embedded object
31036 Error saving to file
31037 Error loading from file
Tehtävä 18