Excel vba sub или function

Содержание

  1. Встроенные функции VBA
  2. Пользовательские процедуры «Function» и «Sub» в VBA
  3. Аргументы
  4. Необязательные аргументы
  5. Передача аргументов по значению и по ссылке
  6. VBA процедура «Function»
  7. Пример VBA процедуры «Function»: Выполняем математическую операцию с 3 числами
  8. Вызов VBA процедуры «Function»
  9. Вызов VBA процедуры «Function» из другой процедуры
  10. Вызов VBA процедуры «Function» из рабочего листа
  11. VBA процедура «Sub»
  12. VBA процедура «Sub»: Пример 1. Выравнивание по центру и изменение размера шрифта в выделенном диапазоне ячеек
  13. VBA процедура «Sub»: Пример 2. Выравнивание по центру и применение полужирного начертания к шрифту в выделенном диапазоне ячеек
  14. Вызов процедуры «Sub» в Excel VBA
  15. Вызов VBA процедуры «Sub» из другой процедуры
  16. Вызов VBA процедуры «Sub» из рабочего листа
  17. Область действия процедуры VBA
  18. Ранний выход из VBA процедур «Function» и «Sub»

Встроенные функции VBA

Перед тем, как приступить к созданию собственных функций VBA, полезно знать, что Excel VBA располагает обширной коллекцией готовых встроенных функций, которые можно использовать при написании кода.

Список этих функций можно посмотреть в редакторе VBA:

  • Откройте рабочую книгу Excel и запустите редактор VBA (нажмите для этого Alt+F11), и затем нажмите F2.
  • В выпадающем списке в верхней левой части экрана выберите библиотеку VBA.
  • Появится список встроенных классов и функций VBA. Кликните мышью по имени функции, чтобы внизу окна отобразилось её краткое описание. Нажатие F1 откроет страницу онлайн-справки по этой функции.

Кроме того, полный список встроенных функций VBA с примерами можно найти на сайте Visual Basic Developer Centre.

Пользовательские процедуры «Function» и «Sub» в VBA

В Excel Visual Basic набор команд, выполняющий определённую задачу, помещается в процедуру Function (Функция) или Sub (Подпрограмма). Главное отличие между процедурами Function и Sub состоит в том, что процедура Function возвращает результат, процедура Sub – нет.

Поэтому, если требуется выполнить действия и получить какой-то результат (например, просуммировать несколько чисел), то обычно используется процедура Function, а для того, чтобы просто выполнить какие-то действия (например, изменить форматирование группы ячеек), нужно выбрать процедуру Sub.

Аргументы

При помощи аргументов процедурам VBA могут быть переданы различные данные. Список аргументов указывается при объявлении процедуры. К примеру, процедура Sub в VBA добавляет заданное целое число (Integer) в каждую ячейку в выделенном диапазоне. Передать процедуре это число можно при помощи аргумента, вот так:

Sub AddToCells(i As Integer)

...

End Sub

Имейте в виду, что наличие аргументов для процедур Function и Sub в VBA не является обязательным. Для некоторых процедур аргументы не нужны.

Необязательные аргументы

Процедуры VBA могут иметь необязательные аргументы. Это такие аргументы, которые пользователь может указать, если захочет, а если они пропущены, то процедура использует для них заданные по умолчанию значения.

Возвращаясь к предыдущему примеру, чтобы сделать целочисленный аргумент функции необязательным, его нужно объявить вот так:

Sub AddToCells(Optional i As Integer = 0)

В таком случае целочисленный аргумент i по умолчанию будет равен 0.

Необязательных аргументов в процедуре может быть несколько, все они перечисляются в конце списка аргументов.

Передача аргументов по значению и по ссылке

Аргументы в VBA могут быть переданы процедуре двумя способами:

  • ByVal – передача аргумента по значению. Это значит, что процедуре передаётся только значение (то есть, копия аргумента), и, следовательно, любые изменения, сделанные с аргументом внутри процедуры, будут потеряны при выходе из неё.
  • ByRef – передача аргумента по ссылке. То есть процедуре передаётся фактический адрес размещения аргумента в памяти. Любые изменения, сделанные с аргументом внутри процедуры, будут сохранены при выходе из процедуры.

