В этом примере из процедуры Main вызывается процедура uvelich, которой передаются два параметра — а (равное 1) и второй — число 3. Процедура uvelich увеличивает первую переданную переменную на значение второго переданного числа, а затем Main отображает результат вычислений. Стоит помнить, что если в заглавии процедуры указываются типы данных переменных, то и в вызывающей процедуре передаваемые значения должны быть определены и иметь тот же тип, иначе Visual Basic for Applications выдаст сообщение об ошибке[229]
.Переменные могут передаваться в процедуру двумя способами — только для чтения или и для изменения. По умолчанию переменные могут в функции изменяться. Как, скажем, в вышеприведенном примере — переменная "а" была передана в процедуру (под именем "Ь", чтобы лучше проиллюстрировать этот момент) и там изменилась (к ней прибавили величину переменной "с"), и затем в исходной программе она тоже стала иметь новое измененное значение.
Если же не нужно, чтобы переменная в процедуре менялась (скажем, процедура использует переменную для каких-то своих нужд, не связанных с исходной программой), то перед именем этой переменной в заголовке процедуры следует поместить инструкцию 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 + с
a=1555
End Function,
то исходная программа — Main в качестве значения переменной "а" отобразила бы число 1555, а не 1.
Указания типов переменных в заголовке функции или процедуры необязательны — их можно опустить. Однако если типы переменных определены в этом заголовке, то они обязательно должны быть определены точно такими же типами и в вызывающей программе, если только они не определяются в функции или процедуре как Variant. Иными словами, если в функцию или процедуру передается переменная типа Integer, то в вызове функции или процедуры можно использовать только переменные именно этого типа, в противном случае возникнет ошибка. Так, если в заголовке функции указано, что первая переменная, передаваемая ей, имеет тип Integer, то та переменная, которая передается в функцию как первая (в последнем примере — "а"), должна быть определена именно как Integer до вызова функции (что мы и видим в этом примере). Если же в вышеприведенной программе переменная "а" определялась бы как Byte или Long, то возникла бы ошибка.
Перед заголовком функции или процедуры можно поставить инструкции Public или Private (для вышеприведенного примера — "Private Function uvelich(b As Integer, с As Integer) As Integer"). Функция или процедура, объявленная как Public, может вызываться и из других модулей, в то время как функция или процедура, объявленная как Private, доступна только из данного модуля.
По умолчанию все функции и процедуры считаются объявленными как Public (а переменные, как нетрудно заметить — объявленные как Private).
Если в программе есть вложенные процедуры или функции (то есть процедура или функция вызывает другую процедуру или функцию, которая, в свою очередь, вызывает еще одну процедуру или функцию и.т.д.), то их взаимоотношения ("кто кого вызывает?") удобно при отладке отслеживать с помощью окна Стек Вызова (рис. 4.5), в котором видны все произошедшие вызовы.
Рис. 4.5.
В выпадающем меню в правом верхнем углу окна программы указаны все процедуры и функции данного модуля. Это меню можно использовать для быстрого перехода к необходимому месту модуля.