This is a quick overview/primer on how to macros using Visual Basic for Applications in Excel 2007.
Object.myProperty = 3 ' Assign the value 3 to the property 'myProperty' Object.myFunction(3, 4) ' Call 'myFunction' with 3 being passed in as the first argument and 4 as the second argument Object.myFunction setting := 3 ' Call 'myFunction' with the specific argument 'setting' set to 3.
setting
could have been the fifth argument to the function myFunction
. All other arguments get their default values, but setting
is set to 3
.Application.Selection.End(xlDown).Select
Application
is an object and Selection
is a property that returns an object (e.g. a Range
object that contains selected cells on the worksheet). End
is a property of the Range object that returns another object (e.g. a Cell
object with the cell at the end of the range). Select
is finally the function, to select the cell indicated by the Cell
object.
xlDown
to the End
property. This shows a slight difference between VBA and other languages, because End
is a (read-only) property, but we can pass an argument to it. In this way, the property is acting a bit like a function.Dim
, and can be passed a type: Dim myVariable As Range
myVariable = 2 Set myVariable = Range("A1":"C3") ' The 'Set' syntax must be used for setting non-trivial values, such as this Range object
Variant
type. If you don't set a type when declaring a variable; e.g.:Dim myVariantVariable
then VBA will create a Variant
, and assign whatever type it thinks is best, based on your usage. On the surface, this sounds great, but it comes with several problems, including increased memory and CPU overhead, and an increased likelihood for lazy-developer errors.
Sub mySubroutine(firstName As String, lastName As String) ' do some stuff End Sub
Function myNameFunction(firstName As String, lastName As String) As String ' do some stuff ' return a value from a function by assigning the return value to a variable with the same name myFunction = firstName & ' ' & lastName End Function
=myNameFunction(A1, A2)
which would run that function and populate the value of the cell with the result.
For…Next
. These are very similar to other languages that support the for() construct, although the syntax is a bit different: For i = 1 To 10 ' do something with i Next i
For i = 300 To 200 Step 10 ' i will go from 300 to 200, in increments of 10 Next i
Do While…Loop
and Do Until…Loop
. These are both constructs that let you run code until something becomes true. They are the same loop; Until
is basically syntactic shorthand for While Not
. Dim testVar As Boolean testVar = true Do While testVar ' do something, and eventually set testVar = false, which breaks out of the loop Loop
For Each…Next
. Like many languages (but certainly not all) VBA supports the For Each construct to iterate over all elements of an object. For Each cell in myRange ' do something with each cell Next cell
If… Then….Else…End If
: If X > 0 Or Y > 0 Then ' do something Else ' do something else End If
Select…Case
: Select Case action Case 'loadData' ' do load proceedure Case 'saveData' ' do save proceedure Case Else ' print an error; nothing matched End Select
Dim myArray(2)
it actually has three elements: myArray(0), myArray(1) and myArray(2). Nearly every other language I'd use would only have two (index 0 and index 1)Dim myArray(2) ' declares a three element, one-dimensional array Dim myArray(2,5) ' declares an eighteen (3 x 6) element, two-dimensional array
Add
, Remove
, Count
and Item
. To use a collection: Dim myCollection As New Collection myCollection.Add 'foobar' 1 ' add the value 'foobar' with a unqiue key of '1' myCollection.Add 'goobar' 2 ' add the value 'goobar' with the unique key of '2' myCollection.Add 'roobar' 1 ' THROWS AN ERROR, because we already have an item with a unqiue key of 1 myCollection.Count ' value is 2 (foobar & goobar)
Dim regex As New RegExp ' Set regex properties; we're looking for a string that starts with 'foobar' With regex .MultiLine = False .Global = True .IgnoreCase = False .Pattern = "^foobar" End With regex.Test("foobarbaz") ' will evaluate to true regex.Test("barfoo") ' will evaluate to false
Range("A1").Select ' Selects only cell A1 Range("A:A").Select ' Selects the entire A column Range("1:1").Select ' Selects the entire 1 row Range("A1:C5").Select ' Select the box from A1 to C5 Range("A1","C5").Select ' Same thing as above; just a different syntax Worksheets("Sheet2").Range("A1").Select ' Selects A1 on the Worksheet 'Sheet2'
Range(“myRange”).Select
myRange.Cells.Item(5,2)
. This would get the cell that is five rows down and two columns over from the root cell of the range.Offset
is similar, but it moves the entire range rather than selecting a cell within it: myRange.Offset(5,2)
will move the Range down five and over two. myRange.Offset(RowOffset:=-1)
moves the range one row up.Resize
lets you expand an existing range. For example, myRange.Resize(RowSize:=2, ColumnSize:=3)
would expand the existing range by two rows and three columns.Cells
object lets you get data from and take action on specific cells.IsEmpty(myCell)
lets you figure out whether a cell is empty or not.ActiveWorkbook.Names.Add Name:="foobar", RefersTo:=ActiveSheet.Range("A4:F5") ActiveSheet.Names.Add Name:="foobaz", RefersTo:=3
Names("ABCDEF").Delete ' Note that names are NOT case sensitive, so this will delete the name created with 'abcdef'
WorksheetFunction
object, e.g. WorksheetFunction.Max(1,2,3,4,5)
will let you use the 'Max' function in Excel.ActiveSheet.Shapes.AddChart.Select ActiveChart.SetDataSource Source:=Range("C3:E4") ActiveChart.ChartType = xlColumnClustered
Shape
that it's attached to, not the chart itself. For example, this positions a chart at the top left corner of cell D6:ActiveChart.Parent.Left = Range("D6").Left ActiveChart.Parent.Top = Range("D6").Top
AppEvent_NewWorkbook
or AppEvent_WindowResize
Workbook_Open
and Workbook_SheetChange
Worksheet_Change
. Note that Worksheet_Change
only applies to a single worksheet, whereas 'Workbook_SheetChange' is fired if any sheet is changed.Chart_SeriesChange
ThisWorkbook
moduleOn Error Resume Next Names("foobar").Delete Range("A1").Value = Err.number ' Contains zero if the name was found, or an error code otherwise