При помощи ключевых слов ByVal или ByRef в объявлении процедуры можно задать, каким именно способом аргумент передаётся процедуре. Ниже это показано на примерах:

Sub AddToCells(ByVal i As Integer)

...

End Sub
В этом случае целочисленный аргумент i передан по значению. После выхода из процедуры Sub все сделанные с i изменения будут утрачены.
Sub AddToCells(ByRef i As Integer)

...

End Sub
В этом случае целочисленный аргумент i передан по ссылке. После выхода из процедуры Sub все сделанные с i изменения будут сохранены в переменной, которая была передана процедуре Sub.

Помните, что аргументы в VBA по умолчанию передаются по ссылке. Иначе говоря, если не использованы ключевые слова ByVal или ByRef, то аргумент будет передан по ссылке.

Перед тем как продолжить изучение процедур Function и Sub более подробно, будет полезным ещё раз взглянуть на особенности и отличия этих двух типов процедур. Далее приведены краткие обсуждения процедур VBA Function и Sub и показаны простые примеры.

VBA процедура «Function»

Редактор VBA распознаёт процедуру Function, когда встречает группу команд, заключённую между вот такими открывающим и закрывающим операторами:

Function

...

End Function

Как упоминалось ранее, процедура Function в VBA (в отличие от Sub), возвращает значение. Для возвращаемых значений действуют следующие правила:

  • Тип данных возвращаемого значения должен быть объявлен в заголовке процедуры Function.
  • Переменная, которая содержит возвращаемое значение, должна быть названа так же, как и процедура Function. Эту переменную не нужно объявлять отдельно, так как она всегда существует как неотъемлемая часть процедуры Function.

Это отлично проиллюстрировано в следующем примере.

Пример VBA процедуры «Function»: Выполняем математическую операцию с 3 числами

Ниже приведён пример кода VBA процедуры Function, которая получает три аргумента типа Double (числа с плавающей точкой двойной точности). В результате процедура возвращает ещё одно число типа Double, равное сумме первых двух аргументов минус третий аргумент:

Function SumMinus(dNum1 As Double, dNum2 As Double, dNum3 As Double) As Double

   SumMinus = dNum1 + dNum2 - dNum3

End Function

Эта очень простая VBA процедура Function иллюстрирует, как данные передаются процедуре через аргументы. Можно увидеть, что тип данных, возвращаемых процедурой, определён как Double (об этом говорят слова As Double после списка аргументов). Также данный пример показывает, как результат процедуры Function сохраняется в переменной с именем, совпадающим с именем процедуры.

Вызов VBA процедуры «Function»

Если рассмотренная выше простая процедура Function вставлена в модуль в редакторе Visual Basic, то она может быть вызвана из других процедур VBA или использована на рабочем листе в книге Excel.

Вызов VBA процедуры «Function» из другой процедуры

Процедуру Function можно вызвать из другой VBA процедуры при помощи простого присваивания этой процедуры переменной. В следующем примере показано обращение к процедуре SumMinus, которая была определена выше.

Sub main()

   Dim total as Double
   total = SumMinus(5, 4, 3)

End Sub

Вызов VBA процедуры «Function» из рабочего листа

VBA процедуру Function можно вызвать из рабочего листа Excel таким же образом, как любую другую встроенную функцию Excel. Следовательно, созданную в предыдущем примере процедуру FunctionSumMinus можно вызвать, введя в ячейку рабочего листа вот такое выражение:

=SumMinus(10, 5, 2)

VBA процедура «Sub»

Редактор VBA понимает, что перед ним процедура Sub, когда встречает группу команд, заключённую между вот такими открывающим и закрывающим операторами:

VBA процедура «Sub»: Пример 1. Выравнивание по центру и изменение размера шрифта в выделенном диапазоне ячеек

