Chyba Overflow ve VBA

Chyba Overflow (Runtime-error 6) se ve VBA objevuje v případě, že zadaná hodnota přeteče definovaný rozsah. Jsou ale chvíle, kdy byste ji možná nečekali.

Chyba Overflow
Chyba Overflow

Upřímně řečeno, když jsem se s tím po letech zkušeností potkal, zíral jsem na monitor s otevřenou pusou. Situaci bych chápal, pokud by proměnná Cislo byla explicitně uvedena jako typ Integer (ve VBA rozsah -32 768 až 32768), tj. Dim Cislo As Integer. Výsledek součinu (40 000) rozsah přetéká a chyba je na světě. Nicméně tady by mělo fungovat, že výchozí je typ Variant a podtyp si program určí sám (Long, –2 147 483 648 až 2 147 486 647). Není tomu tak. Fajn, říkám si, deklarace by se měly uvádět, ostatně učíš to tak, proto v dalším kroku definuji striktně proměnnou Cislo jako Long (Dim Cislo As Long). A opět ta samá chyba. Začínal jsem se vztekat…

Chování je zdokumentované na stránce Overflow Error Running Procedure with Math Calculation. Ne nadarmo se říká, že chyby v softwaru označuje Microsoft jako funkčnost. Popis a řešení uvádím po svém v následující proceduře.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Sub ChybaOverflow()

    'https://support.microsoft.com/en-us/kb/125900
   
    'deklarace nehrají roli
   
    'neprojde
    'násobení dvou konstant typu Integer
    'probíhá v rámci rozsahu Integer
    'ale výsledek tento rozsah přetéká
    'Cislo = 200 * 200

    'projde
    'násobení konstant typu Long a Integer
    'probíhá v rámci většího z rozsahů (Long)
    'a výsledek rozsah Long nepřetéká
    Cislo = 200000 * 200
   
    'ošetření chyby konverzní funkcí
    'konverzní funkce alespoň u jednoho ze členů
    Cislo = CLng(200) * CLng(200)
   
    'ošetření chyby typovou deklarací
    'Long ... znak &
    'uvedena alespoň u jednoho ze členů
    Cislo = 200& * 200&

End Sub

S kyselým výrazem ve tváři uvádím i následující bláznivou proceduru.

1
2
3
4
5
6
7
8
9
10
Sub TakovaBlaznivaProcedura()

    Const clngCislo1 As Long = 200
    Const clngCislo2 As Long = 200

    Dim Cislo As Long

    Cislo = clngCislo1 * clngCislo2

End Sub

Poznámka
Příručka programátora říká, že číselným konstantám, ale i proměnným se snažíme přidělit přiměřený datový typ. Tím nejčastějším je zmíněný Integer. Jeho rozsah (pod VBA) už ovšem někdy přestává stačit, a jak podotkl kolega Martin Král, novodobé systémy Windows už mu ani nejsou nakloněny. Proto i já při výuce VBA zlehka směřuji uživatele k typu Long, byť se pro řadu běžných úloh a čísel může zdát megalomanský a zbytečně blokující paměť.