из-за большого объема оперативной памяти на современных компьютерах.
Тип данных Variant отличается еще и тем, что переменные с таким типом автоматически могут преобразовываться в нужный другой тип, например, если переменная "х" имеет тип Variant и значение 2 (число), то после команды "x=Str(x)", которая преобразует число в строку, она уже будет иметь значение "2", то есть текстовая строка с цифрой "2". Такое преобразование было бы невозможно, если бы переменная "х" была объявлена как Integer.
Может показаться, что определять все переменные как тип Variant или вообще не включать в модуль раздел описаний является очень хорошим решением, однако стоит помнить, что необъявленные переменные не могут быть использованы в других модулях или формах, а, кроме того, переменные типа Variant занимают очень много места в оперативной памяти. Можно запретить для себя использование необъявленных переменных, вставив в начало модуля, в верх раздела описаний инструкцию Option Explicit, и тогда программа остановится и перейдет в режим отладки, если вдруг наткнется на такую переменную.
Стоит быть внимательнее с типами данных, так как в некоторых случаях неправильное их использование может дать ошибку. Например, переменная с типом Integer не может превысить значение 32 767; если же надо использовать большие числа, то следует определить ее тип как Long, а если она может быть еще и дробной, то — Double.
Процедуры и функции
В принципе любая программа для каждого конкретного случая может быть написана в виде одного длинного блока текста. Однако такой код будет крайне нерациональным. Например, в программе необходимо несколько раз подсчитать сумму всех членов арифметической прогрессии для разных чисел. Можно, конечно, считать результат каждый раз по известной формуле, но это очень усложнит код. А если неизвестно, для какого количества чисел надо считать эту сумму (например, это определяет пользователь), то написание программы становится почти невозможным. Поэтому в VBA, как и в других современных языках программирования, есть понятие процедур и функций, иначе называемых подпрограммами.
Процедура — это программа, которая может быть вызвана из другой программы и при этом получить для дальнейшей обработки определенную информацию. Например, можно написать процедуру для вычисления суммы всех членов арифметической прогрессии и помещения результата в текст активного документа, и вызывать ее всякий раз, когда надо подсчитать такую сумму, передавая процедуре число, для которого такая сумма считается.
Можно сказать, что программа, не использующая вызов процедур, состоит из одной большой процедуры.
Функция же — это программа, которая не только получает из другой программы какую-нибудь информацию, но и возвращает той программе определенное значение, которое может быть ею в дальнейшем использовано.
В VBA любая процедура, получающая данные из другой программы, имеет следующий формат:
Sub "Название процедуры"("Получаемая переменная" As "Тип данных получаемой переменной")
"Текст процедуры"
End Sub
Получаемых переменных может быть несколько. Для каждой из них желательно указать ее тип, но это можно опустить.
Вызов процедуры происходит так же, как и вызов любой команды VBA, — путем указания ее названия и передаче ей соответствующих значений переменных, указываемых после имени процедуры в команде ее вызова, как, например, в этой программе:
Sub Main()
Dim a As Integer
a = 1
uvelich a, 3
MsgBox a
End Sub
Sub uvelich(b As Integer, с As Integer)
b = b + с
End Sub
Здесь из процедуры Main вызывается процедура uvelich, которой передаются два параметра — а (равный 1) и второй — число 3. Процедура uvelich увеличивает первую переданную переменную на значение второго переданного числа, а затем Main отображает результат.
Стоит помнить, что если в заглавии процедуры указываются типы данных переменных, то и в вызывающей процедуре передаваемые значения должны быть определены и иметь тот же самый тип, иначе VBA выдаст сообщение об ошибке[2].
Переменные могут передаваться в процедуру двумя способами — только для чтения или и для изменения. По умолчанию переменные могут в функции изменяться. Как, скажем, в вышеприведенном примере — переменная "а" была передана в процедуру (под именем "Ь", чтобы лучше проиллюстрировать этот момент) и там изменилась (к ней прибавили величину переменной "с"), и затем в исходной программе она тоже стала иметь новое измененное значение.
Если же не нужно, чтобы переменная в процедуре менялась (скажем, процедура использует переменную для каких-то своих нужд, не связанных с исходной программой), то перед именем этой переменной в заголовке процедуры следует поместить инструкцию ByVal. Тогда процедура просто использует переменную так, как в этой процедуре описано, возможно, изменив ее значение, а программа, вызвавшая процедуру, дальше будет работать с прежним значением переменной.
К примеру, если бы заголовок процедуры uvelich в вышеприведенном примере имел вид Sub uvelich(ByVal b As Integer, с As Integer), то никакого увеличения переменной "а" не произошло бы и программа отобразила бы в качестве результата число 1. Однако в самой процедуре uvelich соответствующая переменная увеличилась бы на 3 и, если бы последняя ее команда была бы MsgBox b, то она отобразила бы значение 4.
Функция отличается от процедуры тем, что она передает в вызвавшую ее программу определенное значение, которое может быть использовано в дальнейшей работе программы. В частности, при использовании функции вышеприведенный пример мог бы иметь такой вид:
Sub Main()
Dim a As Integer
Dim d As Integer
a = 1
d = uvelich(a, 3)
MsgBox d
End Sub
Function uvelich(ByVal b As Integer, ByVal с As Integer) As Integer
uvelich = b + с
End Function
Как нетрудно видеть, программа присваивает переменной "d" значение, вычисленное функцией.
При создании функций опять-таки следует помнить, что если в заголовке функции не указана инструкция ByVal перед описаниями переменных, то соответствующие переменные могут быть в функции изменены и после ее выполнения в исходной программе они будут иметь уже измененные значения. Так, если бы данный пример имел вид
Sub Main ()
Dim a As Integer
Dim d As Integer
a = 1
d = uvelich(a, 3)
MsgBox d
MsgBox a
End Sub
Function uvelich(b As Integer, с As Integer) As Integer
uvelich = b + с
b = 1555