Рассмотрим пример простой VBA процедуры Sub, задача которой – изменить форматирование выделенного диапазона ячеек. В ячейках устанавливается выравнивание по центру (и по вертикали, и по горизонтали) и размер шрифта изменяется на заданный пользователем:

Sub Format_Centered_And_Sized(Optional iFontSize As Integer = 10)

   Selection.HorizontalAlignment = xlCenter
   Selection.VerticalAlignment = xlCenter
   Selection.Font.Size = iFontSize

End Sub

Данная процедура Sub выполняет действия, но не возвращает результат.

В этом примере также использован необязательный (Optional) аргумент iFontSize. Если аргумент iFontSize не передан процедуре Sub, то его значение по умолчанию принимается равным 10. Однако же, если аргумент iFontSize передается процедуре Sub, то в выделенном диапазоне ячеек будет установлен размер шрифта, заданный пользователем.

VBA процедура «Sub»: Пример 2. Выравнивание по центру и применение полужирного начертания к шрифту в выделенном диапазоне ячеек

Следующая процедура похожа на только что рассмотренную, но на этот раз, вместо изменения размера, применяется полужирное начертание шрифта в выделенном диапазоне ячеек. Это пример процедуры Sub, которой не передаются никакие аргументы:

Sub Format_Centered_And_Bold()

   Selection.HorizontalAlignment = xlCenter
   Selection.VerticalAlignment = xlCenter
   Selection.Font.Bold = True

End Sub

Вызов процедуры «Sub» в Excel VBA

Вызов VBA процедуры «Sub» из другой процедуры

Чтобы вызвать VBA процедуру Sub из другой VBA процедуры, нужно записать ключевое слово Call, имя процедуры Sub и далее в скобках аргументы процедуры. Это показано в примере ниже:

Sub main()

   Call Format_Centered_And_Sized(20)

End Sub

Если процедура Format_Centered_And_Sized имеет более одного аргумента, то они должны быть разделены запятыми. Вот так:

Sub main()

   Call Format_Centered_And_Sized(arg1, arg2, ...)

End Sub

Вызов VBA процедуры «Sub» из рабочего листа

Процедура Sub не может быть введена непосредственно в ячейку листа Excel, как это может быть сделано с процедурой Function, потому что процедура Sub не возвращает значение. Однако, процедуры Sub, не имеющие аргументов и объявленные как Public (как будет показано далее), будут доступны для пользователей рабочего листа. Таким образом, если рассмотренные выше простые процедуры Sub вставлены в модуль в редакторе Visual Basic, то процедура Format_Centered_And_Bold будет доступна для использования на рабочем листе книги Excel, а процедура Format_Centered_And_Sized – не будет доступна, так как она имеет аргументы.

Вот простой способ запустить (или выполнить) процедуру Sub, доступную из рабочего листа:

  • Нажмите Alt+F8 (нажмите клавишу Alt и, удерживая её нажатой, нажмите клавишу F8).
  • В появившемся списке макросов выберите тот, который хотите запустить.
  • Нажмите Выполнить (Run)

Чтобы выполнять процедуру Sub быстро и легко, можно назначить для неё комбинацию клавиш. Для этого:

  • Нажмите Alt+F8.
  • В появившемся списке макросов выберите тот, которому хотите назначить сочетание клавиш.
  • Нажмите Параметры (Options) и в появившемся диалоговом окне введите сочетание клавиш.
  • Нажмите ОК и закройте диалоговое окно Макрос (Macro).

Внимание: Назначая сочетание клавиш для макроса, убедитесь, что оно не используется, как стандартное в Excel (например, Ctrl+C). Если выбрать уже существующее сочетание клавиш, то оно будет переназначено макросу, и в результате пользователь может запустить выполнение макроса случайно.

Область действия процедуры VBA

В части 2 данного самоучителя обсуждалась тема области действия переменных и констант и роль ключевых слов Public и Private. Эти ключевые слова так же можно использовать применительно к VBA процедурам:

Public Sub AddToCells(i As Integer)

...

