Vba функции вызов: Оператор Function (VBA) | Microsoft Learn

Различие в вызовах функций WinAPI в зависимости от версий Windows и Office


Поскольку в приложениях Office 2010 встроен другой VBA (VBA7), в отличие от ранних версий Excel, требуется предусмотреть в коде макросов различных варианты вызова API-функций Windows, чтобы они сохранили свою работоспособность при работе в любой версии Office.

Кроме того, в 64-битных Windows синтаксис вызова функций WinAPI тоже немного отличается от 32-битных систем.

В общем случае, код, корректно работающий в 64-битной Windows, будет выглядеть примерно так:

#If Win64 Then
    Declare Function MyMathFunc Lib "User32" (ByVal N As LongLong) As LongLong
#Else
    Declare Function MyMathFunc Lib "User32" (ByVal N As Long) As Long
#End If

А это код, который не будет выдавать ошибку при работе в Office 2010:

#If VBA7 Then
    Declare PtrSafe Sub MessageBeep Lib "User32" (ByVal N AS Long)
#Else
    Declare Sub MessageBeep Lib "User32" (ByVal N As Long)
#End If

Как же добиться работоспособности кода на любом компьютере?

А вот как: добавляйте описания функций WinAPI для всех возможных конфигураций. Например, ниже приведён универсальный код для вызова WinAPI функции URLDownloadToFile:

#If Win64 Then
    #If VBA7 Then    ' Windows x64, Office 2010
        Declare PtrSafe Function URLDownloadToFile Lib "urlmon" Alias "URLDownloadToFileA" _
                (ByVal pCaller As LongLong, ByVal szURL As String, ByVal szFileName As String, _
                 ByVal dwReserved As LongLong, ByVal lpfnCB As LongLong) As LongLong
    #Else    ' Windows x64,Office 2003-2007
        Declare Function URLDownloadToFile Lib "urlmon" Alias "URLDownloadToFileA" _
                                           (ByVal pCaller As LongLong, ByVal szURL As String, ByVal szFileName As String, _
                                            ByVal dwReserved As LongLong, ByVal lpfnCB As LongLong) As LongLong
    #End If
#Else
    #If VBA7 Then    ' Windows x86, Office 2010
        Declare PtrSafe Function URLDownloadToFile Lib "urlmon" Alias "URLDownloadToFileA" _
                (ByVal pCaller As Long, ByVal szURL As String, ByVal szFileName As String, _
                 ByVal dwReserved As Long, ByVal lpfnCB As Long) As Long
    #Else    ' Windows x86, Office 2003-2007
        Declare Function URLDownloadToFile Lib "urlmon" Alias "URLDownloadToFileA" _
                                           (ByVal pCaller As Long, ByVal szURL As String, ByVal szFileName As String, _
                                            ByVal dwReserved As Long, ByVal lpfnCB As Long) As Long
    #End If
#End If

Более подробно тема описана на сайте Microsoft

Ещё один пример — универсальная декларация функции GetTickCount:

#If Win64 Then
    #If VBA7 Then    ' Windows x64, Office 2010
        Declare PtrSafe Function GetTickCount Lib "Kernel32" () As LongLong
    #Else    ' Windows x64,Office 2003-2007
        Declare Function GetTickCount Lib "Kernel32" () As LongLong
    #End If
#Else
    #If VBA7 Then    ' Windows x86, Office 2010
        Declare PtrSafe Function GetTickCount Lib "Kernel32" () As Long
    #Else    ' Windows x86, Office 2003-2007
        Declare Function GetTickCount Lib "Kernel32" () As Long
    #End If
#End If

(добавлено позже)


Вообще, код достаточно писать в 2 вариантах (ветку Win64 не обязательно прописывать)

Для функций GetKeyState и Sleep, код будет выглядеть так:
(чтобы работало во всех версиях Office и Windows)

