This section provides an overview of what vba is, and why a developer might want to use it.
It should also mention any large subjects within vba, and link out to the related topics. Since the Documentation for vba is new, you may need to create initial versions of those related topics.
The first two syntaxes are for calling Sub
procedures; notice the first syntax involves no parentheses.
See This is confusing. Why not just always use parentheses? for a thorough explanation of the differences between the first two syntaxes.
The third syntax is for calling Function
and Property Get
procedures; when there are parameters, the parentheses are always mandatory. The Let
keyword is optional when assigning a value, but the Set
keyword is required when assigning a reference.
Fourth syntax is for calling Property Let
and Property Set
procedures; the expression
on the right-hand side of the assignment is passed to the property's value parameter.
Comment Blocks
If you need to comment or uncomment several lines at once, you can use the IDE's Edit Toolbar buttons:
Comment Block - Adds a single apostrophe to the start of all selected lines
Uncomment Block - Removes the first apostrophe from the start of all selected lines
Multi-line Comments Many other languages support multi-line block comments, but VBA only allows single-line comments.
Recursion allows for repeated, self-referencing calls of a procedure.
The assignment of string-literals in VBA is confined by the limitations of the IDE and the codepage of the current user's language settings. The examples above demonstrate the special-cases of escaped strings, special, non-printable strings and long string-literals.
When assigning string-literals that contain characters that are specific to a certain codepage, you may need to consider internationalization concerns by assigning a string from a separate unicode resource file.
Strings are a Reference type and are central to most programming tasks. Strings are assigned text, even if the text happens to be numeric. Strings can be zero-length, or any length up to 2GB. Modern versions of VBA store Strings internally using a Byte array of Multi-Byte Character Set bytes (an alternative to Unicode).
VBA will implicitly convert some types to string as necessary and without any extra work on the part of the programmer, but VBA also provides a number of explicit string conversion functions, and you can also write your own.
Three of the most frequently used functions are CStr
, Format
and StrConv
.
When you need to check for the presence or position of a substring within a string, VBA offers the InStr
and InStrRev
functions that return the character position of the substring in the string, if it is present.
VBA has built-in functions for extracting specific parts of strings, including:
Left
/Left$
Right
/Right$
Mid
/Mid$
Trim
/Trim$
To avoid implicit type conversion onverhead (and therefore for better performance), use the $-suffixed version of the function when a string variable is passed to the function, and/or if the result of the function is assigned to a string variable.
Passing a Null
parameter value to a $-suffixed function will raise a runtime error ("invalid use of null") - this is especially relevant for code involving a database.
A string's length can be measured in two ways: The most frequently used measure of length is the number of characters using the Len
functions, but VBA can also reveal the number of bytes using LenB
functions. A double-byte or Unicode character is more than one byte long.
The examples shown in this topic use early binding for clarity, and require a reference to the Microsoft ActiveX Data Object x.x Library. They can be converted to late binding by replacing the strongly typed references with Object
and replacing object creation using New
with CreateObject
where appropriate.
Strings can be concatenated, or joined together, using one or more concatenation operator &
.
String arrays can also be concatenated using the Join
function and providing a string (which can be zero-length) to be used between each array element.
There are times you need to assign a string variable with a specific character repeated a specific number of times. VBA provides two main functions for this purpose:
String
/String$
Space
/Space$
.You must add Microsoft Scripting Runtime to the VBA project through the VBE's Tools → References command in order to implement early binding of the Scripting Dictionary object. This library reference is carried with the project; it does not have to be re-referenced when the VBA project is distributed and run on another computer.
It is much easier to control the boundaries of arrays by declaring the boundaries explicitly rather than letting the compiler fall back on an Option Base {0|1}
declaration. This can be done like so:
Dim myStringsA(0 To 5) As String '// This has 6 elements (0 - 5)
Dim myStringsB(1 To 5) As String '// This has 5 elements (1 - 5)
Dim myStringsC(6 To 9) As String '// This has 3 elements (6 - 9)
This article will show how to create a complete custom class in VBA. It uses the example of a DateRange
object, because a starting and ending date are often passed together to functions.
An event can only be Public
. The modifier is optional because class module members (including events) are implicitly Public
by default.
A WithEvents
variable can be Private
or Public
, but not Friend
. The modifier is mandatory because WithEvents
isn't a keyword that declares a variable, but a modifier keyword part of the variable declaration syntax. Hence the Dim
keyword must be used if an access modifier isn't present.
The Scripting.FileSystemObject
is much more robust that the legacy methods in this topic. It should be preferred in almost all cases.
Operators are evaluated in the following order:
Operators with matching precedence are evaluated from left to right. The default order can be overridden by using parentheses (
and )
to group expressions.
A Collection
is a container object that is included in the VBA runtime. No additional references are required in order to use it. A Collection
can be used to store items of any data type and allows retrieval by either the ordinal index of the item or by using an optional unique key.
Collection | Array | Dictionary | |
---|---|---|---|
Can be resized | Yes | Sometimes1 | Yes |
Items are ordered | Yes | Yes | Yes2 |
Items are strongly typed | No | Yes | No |
Items can be retrieved by ordinal | Yes | Yes | No |
New items can be inserted at ordinal | Yes | No | No |
How to determine if an item exists | Iterate all items | Iterate all items | Iterate all items |
Items can be retrieved by key | Yes | No | Yes |
Keys are case-sensitive | No | N/A | Optional3 |
How to determine if a key exists | Error handler | N/A | .Exists function |
Remove all items | Iterate and .Remove | Erase , ReDim | .RemoveAll function |
1 Only dynamic arrays can be resized, and only the last dimension of multi-dimensional arrays.
2 The underlying .Keys
and .Items
are ordered.
3 Determined by the .CompareMode
property.
Arrays must be passed by reference. This code compiles, but raises run-time error 424 "Object Required":
Public Sub Test()
DoSomething Array(1, 2, 3)
End Sub
Private Sub DoSomething(ByVal foo As Variant)
foo.Add 42
End Sub
This code does not compile:
Private Sub DoSomething(ByVal foo() As Variant) 'ByVal is illegal for arrays
foo.Add 42
End Sub
At its simplest, CreateObject
creates an instance of an object whereas GetObject
gets an existing instance of an object. Determining whether an object can be created or gotten will depend on it's Instancing property. Some objects are SingleUse (eg, WMI) and cannot be created if they already exist. Other objects (eg, Excel) are MultiUse and allow multiple instances to run at once. If an instance of an object does not already exist and you attempt GetObject
, you will receive the following trappable message: Run-time error '429': ActiveX component can't create object
.
GetObject requires at least one of these two optional parameters to be present:
CreateObject has one required parameter and one optional parameter:
Class is always comprised of two parts in the form of Application.ObjectType
:
Some example classes are:
Method Name | Description |
---|---|
IsOpen | Returns a boolean to indicate whether the file is open. |
OpenFile(sFileName As String) | Opens the file specified by the sFileName argument. |
CloseFile | Closes the currently open file. |
ReadBytes(ByteCount As Long) | Reads ByteCount bytes and returns them in a Variant byte array and moves the pointer. |
WriteBytes(DataBytes() As Byte) | Writes the contents of the byte array to the current position in the file and moves the pointer. |
Flush | Forces Windows to flush the write cache. |
SeekAbsolute(HighPos As Long, LowPos As Long) | Moves the file pointer to the designated position from the beginning of the file. Though VBA treats the DWORDS as signed values, the API treats them as unsigned. Make the high-order argument non-zero to exceed 4GB. The low-order DWORD will be negative for values between 2GB and 4GB. |
SeekRelative(Offset As Long) | Moves the file pointer up to +/- 2GB from the current location. You can rewrite this method to allow for offsets greater than 2GB by converting a 64-bit signed offset into two 32-bit values. |
Property | Description |
---|---|
FileHandle | The file handle for the currently open file. This is not compatible with VBA file handles. |
FileName | The name of the currently open file. |
AutoFlush | Sets/indicates whether WriteBytes will automatically call the Flush method. |
Function | Notes |
---|---|
GetFileHash(sFile As String, uBlockSize As Double, sHashType As String) | Simply throw in the full path to be hashed, Blocksize to use (number of bytes), and the type of Hash to use - one of the private constants: HashTypeMD5, HashTypeSHA1, HashTypeSHA256, HashTypeSHA384, HashTypeSHA512. This was designed to be as generic as possible. |
You should un/comment the uFileSize As Double accordingly. I have tested MD5 and SHA1.
When an application supports Automation, the objects the application exposes can be accessed by Visual Basic. Use Visual Basic to manipulate these objects by invoking methods on the object or by getting and setting the object's properties.
If you use the objects in other applications as part of your Visual Basic application, you may want to establish a reference to the object libraries of those applications. Before you can do that, you must first be sure that the application provides an object library.
Allows you to select another application's objects that you want available in your code by setting a reference to that application's object library.
Creates an Automation object of the specified class. If the application is already running, CreateObject will create a new instance.
Common operating environment library files (DLL's):
Dynamic Link Library | Description |
---|---|
Advapi32.dll | Advanced services library for APIs including many security and Registry calls |
Comdlg32.dll | Common dialog API library |
Gdi32.dll | Graphics Device Interface API library |
Kernel32.dll | Core Windows 32-bit base API support |
Lz32.dll | 32-bit compression routines |
Mpr.dll | Multiple Provider Router library |
Netapi32.dll | 32-bit Network API library |
Shell32.dll | 32-bit Shell API library |
User32.dll | Library for user interface routines |
Version.dll | Version library |
Winmm.dll | Windows multimedia library |
Winspool.drv | Print spooler interface that contains the print spooler API calls |
New arguments used for the 64 system:
Type | Item | Description |
---|---|---|
Qualifier | PtrSafe | Indicates that the Declare statement is compatible with 64-bits. This attribute is mandatory on 64-bit systems |
Data Type | LongPtr | A variable data type which is a 4-bytes data type on 32-bit versions and an 8-byte data type on 64-bit versions of Office 2010. This is the recommended way of declaring a pointer or a handle for new code but also for legacy code if it has to run in the 64-bit version of Office 2010. It is only supported in the VBA 7 runtime on 32-bit and 64-bit. Note that you can assign numeric values to it but not numeric types |
Data Type | LongLong | This is an 8-byte data type which is available only in 64-bit versions of Office 2010. You can assign numeric values but not numeric types (to avoid truncation) |
Conversion | Operator | CLngPtr Converts a simple expression to a LongPtr data type |
Conversion | Operator | CLngLng Converts a simple expression to a LongLong data type |
Function | VarPtr | Variant converter. Returns a LongPtr on 64-bit versions, and a Long on 32-bit (4 bytes) |
Function | ObjPtr | Object converter. Returns a LongPtr on 64-bit versions, and a Long on 32-bit (4 bytes) |
Function | StrPtr | String converter. Returns a LongPtr on 64-bit versions, and a Long on 32-bit (4 bytes) |
Full reference of call signatures:
Win32api32.txt for Visual Basic 5.0 (old API declarations, last reviewed Mar 2005, Microsoft)
Win32API_PtrSafe with 64-bit Support (Office 2010, Microsoft)