End Sub
Если перед объявлением процедуры стоит ключевое слово Public, то данная процедура будет доступна для всех модулей в данном проекте VBA.
Private Sub AddToCells(i As Integer)

...

End Sub
Если перед объявлением процедуры стоит ключевое слово Private, то данная процедура будет доступна только для текущего модуля. Её нельзя будет вызвать, находясь в любом другом модуле или из рабочей книги Excel.

Помните о том, что если перед объявлением VBA процедуры Function или Sub ключевое слово не вставлено, то по умолчанию для процедуры устанавливается свойство Public (то есть она будет доступна везде в данном проекте VBA). В этом состоит отличие от объявления переменных, которые по умолчанию бывают Private.

Ранний выход из VBA процедур «Function» и «Sub»

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

Function VAT_Amount(sVAT_Rate As Single) As Single

   VAT_Amount = 0
   If sVAT_Rate <= 0 Then
      MsgBox "Expected a Positive value of sVAT_Rate but Received " & sVAT_Rate
      Exit Function
   End If

...

End Function

Обратите внимание, что перед тем, как завершить выполнение процедуры FunctionVAT_Amount, в код вставлена встроенная VBA функция MsgBox, которая показывает пользователю всплывающее окно с предупреждением.

Оцените качество статьи. Нам важно ваше мнение:

In Visual Basic, the functions and sub-procedures play similar roles but have different or unique characteristics. However, both perform a programmed task. They utilize a set or group of commands to deliver the required results. The key difference between the sub and the functions is that a sub-procedure generally does not return a result whereas functions tend to return a result. Hence if there is a need for having a value post execution of tasks, then place the VBA code under a function or otherwise place the code under a sub-procedure. In Excel, there is the availability of large numbers of VBA functions that could be utilized in the development of new VBA codes. Such functions are referred to as Built-in functions. With the increase in the size of a VBA program, both Functions and Sub-procedures play a crucial role in the management and performance of VBA code.

Functions in VBA

A function in VBA can be defined as a procedure that executes a piece of code or instructions and post-execution, it returns the value of the tasks performed. A function is hence invoked using a variable. Functions are directly called in the spreadsheets by using excel based formulas. An excel VBA function is not of executable nature. They help in performing a set of repetitive tasks. Following is the syntax for the VBA function: –

Function <Function name>  (Parameters) as variable type

Piece of codes

End function.

Here is a small example of the VBA function: 

Function CalcArea(a As Double, b As Double) As Double

CalcArea = a * b

End Function

In an excel spreadsheet, place the formula in range A1 as shown below:

Calcarea-formula-added

The following would be the output in range A1 of the excel spreadsheet as shown below: 

Output-in-cell-A1-obtained

The above code is a very simple example of how to program or develop custom functions. A VBA programmer can develop as many custom functions’ basis the need of the program. He can insert a new module and start developing a new function just by naming it by a new unique function name.

Sub in VBA

A sub-procedure in VBA can be defined as a procedure that executes a piece of code or instructions, but post-execution does not return the value of the tasks performed. A sub-procedure, therefore, does not require a variable for getting invoked. An excel VBA sub-routine or a sub-procedure is of executable nature and can be assigned as a macro to any excel based object. Like functions, they help in performing a set of repetitive tasks. Following is the syntax for the VBA sub-procedure: 

Sub  <sub name>  (Parameters) 

Piece of codes

End sub

Here is a small example of a VBA sub-routine: 

sub CalcArea() 

Dim a As Double, b As Double

c = a * b

Sheet3.activate

Sheet3.range(“A1”).value=c

End sub

In an excel module, select run sub/user form present under the Run option:

Selecting-sub/user-form

The following would be the output in range A1 of the excel spread sheet as shown below:

Output-in-cell-A1-obtained

The above code is like functions but the only difference is that in this program, the values are hard coded in the sub-procedure itself whereas, in functions, the values are to be passed by the end user. The following things should be followed when creating a sub-routine: 

  • It should not have any spaces.
  • It should not begin with any number or special character. It can however begin with an underscore or a simple letter.
  • The name of the sub-procedure should not be the same as that of the reserved keywords present in the excel VBA.

