На этом шаге мы рассмотрим алгоритм описания внешних функций и процедур в модуле документа.
Для начала рассмотрим, как можно получить доступ к функциям и процедурам из стандартной динамической библиотеки и какие ограничения накладываются на них и на их аргументы и возвращаемые значения. В таких функциях можно использовать не все типы переменных - только некоторые типы данных в Excel и Delphi имеют общую структуру. Подходят следующие типы данных:
Чтобы подробней ознакомиться с данным вопросом и получить список всех возможных типов данных, используйте справку по Excel, раздел "Справочник по Visual Basic".
Определив, какими типами данных будем оперировать, попробуем описать и вызвать какую-либо функцию или процедуру из стандартной библиотеки Windows. В качестве примера можем поработать с функцией MessageBox из стандартной динамической библиотеки. Функция MessageBox использует в качестве входных и возвращаемых значений типы PChar и Integer. В макросе Excel тип PChar можно заменить типом String. Прежде чем обращаться к внешней процедуре, опишем ее.
Описание внешних процедур и функций, используемых в макросах, имеет следующий синтаксис.
Описание процедуры:
Declare Sub "имя процедуры" Lib "имя библиотеки" [Alias "псевдоним"] [(["список аргументов"])]
Declare Function "имя функции" Lib "имя библиотеки" [Alias "псевдоним"] [([ "список аргументов "]) ] [As "тип"]
Ключевые слова:
В нашем примере из рабочей книги Excel вызовем функцию MessageBox. Ссылку на эту функцию можно найти в файле WINDOWS.PAS, входящем в состав Delphi. Используем полученную информацию. Из описания, представленного в файле WINDOWS.PAS, видно, что эта функция входит в состав библиотеки USER32.DLL.
Описание ссылки на функцию MeseageBox:
interface . . . . . function MessageBoxA(hWnd:HWND;lpText,lpCaption:PAnsiChar; uType:UINT):Integer; stdcall; . . . . . implementation . . . . . function MessageBoxA; external user32 name 'MessageBoxA';
В редакторе Visual Basic создадим новый модуль с именем Module1, в котором напишем строку, определяемую следующим синтаксисом.
Declare Function MessageBoxA Lib "user32.dll" (ByVal hwnd As Integer, _ ByVal lpText As String, _ ByVal lpCaption As String, _ ByVal uType As Integer) As Integer
Рис.1. Определение функции
Представленное описание указывает на то, что мы используем функцию, возвращающую целое значение. Функция импортируется из библиотеки USER32.DLL. Имена функции в библиотеке и в макросе совпадают, но для макроса можно было бы задать и другое имя. Аргументы импортируемой функции не возвращают значения, а только передают. Для аргументов, возвращающих значения, необходимо опустить зарезервированное слово ByVal. В теле макроса напишем следующую процедуру для вызова функции MessageBox динамической библиотеки user32.dll.
Private Sub CommandButton1_Click()
Call MessageBoxA(0, "Тип объекта = " + TypeName(Selection), _
"Вызов функции MessageBox из библиотеки user32.dll", 0)
Call MessageBoxA(0, "Значение ячейки = " + Range("A1").Text, _
"Вызов функции MessageBox из библиотеки user32.dll", 0)
End Sub
Рис.2. Вызов функции
Данная процедура дважды вызывает функцию MessageBox. Первый вызов процедуры отображает значение типа выделенного объекта. Второй вызов выводит в диалоговом окне значение, записанное в ячейке А1. Выполним этот макрос и получим результат в виде диалогового окна (рисунок 3).
Рис.3. Результат выполнения макроса
На следующем шаге мы рассмотрим соглашения о вызовах.