#If VBA7 Then    '  Office 2010
    Declare PtrSafe Function GetKeyState Lib "user32" (ByVal nVirtKey As Long) As Integer
    Declare PtrSafe Sub Sleep Lib "Kernel32" (ByVal dwMilliseconds As Long)
#Else    '  Office 2003-2007
    Declare Function GetKeyState Lib "user32" (ByVal nVirtKey As Long) As Integer
    Declare Sub Sleep Lib "Kernel32" (ByVal dwMilliseconds As Long)
#End If

—————-
(добавлено ещё позже)

Ну а ещё правильнее будет написать так:
(c использованием LongPtr для версий Office, начиная с 2010)

#If VBA7 Then    '  Office 2010-2013
    Declare PtrSafe Function Beep Lib "kernel32" (ByVal dwFreq As LongPtr, ByVal dwDuration As LongPtr) As LongPtr
#Else    '  Office 2003-2007
    Declare Function Beep Lib "kernel32" (ByVal dwFreq As Long, ByVal dwDuration As Long) As Long
#End If

Основы офисного программирования и язык VBA

Главная / Офисные технологии /
Основы офисного программирования и язык VBA / Тест 9

Упражнение 1:


Номер 1

По каким признакам можно классифицировать процедуры VBA?

Ответ:

&nbsp(1) по способу использования в программе&nbsp

&nbsp(2) по способу компилирования кода&nbsp

&nbsp(3) по способу запуска процедуры на выполнение&nbsp

&nbsp(4) по способу создания кода процедуры&nbsp

&nbsp(5) по месту нахождения кода процедуры в проекте&nbsp


Номер 2

По месту нахождения в проекте процедуры делятся на…

Ответ:

&nbsp(1) находящиеся в стандартных модулях&nbsp

&nbsp(2) находящиеся в модулях классов&nbsp

&nbsp(3) находящиеся в модулях функций&nbsp

&nbsp(4) находящиеся в модулях, связанными с объектами, реагирующими на события&nbsp


Номер 3

В чем состоит главное назначение процедур в языке VBA?

Ответ:

&nbsp(1) упрощение понимания программы&nbsp

&nbsp(2) изменение состояния системы документов, частью которого является изменение состояния самого программного проекта&nbsp

&nbsp(3) изменение состояния программного проекта&nbsp


Упражнение 2:


Номер 1

Как работает оператор Exit Sub в теле процедуры в VBA?

Ответ:

&nbsp(1) он означает окончание процедуры&nbsp

&nbsp(2) он приводит к немедленному завершению процедуры&nbsp

&nbsp(3) такого оператора не существует&nbsp


Номер 2

Как работает оператор End Sub в теле процедуры в VBA?

Ответ:

&nbsp(1) он означает окончание процедуры&nbsp

&nbsp(2) он приводит к немедленному завершению процедуры&nbsp

&nbsp(3) такого оператора не существует&nbsp


Номер 3

В чем состоит основное отличие процедур от функций?

Ответ:

&nbsp(1) в способе их завершения&nbsp

&nbsp(2) в способе их описания&nbsp

&nbsp(3) в способе их использования в вызывающей программе&nbsp


Упражнение 3:


Номер 1

Как называются функции, которые помимо получения значения функции изменяют значения некоторых результирующих параметров, передаваемых функции по ссылке?

Ответ:

&nbsp(1) функции с побочным эффектом &nbsp

&nbsp(2) процедуры-функции&nbsp

&nbsp(3) таких функций не существует&nbsp


Номер 2

Какие из операторов вызовут ошибку при компиляции программы?

Ответ:

&nbsp(1) MyInc (x)&nbsp

&nbsp(2) MyInc (y,z,a)&nbsp

&nbsp(3) Call MyInc (x)&nbsp

&nbsp(4) Call MyInc (y,z,a)&nbsp

&nbsp(5) Call MyInc x&nbsp

&nbsp(6) Call MyInc x,y,z&nbsp