To Summarize, the following are the differences between a function and a sub in VBA: 

Function In VBA

Sub In VBA

Functions always return a value after it completes their required set of instructions. Sub does not return a value after it completes its required set of instructions.
Functions do not have any alternate nomenclature in VBA In VBA, Subs are referred to as subprocedures as well as subroutines
To Execute Function, it is to be passed on to the excel sheet beginning with equal to sign. In Short, they are invoked as excel based formulas. To execute a sub in VBA, it can be run or could be executed through Project explorer or by assigning it as a macro on excel objects.

Learn more about VBA commands

What is Sub vs Function?

In this article, we will discuss the key differences between a sub vs function. Both are sets of commands that are used to perform specific tasks in Microsoft Excel’s Visual Basic Application (VBA).

Sub vs Function

A sub, also known as a subroutine or sub procedure, is a piece of code that is used to perform a specific task mentioned in the code but does not return any kind of value. 

On the other hand, a function, also known as a user-defined function procedure, is a piece of code that executes a specific task determined by the Excel user and returns a result. One of the applications of function procedures is to perform repetitive tasks.

VBA Sub vs Function: Key Differences

The key differences between a sub and a function are as follows:

Sub Function
A sub performs a task but does not return a value. A function returns a value of the tasks performed.
Subs can be recalled from anywhere in the program and in multiple types. Functions are called by a variable.
Subs cannot be used directly in spreadsheets as formulas. Functions are used directly in spreadsheets as formulas.
Users must insert a value in the desired cell before getting the result of the sub. Functions can be used to perform repetitive tasks and return a value.
Excel users can execute a VBA sub. Excel users cannot execute VBA functions.

What is a VBA Sub?

A sub can be described as a small program within the VBA Editor that performs a specific action in Excel. It is used to break large pieces of code into smaller parts that can be easily managed.

The command is used to perform tasks that may involve updating a cell, performing a calculation, or importing a file into the Excel application. However, the outcome or results from the tasks are not returned to another sub.

How to Write a Sub-Procedure in Excel?

When writing a sub, the following rules should be followed:

  • The subroutine should not contain spaces.
  • The sub procedure should not start with a special character or number. Instead, use a letter or underscore.
  • The subroutine name should not be a keyword or reserved word in VBA. Examples of reserved words include Function, Subroutine, Privation, End, etc.

When writing the sub, we use the “Sub” keyword and a name as the procedure name to declare the sub. The sub procedure should be followed by the task to be performed, written in VBA language. The sub should close with the statement End Sub.

A sub should follow the following structure:

Sub [Procedure name] (Parameters)

[Tasks that need to be done]

End Sub.

Types of Sub Procedures in VBA

A sub procedure can take two forms, i.e., private and public. The modifiers “private” and “public” allows users to use the subs differently. The private sub procedure can only be used in the current module. The public sub allows users to use the procedure in all modules present in the workbook.

What is a VBA Function?

A VBA function is similar to a sub procedure, only that the former can return a value whereas the latter cannot. It is a piece of code that can be called anywhere in the VBA Editor and eliminates the need to write the same lines of code every time. VBA allows users to use built-in functions, as well as user-defined functions.

VBA functions work in the same way as formulas in Excel and can be used to perform repetitive tasks. Users can create custom functions for any actions and then access the functions from a cell or a direct reference from a cell.

For example, a user can use functions to create a program that calculates the monthly interest payable on a motor vehicle loan. The function will include fields that accept the total loan amount and payment duration. After inputting the required values, the program will return the monthly interest value payable on the motor vehicle.

How to Write a Custom Function?

Follow the steps below to create a custom function:

  1. Open MS Excel and press Alt+F11 to activate the VBA Editor.
  2. Choose the specific workbook in the Project.
  3. Go to the menu, click Insert then Module to insert a standard VBA module.
  4. In the module, enter the term Function, followed by a unique function name. If the function uses an argument, add the list of arguments in the parentheses.
  5. Insert the VBA code that performs the intended task. The program will store the value of the result in a variable, using the same name as the function.
  6. Close the function with the End Function.

