Обновление программной библиотеки
Давайте дополним нашу библиотеку новой функцией, которая проверяет, существует ли на диске файл с заданным именем. Эту функцию следует вызывать перед попыткой открыть файл или создать его (чтобы предотвратить случайное уничтожение существующего файла):
1. Если проект из предыдущего раздела не сохранился, создайте новый проект командой File > New Project.
2. Если модуль MyLibrary.Bas не был включен в проект, щелкните правой кнопкой мыши в окне проекта и выполните команду Add > Module из контекстного меню.
3. В диалоговом окне Add Module перейдите на вкладку Existing, найдите файл MyLibrary.Bas и нажмите кнопку Open. Программный модуль включается в проект.
4. Дважды щелкните на файле MyLibrary.Bas в окне проекта. В открывшемся окне программы вставьте следующий фрагмент в секцию (Genera)(Declarations):
Public Function IsFile(FileName As String) As Boolean
If Len(Dir(Filename)) > 0 Then
‘Файл существует
IsFile = True
Else
‘Файл не существует
IsFile = False
End If
End Function
5. Сохраните библиотеку командой File > Save MyLibrary. Вся основная работа выполняется в строке
If Len(Dir(Filename)) > 0 Then
В ней вызываются еще две функции, которые формируют одно итоговое значение. Функция Dir() получает один параметр — Filename. Она проверяет, существуют ли файлы, соответствующие заданному критерию (например, *. txt), и возвращает первый подходящий файл, если он существует. Например, если в папке Мои документы существует файл FooBar.txt и переменной Filename будет присвоено значение С:\Мои документы\FооВаг.txt, функция возвращает текстовую строку FooBar, txt. Если файл не существует, Dir() возвращает пустую строку. После функции Dir() вызывается функция Len(). Она возвращает длину строки, переданной ей в качестве аргумента. Например, функция Len("abc") возвращает значение 3, потому что строка abc состоит из трех байтов. Поскольку Diг() возвращает имя файла, соответствующего переданному критерию, цепочка Len(Dir()) эквивалентна вызову Len("FooBar. txt"), который возвращает значение 10. Наконец, мы проверяем, возвратила ли функция Len() положительное число. Длина FooBar. txt равна 10; несомненно, это число больше нуля, поэтому переменной IsFile присваивается значение True — оно показывает, что файл действительно существует. Если Dir() вернет пустую строку, функция Len() возвращает 0. Это число не является положительным, поэтому IsFile присваивается значение False -следовательно, файл не существует.
ПОДСКАЗКАФункция, в которой скрывается более сложный код, называется оболочкой. Функции-оболочки играют важную роль в программировании и часто используются для упрощения вызова функций API. Дополнительные сведения приведены в уроке 19, «Использование DLL и Windows API».
Первый модуль готов, и теперь вы можете включать его в свои проекты для выполнения некоторых простых задач. Функция IsFile проверяет, существует ли на жестком диске файл с заданным именем. Подобную проверку следует выполнять перед попыткой открытия файла в программе. От вас требуется лишь указать, какой файл вас интересует:
If IsFile("C:\CONFIG.SYS") Then
... действия вашей программы ...
End If
Передача параметров
Чтобы процедура работала с различными исходными данными, ей можно передавать параметры, которые также иногда называются аргументами. Передача параметров функциям имеет очевидный смысл: вы хотите, чтобы функция выполняла одни и те же действия с разными данными. Сказанное относится и к процедурам, за одним исключением: процедура не возвращает значения. Одну и ту же процедуру можно вызывать снова и снова, что становится первым шагом на пути к повторному использованию кода.
Чтобы лучше понять, как работает этот механизм, представьте себе соковыжималку. Все, что она умеет делать, — выжимать сок из фруктов и овощей. Положите в нее морковку, и вы получите морковный сок. Положите апельсин — и получит-
ся апельсиновый сок. Замените соковыжималку некоторой функцией, «положите» в нее некоторый параметр, и вы получите соответствующий тип сока, то есть результат.
Любую процедуру или функцию следует свести к выполнению конкретной задачи. Эта задача может состоять из нескольких подзадач, но все они работают вместе и дают общий результат. Например, следующая процедура изменяет свойство формы Caption:
1. Создайте новый проект типа Standard EXE.
2. Поместите кнопку на форму Form"). Задайте ее свойству Name значение cmdCaption, а свойству Caption — значение Изменить заголовок.
Private Sub AlterCaption(X As String)
Caption = X
End Sub
Примерный вид окна программы показан на следующем рисунке.
Рис. 4.7. Окно приложения-примера
Процедуре передается всего один аргумент — X. Его имя не имеет никакого значения, однако процедура будет правильно работать лишь в том случае, если ей будет передано строковое (текстовое) значение. Например, вы можете создать строковую переменную с именем MyTitleText и присвоить ей значение Новый заголовок, после чего передать MyTitleText в качестве параметра процедуры. Другими словами, процедуре можно передать имя строковой переменной или обычный текст, заключенный в кавычки (строковую константу).
Чтобы вызвать процедуру (скажем, из процедуры события Click кнопки), попробуйте ввести следующий фрагмент (см. окно программы на следующем рисунке):
Текст после имени процедуры образует строковую константу — обратите внимание на окружающие кавычки. Строковая константа и является параметром, который ставится в соответствие аргументу X. Передача строковой переменной может быть продемонстрирована на следующем примере (см. окно программы далее):
Как видите, на этот раз кавычки не используются. Также следует обратить внимание на отсутствие скобок вокруг параметра (хотя аргумент, которому он передается, заключен в скобки). Ваша форма должна быть похожа на рис. 4.8.
Рис. 4.8. Изменение свойства Caption в программе
Параметры, передаваемые функциям, должны заключаться в скобки. Параметры процедур в скобки не заключаются. Кроме того, если передается несколько параметров, их следует разделять запятыми. Например, у вас имеется процедура CreateUser, которая получает два параметра — имя пользователя и пароль. Ее вызов в программе может выглядеть следующим образом:
CreateUser "Джон Доу", "123456"
Или
Dim UserlD As String
Dim Password As String
UserlD = "Джон Доу"
Password = "123456"
CreateUser UserID, Password
Как видите, код обоих примеров выглядит очень просто. В первом случае нужные значения параметров передаются процедуре напрямую — это называется «жесткое кодирование». Хотя этот вариант возможен, при создании нескольких пользователей в программе появится много лишних строк. Альтернативный вариант — использовать переменные, присвоить им нужные значения и один раз вызвать процедуру (как это сделано во втором примере).
Кроме того, можно создать специальную функцию, которая будет проверять комбинацию имени и пароля пользователя и возвращать значение, определяющее правильность данных. Например, это может выглядеть так:
Dim UserlD As String
Dim Password As String
UserlD = "Джон Доу"
Password = "123456"
If ValidUser(UserID, Password) = True Then
‘Сделать что-то полезное
Else
‘Вывести сообщение об ошибке
End If
Обратите внимание на то, что параметры заключены в скобку и разделены запятыми. Количество параметров определяется при объявлении функции. Одни функции вызываются с несколькими параметрами, другие — вообще без параметров.
Ключевое слово Optional
При определении функции можно указать, что некоторые из передаваемых параметров являются необязательными. Для этого перед определением параметра ставится ключевое слово Optional:
Public Function CreateUser (UserlD As String, Password As String, _
Optional Description As String) As Boolean
Третий параметр, Description, необязателен. При желании функции CreateUser можно передать описание пользователя, но функция будет работать и без него. Единственное, о чем следует помнить при объявлении необязательных параметров, -все последующие аргументы тоже должны быть необязательными и объявляться с ключевым словом Optional.
Перед именем объявляемого параметра могут указываться еще три префикса —
ByRef, ByVal и ParamArray.
Ключевое слово ByRef
Префикс ByRef означает, что параметр передается по ссылке (по умолчанию в Visual Basic используется именно такой способ передачи). Когда переменная передается по ссылке, функция или процедура получает ее адрес в памяти и может изменить фактическое значение переменной. Передача по ссылке позволяет передать или получить несколько результатов при одном вызове функции. Синтаксис выглядит следующим образом:
Function FunctionName(ByRef AVariable As String) As Boolean
или
Function FunctionName(AVariable As String) As Boolean
ПОДСКАЗКАПоскольку передача по ссылке используется по умолчанию, указывать ключевое слово ByRef в объявлении ваших собственных функций необязательно. Тем не менее это ключевое слово довольно часто используется при работе с DLL
Ключевое слово ByVal
Префикс ByVal говорит о том, что параметр передается по значению. В этом случае Visual Basic передает копию текущего содержимого переменной вместо ее адреса в памяти, и функция или процедура не сможет напрямую модифицировать исходное значение. Синтаксис выглядит следующим образом:
Function FunctionName(ByVal AVariable As String) As Boolean
Ключевое слово ParamArray
Ключевое слово ParamArray позволяет передать функции неопределенное количество параметров. Например, с его помощью можно передать функции CreateUser сведения о произвольном количестве пользователей. Одно из требований, связанных с ключевым словом ParamArray, состоит в том, что передаваемый массив данных должен иметь тип Variant. Объявление функции должно иметь следующий синтаксис:
Function FunctionName(ParamArray AnArray() As Variant) As Boolean
В этом случае функция может вызываться так:
Dim rc As Boolean
rс = FunctionName("Джон", "Джейн", "Джим", "Дженни")
rс = FunctionName("Джеймс")
rс = FunctionName("Джерри", "Джеки")
Обратите внимание: такую функцию можно вызывать с любым количеством параметров, вам не придется включать в программу несколько отдельных вызовов. Ключевое слово ParamArray делает функции более универсальными, но за это приходится расплачиваться скоростью выполнения программы: данные типа Variant обрабатываются медленнее, чем другие типы Visual Basic.