Числа

Язык VBA поддерживает следующие числовые типы:

Dim p As Variant
p = CDec(12.4546565)
Debug.Print TypeName(p) ' Выведет: Decimal

Создать объект целочисленного типа можно обычным способом:

Dim x As Integer, y As Integer
x = 10
y = -50
Debug.Print x; y ' 10 -50

Кроме того, можно указать число в восьмеричной или шестнадцатеричной форме. Такие числа будут автоматически преобразованы в десятичные целые числа. Восьмеричные числа начинаются с комбинации символов &O и содержат цифры от 0 до 7:

Debug.Print &O7; &O12; &O777 ' 7  10  511

Шестнадцатеричные числа начинаются с комбинации символов &H и могут содержать цифры от 0 до 9 и буквы от A до F:

Debug.Print &H9; &HA; &H10; &HFF ' 9  10  16  255

Вещественное число может содержать точку и (или) быть представлено в экспоненциальной форме с буквой E (регистр не имеет значения):

Dim x As Double, y As Double, z As Double
x = 10.5
y = 1.1E+21
z = 2.5E-25
Debug.Print x; y; z ' 10,5  1,1E+21  2,5E-25

При выполнении операций над вещественными числами следует учитывать ограничения точности вычислений. Например, результат следующей операции может показаться странным:

Debug.Print (0.3 - 0.1 - 0.1 - 0.1) ' -2,77555756156289E-17

Ожидаемым был бы результат 0.0, но, как видно из примера, мы получили совсем другой результат. Если необходимо производить операции с фиксированной точностью, то следует использовать тип Currency:

Dim a As Currency, b As Currency, c As Currency, d As Currency
a = 0.3: b = 0.1: c = 0.1: d = 0.1
Debug.Print (a - b - c - d) ' 0

Функции для работы с числами

Для работы с числами предназначены следующие встроенные функции:

Debug.Print CByte(0)       ' Выведет: 0
Debug.Print CByte(145.8)   ' Выведет: 146
Debug.Print CByte(145.3)   ' Выведет: 145
Debug.Print CByte(145.5)   ' Выведет: 146
Debug.Print CInt(145.8)   ' Выведет: 146
Debug.Print CInt(145.3)   ' Выведет: 145
Debug.Print CInt(145.5)   ' Выведет: 146
Debug.Print CLng(145.8)   ' Выведет: 146
Debug.Print CLng(145.3)   ' Выведет: 145
Debug.Print CLng(145.5)   ' Выведет: 146
Debug.Print CSng(145)     ' Выведет: 145
Debug.Print CSng("45,5")  ' Выведет: 45,5
Debug.Print CDbl(145)     ' Выведет: 145
Debug.Print CDbl("45,5")  ' Выведет: 45,5
Debug.Print CCur(145)     ' Выведет: 145
Debug.Print CCur("45,5")  ' Выведет: 45,5
Debug.Print CDec(145)     ' Выведет: 145
Debug.Print CDec("45,5")  ' Выведет: 45,5
Debug.Print Val("str")           ' 0 (преобразовать нельзя)
Debug.Print Val("125 45.54 str") ' 12545,54
Debug.Print Val("125 45,54 str") ' 12545
Debug.Print Val("&O100")         ' 64 (восьмеричное число)
Debug.Print Val("&Hff")          ' 255 (шестнадцатеричное число)
Debug.Print Oct(7)           ' 7
Debug.Print Oct(8)           ' 10
Debug.Print Oct(64)          ' 100
Debug.Print Hex(10)          ' A
Debug.Print Hex(16)          ' 10
Debug.Print Hex(255)         ' FF
Debug.Print "'" & CStr(145) & "'"    ' Выведет: '145'
Debug.Print "'" & CStr(145.5) & "'"  ' Выведет: '145,5'
Debug.Print "'" & CStr(-145.5) & "'" ' Выведет: '-145,5'
Debug.Print "'" & str(145) & "'"     ' Выведет: ' 145'
Debug.Print "'" & str(145.5) & "'"   ' Выведет: ' 145.5'
Debug.Print "'" & str(-145.5) & "'"  ' Выведет: '-145.5'