Номер 3

Какие из операторов буду некорректно откомпилированы?

Ответ:

&nbsp(1) MyInc (x)&nbsp

&nbsp(2) MyInc (y,z,a)&nbsp

&nbsp(3) Call MyInc (x)&nbsp

&nbsp(4) Call MyInc (y,z,a)&nbsp

&nbsp(5) Call MyInc x&nbsp

&nbsp(6) Call MyInc x,y,z&nbsp


Упражнение 4:


Номер 1

Какой вызов процедуры из другой процедуры в языке VBA является корректным при компиляции?

Ответ:

&nbsp(1) с помощью оператора Call&nbsp

&nbsp(2) просто именем процедуры и перечислением ее параметров&nbsp

&nbsp(3) с помощью с аргументов, передаваемых по ссылке&nbsp


Номер 2

Какой вызов процедуры из другой процедуры в языке VBA является корректным при работе программы?

Ответ:

&nbsp(1) с помощью оператора Call&nbsp

&nbsp(2) просто именем процедуры и перечислением ее параметров&nbsp

&nbsp(3) с помощью с аргументов, передаваемых по ссылке&nbsp


Номер 3

Какой вызов функции из другой процедуры в языке VBA является корректным при работе программы?

Ответ:

&nbsp(1) с помощью оператора Call&nbsp

&nbsp(2) просто именем процедуры и перечислением ее параметров&nbsp

&nbsp(3) с помощью с аргументов, передаваемых по ссылке&nbsp


Упражнение 5:


Номер 1

Можно ли при вызове процедур или функций указывать значения аргументов в произвольном порядке?

Ответ:

&nbsp(1) да возможно&nbsp

&nbsp(2) нет, нельзя&nbsp

&nbsp(3) возможно только для процедур&nbsp

&nbsp(4) возможно только для функций&nbsp


Номер 2

Как обозначаются необязательные аргументы при объявлении функции или процедуры?

Ответ:

&nbsp(1) параметром Call&nbsp

&nbsp(2) параметром As&nbsp

&nbsp(3) параметром Optional&nbsp


Номер 3

С помощью какой функции процедура узнает передан ли ей при вызове необязательный аргумент?

Ответ:

&nbsp(1) Call&nbsp

&nbsp(2) As&nbsp

&nbsp(3) Optional&nbsp

&nbsp(4) IsMissing&nbsp

&nbsp(5) Missing&nbsp


Упражнение 6:


Номер 1

Какие встроенные функции помогают определить размерность массива в функциях использующих массивы?

Ответ:

&nbsp(1) LBound&nbsp

&nbsp(2) Bound&nbsp

&nbsp(3) UBound&nbsp

&nbsp(4) ScalarProduct&nbsp

&nbsp(5) ParamArray&nbsp


Номер 2

Какая конструкция используется, когда в процедуру следует передать только один массив?

Ответ:

&nbsp(1) LBound&nbsp

&nbsp(2) Bound&nbsp

&nbsp(3) UBound&nbsp

&nbsp(4) ScalarProduct&nbsp

&nbsp(5) ParamArray&nbsp


Номер 3

Что является преимуществом использования массива аргументов ParamArray?

Ответ:

&nbsp(1) он служит для передачи только одного массива&nbsp

&nbsp(2) передаваемые аргументы могут иметь разные типы&nbsp

&nbsp(3) возможность непосредственного перечисления элементов массива в момент вызова&nbsp


Упражнение 7:


Номер 1

В чем преимущества использования рекурсий?

Ответ:

&nbsp(1) время выполнения программы&nbsp

&nbsp(2) использование стековой памяти&nbsp

&nbsp(3) обработке данных, имеющих рекурсивную структуру&nbsp


Номер 2

В чем недостатки использования рекурсий?

Ответ:

&nbsp(1) время выполнения программы&nbsp

&nbsp(2) использование стековой памяти&nbsp

