Escolar Documentos
Profissional Documentos
Cultura Documentos
2
Subroutines in VBA are very similar to those in VB
◦ [Private | Public]
Optional element
We can choose either public or private
Public: this subroutine can be accessed from all other
procedures in all modules
Private: this subroutine can only be accessed from all other
procedures in the module where it is declared
The default value is Public
3
◦ name
Required element
The name of the subroutine
◦ [(arglist)]
Optional element
The list of arguments / parameters
◦ [statements]
Statements to be executed when this subroutine is
invoked
4
Only subroutines without any parameters can
be executed directly as macro in Excel
◦ To run subroutines with parameters, we have to
invoke it from other procedures
Sub Demo1()
Create an input
Dim myName As String
dialog box
myName = InputBox("What is your name?")
BoxDemo myName
End Sub
Create a
Sub BoxDemo(ByVal name As String)
message box
MsgBox "Hi " & name & "! Nice to meet you!"
End Sub
5
Only Demo1 can
be run directly, but
not BoxDemo
6
7
The syntax of a function is as follows:
[Private | Public] Function name [(arglist)] [As type]
[statements]
[name = returnValue]
End Function
◦ [As type]
Specify the return type of the function
It is optional (but recommended)
If we omit it, the default return type is Variant
◦ [name = returnValue]
The keyword “return” cannot be used in a VBA function
Hence, we have to use [name = returnValue] instead
It is optional (but we will have to write it in most cases)
If we omit it, the function will return the default value of the return type
E.g. 0 for integer
8
Function CompoundInterest(ByVal p As Double, ByVal n As Double,
ByVal r As Double) As Double
CompoundInterest = p * (1 + r) ^ n
End Function
Sub Demo2()
Dim p, n, r, amount As Double
p = InputBox("Principal: ") Round to the nearest even
n = InputBox("# of years: ") for 2 decimal places
r = InputBox("Interest rate: ")
amount = CompoundInterest(p, n, r)
MsgBox "The total amount is " & Round(amount, 2)
End Sub
9
Calling as macro
10
11
We can call the function from the formula in a
cell
◦ The function to be called has to be placed in a user
created module (not Sheet nor Workbook) inside the
Visual Basic Editor
12
Arguments are passed by value or by reference
◦ When an argument is passed by value (ByVal)
The program makes a copy of the argument’s value and
passes the copy
Changes to the copy do not affect the original variable
◦ When an argument is passed by reference (ByRef)
The original data can be accessed and modified directly
13
Sub Demo3()
Dim i As Integer
i = 10
MsgBox i 'Print 10
Test i
MsgBox i 'Print 20
End Sub
Sub Test(i)
i = 20
End Sub
14
Sub Demo3()
Dim i As Integer
i = 10
MsgBox i 'Print 10
Test i
MsgBox i 'Print 20
End Sub
15
Sub Demo3()
Dim i As Integer
i = 10
MsgBox i 'Print 10
Test i
MsgBox i 'Print 10
End Sub
16
Enclose the argument in parentheses to force it to
be passed by value (even if the procedure explicitly
specifies it to be passed by reference)
Sub Demo4()
Dim i As Integer
i = 10
MsgBox i 'Print 10
Test (i) 'Force i to be passed by value
MsgBox i 'Print 10 (instead of 20)
End Sub
17
We can also set the argument as optional
◦ the parameter can be omitted when the procedure is
invoked
18
Function CompoundInterest(ByVal p As Double, ByVal n As Double,
Optional ByVal r As Double = 0.1) As Double
CompoundInterest = p * (1 + r) ^ n
End Function
19
The following is the syntax to declare a one-
dimensional (1D) array
Dim varname(upperBound) As vartype
In addition, all elements will be initialized to its
default value
Sub ArrayTest()
Dim intArray(9) As Integer 'declare array
For i = 0 To 9 'index starts at 0
intArray(i) = i
Next
Range("A1").Select
For Each e In intArray
ActiveCell.Value = e
ActiveCell.Offset(1, 0).Activate
Next
End Sub
20
To determine the lower bound of the array index,
we can use the function LBound(arrayVar)
Sub ArrayTest()
Dim intArray(9) As Integer 'declare array
For i = Lbound(intArray) To Ubound(intArray)
intArray(i) = i
Next
Range("A1").Select
For Each e In intArray
ActiveCell.Value = e
ActiveCell.Offset(1, 0).Activate
Next
End Sub
21
The following is the syntax to declare a 2D
array
22
We can check the upper bound of the i-th
dimension by UBound(arrayVar, i)
Selection.Count
◦ Return the number of selected cells
Selection.Value
◦ Return the values of the selected cells
◦ Usually, we will assign it to an array
◦ The lower bound of the returned array is 1 instead of 0
(different from VB and the previous example for VBA)
24
Sub ArrayTest()
Dim a() As Variant 'Declare an array with arbitrary dimension
Dim count As Integer
count = Selection.Count 'Count the number of selected cells
a = Selection.Value 'Read the values of the selected cells
28
Sub Demo5()
Dim a(3) As Integer
Dim b() As Integer
For i = LBound(a) To UBound(a)
a(i) = i
Next
b = ArrayTest(a) ' b stores a copy of a (different from VB,
' where b and a refer to the same array)
a(1) = 50
For Each e In a
MsgBox e ' Popup and show 0, 50, 20, 30
Next
For Each e In b
MsgBox e ' Popup and show 0, 10, 20, 30
Next
End Sub
30