Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ОСНОВЫ ОФИСНОГО ПРОГРАММИРОВАНИЯ И ЯЗЫК VBA - 2....doc
Скачиваний:
78
Добавлен:
17.12.2018
Размер:
1.62 Mб
Скачать

Void функции языка c

В языке С формально нет процедур, есть только функции. В тех случаях, когда по существу речь идет о процедурах, вычисляющих не один скалярный результат, а имеющих несколько выходных параметров, как правило, используется функция, результат которой говорит об успешности выполнения процедуры. Если результат функции имеет значение True, то все выходные параметры благополучно вычислены, в противном случае следует проанализировать причину неуспеха. Типично для языка C то, что вызов функций является условием оператора If, - оператор If задает упаковку вызова функции, позволяя не только вызвать функцию, но и проверить корректность завершения ее работы. При трансляции заголовков таких функций в язык VBA, они естественно транслируются в функции VBA и для работы с ними можно сохранить стиль языка C.

Однако в языке C используются и функции, не возвращающие результата. Результат таких функций задается описателем Void, по существу, они являются процедурами. И при трансляции их в VBA их и следует задавать в виде процедур.

Вызов аргументов по ссылке ByRef и по значению ByVal

В языке C++ основным способом передачи параметров является передача их по значению, в VBA - по ссылке. Конечно, в обоих языках применяются оба способа. Тем не менее, нужно понимать, что описатель ByVal очень часто будет встречаться при вызове Win32 API функций, значительно чаще, чем при вызове обычных VBA функций. Если используется API Viewer, то этот описатель автоматически будет появляться для тех параметров, где необходима подобная форма вызова. Следует обратить внимание на одно обстоятельство. Несмотря на то, что такой описатель может появляться и для строковых аргументов, строки всегда передаются в функции Win32 API по ссылке. Последнее обстоятельство также связано со спецификой работы со строками в функциях языка C, на которых следует остановиться подробнее.

Строковые аргументы при вызове функций Win32 api

Как мы уже говорили, строки передаются по ссылке, даже если у параметра указан описатель ByVal. Не возникает никаких проблем при передаче строки в функцию Win32 API. Передаваемый аргумент может быть произвольным строковым выражением, в том числе переменной типа String или строковой константой. Сложнее дело обстоит, если функция должна вернуть строку, в качестве результата. Прежде всего, напомним, что в функциях Win32 API тип возвращаемого значения никогда не является строкой, - это всегда целочисленное значение, чаще всего булево значение, указывающее на то, удачно ли завершилось выполнение функции. Поэтому, если нужно получить строку в качестве результата, то функции передается два параметра - строка и ее длина, описанные чаще всего следующим образом:

ByVal lpResultStr As String, ByVal LenResultString As Long

Поскольку результат будет формироваться непосредственно в области памяти, отведенной строке lpResultStr, то перед вызовом эта строка должна удовлетворять следующим условиям:

  • она должна быть строкой, завершаемой нулем. Чаще всего она вся состоит из нулевых символов.

  • Ее длина должна быть достаточной для того, чтобы вместить результирующую строку.

  • Параметр LenResultString должен указывать максимально допустимое число символов результирующей строки.

С учетом этих требований перед вызовом функций, возвращающих строковые значения, как правило, передаваемая функции строка инициализируется и набивается подходящим количеством нулевых символов. Напомним, нулевой символ задается константой vbNullChar. Обычно, это делается следующим образом:

Const MaxSize = 255 As Long

lpResultString = String$(MaxSize, vbNullChar)

LenResultString = Len(lpResultString)

После того, как функция благополучно завершит работу, приходится выделять из строки возвращенное значение. Если строка до вызова состояла сплошь из нулевых символов, то результат после вызова представляет ее префикс, заканчивающийся первым нулевым значением. В этом случае результат легко выделяется и это причина того, почему целесообразно строку инициализировать нулевыми символами.

Тип Any

Иногда, параметр функции API может принимать значения различных типов. В этом случае в операторе Declare нельзя указать один конкретный тип этого параметра. Для решения подобной проблемы и был введен специальный тип Any. Если параметр имеет этот тип, то в период трансляции не проверяется правильность соответствия типов и аргумент может принимать значения любых типов. Конечно, нужно иметь в виду, что функция может принимать значения хоть и нескольких, но совершенно определенных типов. Поэтому при работе с типом Any на программиста возлагается вся ответственность за корректную передачу значения функции API. Альтернативой применения типа Any является задание для одной функции нескольких операторов Declare, - по одному на каждый возможный тип параметра. Тогда в каждой конкретной ситуации будет вызываться соответствующая функция с нужным типом параметра.