&nbsp(3) обработке данных, имеющих рекурсивную структуру&nbsp


Номер 3

Где могут находиться вызовы рекурсивной процедуры?

Ответ:

&nbsp(1) ее могут вызывать другие процедуры&nbsp

&nbsp(2) они могут непосредственно входить в ее тело&nbsp

&nbsp(3) она может вызывать себя через другие процедуры&nbsp


Упражнение 8:


Номер 1

Как называется бинарная структура, у которой каждая вершина имеет одного или двух потомков:

Ответ:

&nbsp(1) бинарный граф&nbsp

&nbsp(2) бинарное дерево&nbsp

&nbsp(3) бинарный корень&nbsp

&nbsp(4) бинарное поддерево&nbsp


Номер 2

Как называется бинарное дерево, в котором ключ каждой вершины больше ключа, хранящегося в корне левого поддерева, и меньше ключа, хранящегося в корне правого поддерева?

Ответ:

&nbsp(1) линейный список&nbsp

&nbsp(2) бинарный корень&nbsp

&nbsp(3) дерево поиска&nbsp


Номер 3

Где используются деревья поиска?

Ответ:

&nbsp(1) для поиска наилучшего пути&nbsp

&nbsp(2) для представления словарей и справочников&nbsp

&nbsp(3) в программировании при работе с данными, требующими выполнения операций поиска, сортировки, удаления и вставки&nbsp


Упражнение 9:


Номер 1

Что является недостатком деревьев поиска?

Ответ:

&nbsp(1) сложность осуществления алгоритма&nbsp

&nbsp(2) они могут быть плохо сбалансированы&nbsp

&nbsp(3) они могут иметь относительно длинные ветви&nbsp

&nbsp(4) у них нет недостатков&nbsp


Номер 2

Чем сложно удаление элемента из дерева поиска?

Ответ:

&nbsp(1) тем, что нужно поддерживать структуру дерева поиска&nbsp

&nbsp(2) при этом нужно удалять все поддеревья этого элемента&nbsp

&nbsp(3) это очень простая процедура&nbsp


Номер 3

Какие действия наиболее сложно воспроизвести по рекурсивной функции?

Ответ:

&nbsp(1) поиск текста&nbsp

&nbsp(2) поиск пути&nbsp

&nbsp(3) вычисления&nbsp


Главная / Офисные технологии /
Основы офисного программирования и язык VBA / Тест 9

excel — Как вызвать пользовательскую функцию в коде vba

Задавать вопрос

спросил

Изменено
4 года, 10 месяцев назад

Просмотрено
15 тысяч раз

Я создал публичную функцию во втором модуле под названием "значение_t" . Теперь я хочу использовать эту функцию в коде VBA для пользовательской формы, которая использует ввод из пользовательской формы.

Это функция:

 Публичная функция t_value (тета как вариант)
    Dim theta_1 как целое число, theta_2 как целое число
    Dim A как вариант, B как вариант, s как вариант
    theta_1 = Application.WorksheetFunction.Floor(theta, 5)
    theta_2 = Application.WorksheetFunction.Ceiling(theta, 5)
    А = тета - тета_1
    B = тета_2 - тета_1
    с = А / В
    т_значение = с
Конечная функция
 

Вот код, в котором я хотел бы использовать приведенную выше функцию:

 Private Sub Submit_Click()
    Dim тета как вариант, альфа как вариант, t как вариант, u как вариант
    тета = UserForm1.theta_input.Value
    альфа = UserForm1.alpha_input.Value
    t = Application.WorksheetFunction.t_value (тета)
Конец сабвуфера
 

Обычно "Application.WorksheetFunction.[функция]" работает, но в данной ситуации у меня не сработало — я подумал, что это может быть связано с тем, что я создал формулу. Было бы проще просто поместить формулу в Sub? Я беспокоился о времени выполнения. Я новичок, поэтому не совсем знаком с синтаксисом VBA.

  • Excel
  • vba
  • пользовательская форма

