В этой главе вы научитесь:
• разбираться в разновидностях подпрограмм,
• создавать собственные подпрограммы,
• использовать встроенные процедуры и функции.
В предыдущей главе мы познакомились с возможностью изменения последовательности операторов программы с помощью условных инструкций и циклов. Сюда же можно отнести и инструкции вызова процедур.
Процедурой (Procedure) в языке Visual Basic называется именованная часть программы, которая вызывается, выполняет определенные действия и возвращает управление в строку, следующую за точку вызова.
Различают следующие основные разновидности процедур:
• обработки событий,
• общего назначения,
• встроенные.
Процедуры обработки событий (Event Procedures) вызываются самим Visual Basic, когда происходят определенные события, связанные с элементами управления. В главе 2 мы уже составляли текст таких процедур, занимающихся обработкой события Click (Щелчок) кнопок cmdHello и cmdExit.
Процедуры общего назначения (General Procedures) не привязаны ни к каким событиям или объектам. Необходимость в их написании возникает, когда в разных частях программы приходится использовать одну и ту же последовательность операторов. Тогда пишется одна процедура общего назначения, а в нужных точках программы вставляются инструкции вызова этой процедуры. Использование процедур общего назначения улучшает читаемость текста программы, а также уменьшает число ошибок.
Встроенные процедуры (Built-In Procedures) поставляются уже готовыми в комплекте Visual Basic. Они выполняют все наиболее часто требуемые операции, но их внутренняя структура скрыта от программиста. Встроенные процедуры вызываются из основной программы так же, как и процедуры общего назначения. Методы и свойства стандартных объектов, также являются встроенными процедурами, однако они могут использоваться только применительно к этим объектам.
Обобщенный синтаксис инструкции вызова процедуры (Procedure Call) выглядит следующим образом:
имя_процедуры [(список_аргументов)]
Аргументы (Arguments), иначе именуемые параметрами (Parameters), представляют собой выражения, значения которых используются в процедуре и влияют на результаты ее работы. Процедуры, не требующие входных параметров, вызываются без аргументов.
Особенности использования процедур в программе зависит еще и от того, возвращают ли они какие-нибудь значения или нет. По этому признаку все процедуры делятся на две разновидности:
• Sub (Подпрограмма) – не возвращающие значения,
• Function (Функция) – возвращающие значения.
Инструкции вызова процедур Sub (Подпрограмма) пишутся отдельной строкой. Вызов Function (Функция) обязательно должен находиться на месте одного из параметров оператора языка Visual Basic или аргумента другой процедуры, где обычно может располагаться выражение.
Основное различие в синтаксисе вызова процедур различных видов заключается в том, что перечень аргументов процедуры Sub (Подпрограмма) приводится без скобок, а у Function (Функция) – он заключен в круглые скобки.
Примеры вызовов процедур различного типа:
MySub 5, varX +3, varY / varX
Form1.Caption = Now ()
Первой строкой вызывается процедура общего назначения MySub, которой передается три параметра. Во второй строке полученное значение встроенной функции Now без параметров, возвращающей текущую системную дату и время, присваивается свойству Caption (Заголовок) формы Form1.
А теперь перейдем к более подробному рассмотрению процедур общего назначения, которым посвящена данная глава.
Процедура Sub (Подпрограмма) представляет собой последовательность операторов языка Visual Basic, выполняющая определенные действия, не возвращающая значений. Синтаксис объявления подпрограммы следующий:
[{Private|Public}] [Static] Sub имя ([список_аргументов])
[инструкции]
[Exit Sub]
[инструкции]
End Sub
Ключевое слово Private (Частная) указывает на то, что данная процедура видна только внутри текущего модуля, а Public (Общая) делает ее общедоступной.
Другое ключевое слово Static (Постоянный) информирует Visual Basic о необходимости сохранения значений внутренних переменных между вызовами процедуры, хотя от этого они и не становятся видимыми для других подпрограмм.
Процедура Sub (Подпрограмма) может получать входные данные – аргументы, которые перечисляются в круглых скобках. Если аргументы отсутствуют, круглые скобки должны оставаться пустыми.
Необязательная в использовании инструкция Exit Sub (Выход из подпрограммы) позволяет досрочно завершить работу процедуры в тех случаях, когда это вам бывает необходимо.
Пример определения общедоступной процедуры Sub (Подпрограмма) общего назначения, которая выдает нужное количество гудков:
Public Sub Trill (intCount As Integer) ‘ начало процедуры
If intCount <1 Then Exit Sub ‘ если intCount <1, то выходим
For i = 1 To intCount ‘ цикл For… Next от 1 до intCount
Beep ‘ подача звукового сигнала из динамика компьютера
Next ‘ переходим к следующей итерации цикла For… Next
End Sub
В данной процедуре, кроме обычных операторов и инструкций языка Visual Basic были использованы комментарии, представляющие собой текст, поясняющий код программы.
Чтобы Visual Basic не воспринимал комментарии в качестве неверного кода, перед ними ставится символ «‘» или инструкция Rem. Когда Visual Basic встречает признак комментария, он игнорирует остальные символы до конца текущей строки.
Теперь в коде любой другой процедуры данной формы можно осуществлять вызов процедуры Trill с аргументом – количеством гудков:
Trill 10
Чтобы процедуру можно было вызывать извне текущего программного модуля, при ее вызове требуется дополнительно указать имя формы или модуля, где она была определена. Например, если процедура Trill находится в форме Проба, то она вызывается аналогично методу данной формы:
Проба.Trill 10
Проиллюстрируем режим сохранения значения внутренних переменных между вызовами процедуры, благодаря использованию ключевого слова Static (Постоянный). Можно привести пример такой процедуры, которая выполняет какие-то действия только ограниченное число раз:
Public Static Sub Proc1 () ‘ процедура Proc1 без аргументов
Dim CallCount As Integer ‘ объявляем целую переменную
If CallCount> = 5 Then Exit Sub ‘ если CallCount> =5 – выход
CallCount = CallCount +1 ‘ увеличиваем переменную на 1
…далее выполняется что-то полезное…
End Sub ‘ завершение процедуры
Эта процедура подсчитывает количество своих вызовов, сохраняя его в переменной CallCount. Процедура Proc1 выполняет какие-то полезные действия только в течение первых 5-ти вызовов, а следующие работают «вхолостую».
Данный пример иллюстрирует тот факт, что значение переменной CallCount хранится в памяти компьютера между вызовами процедуры.
Объявление процедуры Function (Функция) по своему синтаксису подобно Sub (Подпрограмма). Отличия обусловлены тем, что функция возвращает значение:
[{Private|Public}] [Static] Function имя [(аргументы)] [As тип]
[инструкции]
имя = выражение
[Exit Function]
[инструкции]
End Function
После ключевого слова As (Как) может быть указан тип данных, возвращаемых функцией. Внутри тела процедуры Function (Функция) обязательно должен встретиться оператор, который присваивает значение имени функции, например:
Private Function GetValue ()
[инструкции]
GetValue = 3
[инструкции]
End Function
В языке Visual Basic определено большое количество встроенных функций, которые могут вызываться, но их внутреннее содержимое скрыто от программиста. Чтобы получить возвращаемое значение функции, указывают ее имя.
В данном примере производится преобразование числа в текстовую строку с помощью функции Str и запись ее в переменную strTemp:
Dim strTemp As String
strTemp = Str (-19.436)
Если возвращаемое значение не требуется, можно вызвать функцию так же, как и процедуру Sub. Следует опустить скобки и указать список аргументов. Например, следующая строка выводит сообщение с текущей датой и временем:
MsgBox Now ()
Здесь используются сразу две встроенные функции языка Visual Basic. MsgBox не возвращает никакого значения, а только выводит окно сообщения. Функция Now используется в качестве аргумента, возвращая дату и время.
При вызове процедур типа Sub (Подпрограмма) или Function (Функция) возможно использование двух способов передачи фактических значений аргументов:
• по ссылке (ByRef),
• по значению (ByVal).
По умолчанию параметры передаются в виде ссылок, что дает возможность процедурам изменять их значения. Если необходимо предотвратить возможные изменения аргументов процедуры, следует осуществлять их передачу по значению, для чего при объявлении процедуры перед аргументом использовать ключевое слово ByVal, например:
Sub Proc2 (ByVal Arg1)
End Sub
Кроме параметров, которые должны быть непременно указаны при вызове процедуры, встречаются и необязательные параметры. Для их обозначения при объявлении применяется ключевое слово Optional (Необязательный):
Sub Proc3 (Arg1, Optional Arg2)
End Sub
При вызове процедуры с аргументом Optional (Необязательный) можно как указывать, так и не указывать необязательный аргумент. Если аргумент не указан, то для него используется имеющееся значение по умолчанию. Если по умолчанию значение не присвоено, аргумент обрабатывается так же, как любая другая переменная соответствующего типа.
В данном случае, правильными будут оба варианта записи вызова этой процедуры:
Proc3 10, 15
Proc3 10
Обычный синтаксис вызова процедур предусматривает позиционную передачу аргументов, то есть в порядке их следования в описании процедуры. Также, возможен вызов процедур с именованными аргументами, которые могут передаваться в любом порядке.
Каждый именованный аргумент состоит из имени, за которым следует двоеточие со знаком равенства (:=) и значение аргумента.
Например, следующие три вызова процедуры Proc3 абсолютно равноценны между собой:
Proc3 10, 15
Proc3 Arg1:=10, Arg2:=15
Proc3 Arg2:=15, Arg1:=10
Первый вызов процедуры Proc3 осуществляется с применением обычных неименованных аргументов. Вторая и третья строка показывает пример использования именованных аргументов Arg1 и Arg2.