Related Readings

To keep learning and developing your knowledge base, please explore the additional relevant resources below:

  • VBA Cell References
  • Excel IF Statement
  • How to Debug Code
  • VBA in Excel
  • See all Excel resources

A VBA Function can accept parameters and return results. Functions, however, can’t be executed directly. On the other hand a VBA Sub procedure can be executed directly and can also accept parameters. Procedures, however, do not return values.

We often use Subs and Functions often not thinking about their true potential and how much we can squeeze out of a regular VBA Function. Let’s start with a reminder how both differ from each other and then dive into the details.

Below structure resembles a VBA Sub and VBA Function:

'This is a Sub (procedure). Subs can only take arguments, they don't return results
Sub SomeSub(...)
  ...
End Sub

'This is a simple Function
Function SomeFunc(...) as ... 'Functions can take arguments and can return results
 ...
End Function 

Below are simple examples of Subs and Functions:

'Example Sub
Sub SayHello(name as String)
  Debug.Print "Hello " & name
End Sub

'Example Function
Function Add2Numbers(num1 as Long, num2 as Long) as Long 
  Add2Numbers = num1 + num2
End Function 

'Below Sub tests the Function Add2Numbers
Sub TestAdd2Numbers()
  Debug.Print Add2Numbers(1,2)
End Sub
'Result: 3

VBA Sub procedure syntax

The code block of a VBA Sub procedure is marked by the Sub and End Sub statements.
VBA Sub procedure

VBA Function procedure syntax

The code block of a VBA Function is marked by the Function and End Function statements.
VBA Function

VBA Function vs VBA Sub

We often tend to mix up procedures, Subs and Functions in VBA. So let’s get it right this time. There are 2 main differences between VBA Procedures (Subs) and VBA Functions:

  • VBA Functions return values, VBA Subs don’t
  • You can execute a VBA Sub, you can’t execute VBA Functions – they can only be executed by VBA Subs

Executing Functions and Subs

Although I provided examples above there are multiple ways to execute a VBA Function and a VBA Sub:

'An example VBA Procedure
Sub TestSub(arg as Long)
..
End Sub

'An example VBA Function
Function TestFunction(arg as Long) as String
...
End Function 


'HOW TO RUN FUNCTIONS AND PROCEDURES
Sub Test()
  Dim result

  '---RUN A FUNCTION---
  
 'Example 1: Run a Sub with brackets with the Call operator
  Call TestSub (10) 

  'Example 2: Run a Sub without brackets and without the Call operator
  TestSub 10

  '---RUN A FUNCTION---
  'Example: Functions are meant to return values so then need to be used with brackets
  result = TestFunction(1)
End Sub

Passing arguments ByVal and ByRef

The common knowledge is that only VBA Functions can return values. That indeed is mostly true. However, instead of a value (the result of the Function), we can assign values to variables that can be passed to the procedure by reference. What does that mean?

Variables can either by passed to a procedure (Function, Sub etc.) by their value or their reference.
Passing by value translates to making a copy of the variable. Thus any changes to the copy will not be reflected in the original variable.
Passing by reference is passing the address of the variable to the procedure. This means that any changes to a argument will be reflected in the original variable.
ByVal vs ByRef

By default all arguments are passed to procedures ByVal, so that no changes can be made to the original variables

ByVal and ByRef examples

Let’s look at some examples now:

Sub SetValueByVal(ByVal someLong As Long)
    someLong = 10
End Sub
Sub SetValueByRef(ByRef someLong As Long)
    someLong = 10
End Sub

Sub Test()
    Dim someLong As Long
    someLong = 1
    
    SetValueByVal someLong
    Debug.Print someLong 'Result: 1 (no change)
    
    SetValueByRef someLong
    Debug.Print someLong 'Result: 10
End Sub

When passing by value the variable someLong is not modified. However, when we pass it by reference its value is changed within the Sub procedure.

Objects and arrays are always passed by reference, because objects are in fact references (e.g. a Collection). Beware in such cases not to modify referenced objects by mistake!

