Хочу предложить обсудить различия в поведении VBA при переполнении целоцисленной переменной, в зависимости от ситуации.
(Примечание: наблюдение более актуально для VBA. В VB, в меню Advenced Optimizations есть параметр Remove Integer Overflow Checks,
который на практике почти всегда установлен, и с ним целые цисла всегда переполняются корректно.)
Выполнение каждой из процедур этого кода:
- Код: Выделить всё
Option Explicit
Sub IntOverflow1()
nN = &H7FFFFFFF
nN = nN + 1&
Debug.Print "nN = " & Hex(nN)
End Sub
Sub IntOverflow2()
Dim nN As Long
For nN = &H7FFFFFFF To &H7FFFFFFF
Next nN
Debug.Print "nN = " & Hex(nN)
End Sub
Sub IntOverflow3()
Dim nN As Long
For nN = &H7FFFFFFF To &H7FFFFFFF Step 1&
Next nN
Debug.Print "nN = " & Hex(nN)
End Sub
Ожидаемо вызовет Run-time error '6': Overflow, ничего не обычного.
(Примечание: для циклов FOR значение переменной цикла после его выполнения штатно на шаг больше верхней границы цикла.
Значение верхней границы специально взято тамким, чтобы спровоцировать переполнение.)
Изменим код:
- Код: Выделить всё
Sub IntOverflow()
Dim nN As Long
On Error Resume Next
'1
nN = &H7FFFFFFF
nN = nN + 1&
Debug.Print "nN = " & Hex(nN)
'2
For nN = &H7FFFFFFF To &H7FFFFFFF
Next nN
Debug.Print "nN = " & Hex(nN)
'3
For nN = &H7FFFFFFF To &H7FFFFFFF Step 1&
Next nN
Debug.Print "nN = " & Hex(nN)
End Sub
Получаем вывод:
nN = 7FFFFFFF
nN = 80000000
nN = 7FFFFFFF
То есть, при, казалось бы, схожих начальных условиях переполнение целого в одних случаях выполняется, в других - нет.