Функция str() возвращает значение типа Variant (String). Чтобы получить значение типа String следует использовать функцию str$(), имеющую тот же самый формат. Пример:

Debug.Print "'" & str$(145) & "'"     ' Выведет: ' 145'
Debug.Print IsNumeric("10")     ' Выведет: True
Debug.Print IsNumeric("10,5")   ' Выведет: True
Debug.Print IsNumeric("10.5")   ' Выведет: False
Debug.Print IsNumeric("Строка") ' Выведет: False

Математические функции

Перечислим основные математические функции:

Debug.Print 4 * Atn(1)          ' 3,14159265358979
Debug.Print Sqr(100); Sqr(25)   ' 10  5
Debug.Print Abs(-10); Abs(10); Abs(-12.5)   ' 10  10  12,5

Пример:

Debug.Print Sgn(5); Sgn(0); Sgn(-5)      ' 1  0 -1

Округление чисел

Для округления чисел предназначены следующие функции:

Debug.Print Fix(1.49); Fix(1.5); Fix(1.51)       ' 1  1  1
Debug.Print Fix(-1.49); Fix(-1.5); Fix(-1.51)    ' -1 -1 -1
Debug.Print Int(1.49); Int(1.5); Int(1.51)       ' 1  1  1
Debug.Print Int(-1.49); Int(-1.5); Int(-1.51)    ' -2 -2 -2

Для округления чисел можно также воспользоваться функцией CInt():

Debug.Print CInt(1.49); CInt(1.5); CInt(1.51)    ' 1  2  2
Debug.Print CInt(-1.49); CInt(-1.5); CInt(-1.51) ' -1 -2 -2

Генерация псевдослучайных чисел

Для генерации псевдослучайных чисел используются следующие функции и процедуры:

Debug.Print Rnd()      ' 0,9639515
Debug.Print Rnd()      ' 0,7691374
Debug.Print Rnd()      ' 0,1994485

Если в качестве параметра указать отрицательное значение, то будет генерироваться одно и тоже число, соответствующее значению:

Debug.Print Rnd(-2)      ' 0,7133257
Debug.Print Rnd(-2)      ' 0,7133257
Debug.Print Rnd(-2)      ' 0,7133257
Debug.Print Rnd(-3)      ' 0,9633257
Debug.Print Rnd(-3)      ' 0,9633257

Если указано значение 0, то функция возвращает последнее сгенерированное число:

Debug.Print Rnd()       ' 0,7892948
Debug.Print Rnd(0)      ' 0,7892948

Создадим генератор паролей произвольной длины (листинг 5.1). Для этого добавляем в массив arr все разрешенные символы, а далее в цикле получаем случайный элемент, сгенерировав индекс с помощью пользовательской функции Rand(), возвращающей целое число в указанном диапазоне.

Листинг 5.1. Генератор паролей

Function Rand(От As Integer, До As Integer) As Integer
   Randomize
   Rand = Int((До - От + 1) * Rnd() + От)
End Function

Function PassGen(Длина As Integer) As String
   Dim arr As Variant, s As String, i As Integer, n As Integer
   arr = Array("a", "b", "c", "d", "e", "f", "g", "h", "i", _
         "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", _
         "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", _
         "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", _
         "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", _
         "X", "Y", "Z", "1", "2", "3", "4", "5", "6", "7", _
         "8", "9", "0")
   s = ""
   n = UBound(arr)
   For i = 1 To Длина
      s = s & arr(Rand(0, n))
   Next
   PassGen = s
End Function

Sub Тест()
   Debug.Print PassGen(6)      ' KEdfSg
   Debug.Print PassGen(8)      ' nwkV786b
   Debug.Print PassGen(10)     ' CLTtJI260Z
End Sub
Предыдущая статья Все статьи Следующая статья