3

Application.WorksheetFunction — это класс, определенный в библиотеке Excel ; вы можете найти его в обозревателе объектов (F2):

Общедоступная функция в стандартном модуле — это просто функция, которую можно вызвать из ячейки рабочего листа (при условии, что она не имеет побочных эффектов ). ), так же, как и из любого места в проекте VBA рабочей книги: вы не можете написать какой-либо код VBA, который «становится членом» класса, определенного в библиотеке, на которую вы ссылаетесь.

Итак, если у вас есть функция с именем MyFunction в модуле с именем Module1 , вы можете вызвать ее следующим образом:

 foo = MyFunction(args)
 

Или так:

 foo = Module1. MyFunction(args)
 

Итак, в этом случае:

 t = t_value(theta)
 

Не проще ли просто поместить формулу в Sub?

Нет, потому что Sub не будет возвращать значение (однако вы можете передавать переменные ByRef ):

 Sub t_value (тета как вариант, ByRef t как вариант)
Dim theta_1 как целое число, theta_2 как целое число
Dim A как вариант, B как вариант, s как вариант
theta_1 = Application.WorksheetFunction.Floor(theta, 5)
theta_2 = Application.WorksheetFunction.Ceiling(theta, 5)
А = тета - тета_1
B = тета_2 - тета_1
с = А / В
t = s '## Присвоить значение переменной ByRef 't', и она должна сохранить свое значение в вызывающей процедуре
Конец сабвуфера
 

Если вы решите поместить эту функцию в модуль ( Public ) или в модуле пользовательской формы — это конструктивное решение, которое зависит от того, хотите ли вы, чтобы функция была общедоступной за пределами экземпляра(ов) формы. Независимо от того, решите ли вы сделать эту функцию sub , это немного другое — я бы, вероятно, рекомендовал против этого, следуя общей передовой практике, согласно которой функции должны возвращать значения, а подпрограммы должны просто выполнять действия и/или манипулировать объектами.

1

Прямое использование

t = t_value (тета)

, вместо

t = Application.WorksheetFunction.t_value (тета)

Зарегистрируйтесь или войдите в систему

Зарегистрируйтесь с помощью Google

Зарегистрироваться через Facebook

Зарегистрируйтесь, используя адрес электронной почты и пароль

Опубликовать как гость

Электронная почта

Требуется, но не отображается

Опубликовать как гость

Электронная почта

Требуется, но не отображается

Нажимая «Опубликовать свой ответ», вы соглашаетесь с нашими условиями обслуживания и подтверждаете, что прочитали и поняли нашу политику конфиденциальности и кодекс поведения.

excel — Как вызвать функцию внутри другой функции в VBA?

спросил

Изменено
1 год, 4 месяца назад

Просмотрено
513 раз

Я пытаюсь вызвать функцию внутри другой функции, но получаю результат 0

 Функция DepositRate(Депозит):
    Если Депозит > 100000 Тогда
        Ртакса = 0,078
    ИначеЕсли Депозит <= 100000 И Депозит > 10000 Тогда
        Ртакса = 0,073
    ИначеЕсли Депозит <= 10000 И Депозит > 1000 Тогда
        Ртакса = 0,063
    ИначеЕсли Депозит <= 1000 И Депозит > 0 Тогда
        Ртакса = 0,055
    Еще
        Rtaxa = "Отрицательное значение"
    Конец, если
    
    Депозитная ставка = Rtaxa
        
Конечная функция
Функция NewDFV (значение, год):
    Вызов DepositRate(значение)
    ValorFuturo = Депозит * (1 + Rtaxa) ^ (Год)
    NewDFV = ValorFuturo
    
Конечная функция
 

Итак, что я делаю не так?

  • excel
  • vba

Функция, вызывающая функцию

  • Обратите внимание, что обе функции могут использоваться как пользовательские функции.