Passing arrays to Subs and Functions

You can also easily pass arrays to Subs or Functions, even redefining their length. See example below:

Sub ChangeLength(arr() As Long)
    ReDim arr(5) As Long
End Sub

Sub Test()
    Dim arr() As Long
    ReDim arr(2) As Long
    Debug.Print UBound(arr) 'Result: 2
    ChangeLength arr
    Debug.Print UBound(arr) 'Result: 5
End Sub

Optional parameters

VBA Functions and Subs permit optional parameters, ones that need not be provided when executing the Function or Sub. It is a good practice to specify the default value for such parameters. See example below:

Sub SayHi(name As String, Optional surname As String = vbNullString)
    Debug.Print "Hi there, " & name & IIf(surname = vbNullString, "", " " & surname)
End Sub

Sub Test()
    Call SayHi("John") 'Result: "Hi there, John"
    
    Call SayHi("John", "Smith") 'Result: "Hi there, John Smith"
End Sub

You can verify if a parameter has not been passed to an Sub or Function by using the IsMissing function. The IsMissing function works however only for Variant type parameters. See the same SayHi procedure as above, this time with the IsMissing function.

Sub SayHi(name As String, Optional surname As Variant)
    Debug.Print "Hi there, " & name & IIf(IsMissing(surname), "", " " & CStr(surname))
End Sub

Sub Test()
    Call SayHi("John") 'Result: "Hi there, John"
    
    Call SayHi("John", "Smith") 'Result: "Hi there, John Smith"
End Sub

Dynamic parameter list

Say you want to create a VBA function like the Excel SUM or AVERAGE formulas – that can be provided with a dynamic list of parameters. VBA extends a neat solution for such a scenario called the ParamArray.

Public Function MySUM(ParamArray args())
    For Each arg In args
        MySUM = MySUM + arg
    Next arg
End Function

Sub Test()
    Debug.Print MySUM(1, 2, 3, 4) 'Result: 10
End Sub

The ParamArray transforms a list of Variant variables passed as parameters into a neat Variant array.

Read more on the ParamArray in this post.


VBA has two types of procedures for creating and executing codes: Subroutine (or simply Sub) and Function.

So far, the examples in this tutorial have always been tied to a Sub. From here on, we will continue to assume that it is a Sub unless it is explicit that it is a Function.


Subroutine

A Sub can be used to execute another Sub:

    Sub sub_main()
        sub_auxiliary1
        sub_auxiliary2
    End Sub
    Sub sub_auxiliary1()
        MsgBox "One Sub executing another Sub"
    End Sub
    Sub sub_auxiliary2()
        MsgBox "One Sub executing a second Sub"
    End Sub

For this and further examples, just run the sub_main. By clicking anywhere between the line Sub sub_main() and the first End Sub.

A Sub can also accept an argument:

    Sub sub_main()
        sub_argument(10) '10 is an argument
    End Sub
    Sub sub_argument(x as Integer)
        MsgBox x
    End Sub

You can assign an argument to the Sub using a single space:

    sub_argument 10 '10 is an argument

Or multiple arguments:

    Sub sub_main()
        Dim score As Single
        Dim student As String

        score=10
        student="Paulo"
        Call sub_argument (score, student) 'score is an argument, student is another argument
    End Sub
    Sub sub_argument(s_exam as Single, name as String)
        MsgBox name & "'s score was " & s_exam
    End Sub

To have more than one argument into a Sub, you can use the Call instruction before the name of the Sub you want to call.

You can also execute a Sub with multiple arguments omitting the Call instruction and the parentheses:

sub_argument score, student

Have the practice of declaring the variables in the same data types that the Sub requires as arguments.

E.g.score and s_exam.

Subs can also be accessed from different modules:


Types of Sub

The types of Sub available are Private and Public:

Private Sub

An undefined Sub is considered Public by VBA.


Functions

