Você está na página 1de 30

1

 Procedures in VBA are very similar to methods


in VB
◦ Subroutines
 Perform some actions
◦ Functions
 Perform some actions and return a value

2
 Subroutines in VBA are very similar to those in VB

 The syntax of a subroutine is as follows:


[Private | Public] Sub name [(arglist)]
[statements]
End Sub

◦ [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

 In VBA, by default, arguments are passed by reference


◦ If we want to pass by value, we have to add the keyword “ByVal”
before the parameter name

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

Sub Test(ByRef i As Integer)


i = 20
End Sub

15
Sub Demo3()
Dim i As Integer
i = 10
MsgBox i 'Print 10
Test i
MsgBox i 'Print 10
End Sub

Sub Test(ByVal i As Integer)


i = 20
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

Sub Test(ByRef i As Integer)


i = 20
End Sub

17
 We can also set the argument as optional
◦ the parameter can be omitted when the procedure is
invoked

 Use the Optional keyword before the parameter


that we wish to set optional
◦ We may provide a default value to the optional parameter
◦ If we do not provide a default value, the default value for
that type is used, e.g. 0 for integer

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

The last parameter


is optional. In this
way, r will be 0.1.

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)

 To determine the upper bound of the array index,


we can use the function UBound(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

Dim varname(upperIndex1, upperIndex2) As vartype

 We can have an array with more dimensions

Dim varname(upperIndex1, upperIndex2, upperIndex3, ...)


As vartype

22
 We can check the upper bound of the i-th
dimension by UBound(arrayVar, i)

 We can check the lower bound of the i-th


dimension by LBound(arrayVar, i)
Sub ArrayTest()
Dim a(4, 9) As Integer '5 rows and 10 columns

'Index start at 1 (but not 0)


'[different from GetUpperBound() in VB]
MsgBox LBound(a, 1) 'Popup and show 0 (1st dimension)
MsgBox UBound(a, 1) 'Popup and show 4 (1st dimension)
MsgBox LBound(a, 2) 'Popup and show 0 (2nd dimension)
MsgBox UBound(a, 2) 'Popup and show 9 (2nd dimension)
End Sub 23
 Selection
◦ Return the range of currently selected cells

 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

MsgBox Count & " cells are selected"


For i = LBound(a, 1) To UBound(a, 1)
For j = LBound(a, 2) To UBound(a, 2)
MsgBox "Cell(" & i & "," & j & ")=" & a(i, j)
Next
Next Indexes start at 1 (but not 0)
End Sub
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

MsgBox Count & " cells are selected"


For i = LBound(a, 1) To UBound(a, 1)
For j = LBound(a, 2) To UBound(a, 2)
MsgBox "Cell(" & i & "," & j & ")=" & a(i, j)
Next
Next
End Sub
Sub ArrayTest()
Dim count As Integer
count = Selection.Count 'Count the number of selected cells
If count = 1 Then
Dim i As Variant 'Declare a variable
i = Selection.Value
MsgBox "Only one cell=" & i & " is selected“
Else
Dim a() As Variant 'Declare an array
a = Selection.Value 'Read the values of the selected cells
MsgBox count & " cells are selected"
For i = LBound(a, 1) To UBound(a, 1)
For j = LBound(a, 2) To UBound(a, 2)
MsgBox "Cell(" & i & "," & j & ")=" & a(i, j)
Next
Next
End If
End Sub
 We can pass arrays to procedures
(subroutines or functions)
◦ Array passing must be passing by reference
Sub aSub(ByRef anArray() As Integer,
ByRef anotherArray() As Integer)

 We can return an array from a function


Function aFunction() As Integer()
Dim anotherArray() As Integer
......
aFunction = anotherArray
End Function

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

' a and c refer to the same array (same as VB)


Function ArrayTest(ByRef c() As Integer) As Integer()
For i = LBound(c) To UBound(c)
c(i) = c(i) * 10
Next
ArrayTest = c
End Function 29
 Excel VBA Marco Programming
◦ Shephred, McGraw-Hill
 Power Programming with VBA/EXCEL
◦ Chapra, Prentice Hall
 MSDN – Visual Basic for Application (VBA)
◦ http://msdn.microsoft.com/en-us/isv/bb190540

30

Você também pode gostar