Functions work similarly to Subroutines with arguments. The main difference is that the Function will necessarily return a value and should be called by some other procedure.

    Sub sub_main()
        result = multiply_2(10)
        Msgbox result
    End Sub
    Function multiply_2(x As Single)
        multiply_2 = x*2
    End Function

It is not possible to pass arguments to a function through the single space if it is being associated with a variable.

    result = multiply_2 10 'Will result in error!

Note that:

MsgBox resultado 'It will not result in an error because there is no association.

You can not run a Function by itself. It is necessary to be called by another procedure.

E.g. Sub sub_main().

Once defined, functions can be used normally by the user in the Excel spreadsheet environment. Just call by the name of the function, as with any other predefined function (SUM, AVERAGE, etc.).

User Defined Function

We can also define in the declaration the type of result that the Function will return:

  Function multiply_2(x As Single) As Integer
      multiply_2 = x*2
  End Function

Note that now the function will only return rounded results, given the return specification As Integer.

There are many predefined functions in VBA. MsgBox is one of them.

        Msgbox "This should be shown" 'MsgBox works without the parentheses
        Msgbox ("This should be shown") 'and works with the parentheses

Naming a Function

When you create a function it needs to be followed by a name that must comply with the following rules:

  • It must initiate with an alphabetical character
  • It must not contain especial characters, such as: #, $, %, &, !
  • It must not contain whitespace characters, dots or commas
  • It must not be a VBA reserved word like: And, Or, Sub

Function Errors

Question: What if the user inserts unexpected values into my function?

Answer: Create an error to warn him.

This procedure can be done through the predefined CVErr function, which uses an integer value to specify an error.

The possible value it accepts are:

  • 2000 (ou xlErrNull) which returns a #NULL! error
  • 2007 (ou xlErrDiv0) which returns a #DIV/0 error
  • 2015 (ou xlErrValue) which returns a #VALUE! error
  • 2023 (ou xlErrRef) which returns a #REF! error
  • 2029 (ou xlErrName) which returns a #NAME? error
  • 2036 (ou xlErrNum) which returns a #NUM! error
  • 2042 (ou xlErrNA) which returns a #N/A error

Compare how an User Defined Function (UDF) to calculate the area of a triangle should be changed to apply the CVErr

Function AreaTriangle(Base As Single, Height As Single) As Double
    'As Double above specifies the return type of AreaTriangle
    AreaTriangle = (Base * Height) / 2

End Function

Negative values are not expected for the area calculation, so let’s create an error if the user enters them:

Function AreaTriangle(Base As Single, Height As Single) As Variant 
'As Variant is defining the data type of AreaTriangle

    If Base < 0 Or Height < 0 Then
        AreaTriangle = CVErr(2036)
    Else
        AreaTriangle = (Base * Height) / 2
    End If

End Function

In this way, if the user inserts negative values, the following error will appear in the cell of the function: NÚM!

The data type of CVErr(2036) is Error. This data type besides not being common is also incompatible with numeric data (that will be necessary for the calculation of the area). Therefore we assign to AreaTriangle the data type Variant. In this way, AreaTriangle will accept both the Error data type, if it occurs, and the Double data type, which will be returned if the calculation proceeded properly.


Sub VS Function

  • Subroutines do not return values if called. Functions return values
  • Subroutines can be assigned to buttons and shapes in Excel, Functions can’t
  • Functions created in VBA can be used in your Excel worksheet

By default the predefined Excel functions are named in all capital letters.

Mixing uppercase and lowercase letters is a good way to differentiate from Excel and make explicit the functions that were created by the user.



Consolidating Your Learning

Suggested Exercises



SuperExcelVBA.com is learning website. Examples might be simplified to improve reading and basic understanding. Tutorials, references, and examples are constantly reviewed to avoid errors, but we cannot warrant full correctness of all content. All Rights Reserved.

Excel ® is a registered trademark of the Microsoft Corporation.

© 2023 SuperExcelVBA | ABOUT

Protected by Copyscape

Like this post? Please share to your friends:
  • Excel vba sub workbooks
  • Excel vba sub return
  • Excel vba sub range
  • Excel vba string to number one
  • Excel vba string to long