VBA Data Types
Data Types define what kinds of values can be stored in a variable or returned from a function. Each data type takes up a certain amount of memory, has a certain range of values, and has a default value representing the falsey value for the type. The Variant data type can be used to hold almost any type of data, however it is more efficient, more descriptive, and more secure to assign a specific data type for each variable and function.
Data Type | Bytes | Value Range | Default Value |
---|---|---|---|
Boolean | 2 | True (-1) or False (0) | False |
Byte | 1 | 0 to 255 | 0 |
Integer | 2 | -32,768 to 32,767 | 0 |
Long | 4 | -2,147,483,648 to 2,147,483,647 | 0 |
LongLong* | 8 | -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 | 0 |
LongPtr* |
4 on 32-bit
8 on 64-bit |
Same as Long on 32-bit
Same as LongLong on 64-bit |
0 |
Single | 4 |
-3.402823E38 to -1.401298E-45 for negative values
1.401298E-45 to 3.402823E38 for positive values |
0 |
Double | 8 |
-1.79769313486231E308 to -4.94065645841247E-324 for negative values
4.94065645841247E-324 to 1.79769313486232E308 for positive values |
0 |
Currency | 8 | -922,337,203,685,477.5808 to 922,337,203,685,477.5807 | 0 |
Decimal | 14 |
+/-79,228,162,514,264,337,593,543,950,335 with no decimal point
+/-7.9228162514264337593543950335 with 28 places to the right of the decimal Smallest non-zero number is +/-0.0000000000000000000000000001 |
0 |
Date | 8 | 01/01/100 12:00:00 AM To 12/31/9999 11:59:59 PM | #12:00:00 AM# (Saturday, December 30, 1899 12:00:00 AM) |
Object | 4 for reference + object's data | Any object type | Nothing |
Variant (Numeric) | 16 |
-1.797693134862315E308 to -4.94066E-324 for negative values
4.94066E-324 to 1.797693134862315E308 for positive values |
Empty |
Variant (Text) | 22 + 2 bytes per character | 0 to 2,147,483,635 characters | Empty |
String (Variable‑Length) | 10 + 2 bytes per character | 0 to 2,147,483,635 characters | vbNullString |
String (Fixed‑Length) | 2 bytes per character | 1 to 65,526 characters | Null character repeated for length of string |
User‑Defined Type | Sum of Members | Ranges of Members | Default Values of Members |
*The LongLong and LongPtr data types were added in VBA7.
Data Type Functions
VBA provides functions to determine a variable's data type at runtime.
The TypeName function returns a string describing a variable's type.
The VarType function returns a member of the VbVarType enum.
Option Explicit
Public Sub Example()
Dim i As Long
Debug.Print TypeName(i)
If VarType(i) = vbLong Then
Debug.Print "i is a Long Integer"
End If
End Sub
Type Conversion Functions
Type Conversion Functions are used to convert data of one type to another type.
Function | Return Type | Argument Value Range |
---|---|---|
CBool | Boolean | Any number, date, or the case-insensitive strings "True" and "False" |
CByte | Byte | 0 to 255 |
CInt | Integer | -32,768 to 32,767. Decimals are rounded. |
CLng | Long | -2,147,483,648 to 2,147,483,647. Decimals are rounded. |
CLngLng* | LongLong | -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807. Decimals are rounded. 64-bit platforms only. |
CLngPtr* | LongPtr | Same as CLng on 32-bit systems. Same as CLngLng on 64-bit systems. Decimals are rounded. |
CSng | Single | -3.402823E38 to -1.401298E-45 for negative values. 1.401298E-45 to 3.402823E38 for positive values. |
CDbl | Double | -1.79769313486231E308 to -4.94065645841247E-324 for negative Values. 4.94065645841247E-324 to 1.79769313486232E308 for positive values. |
CCur | Currency | -922,337,203,685,477.5808 to 922,337,203,685,477.5807 |
CDec | Decimal |
+/- 79,228,162,514,264,337,593,543,950,335 for numbers with no decimal.
+/- 7.9228162514264337593543950335 for numbers with 28 decimal places. 0.0000000000000000000000000001 is the smallest value. |
CDate | Date | Any valid date expression. |
CStr | String | Any value type. |
CVar | Variant | Any value type. |
*CLngLng and CLngPtr were added in VBA7.
Integral Conversion Rounding
CLngLng, CLngPtr, CLng, CInt, and CByte round decimals to the nearest whole number except when the decimal is .5, in which case they will round in the direction of the nearest even number (1.5 will round to 2 and 2.5 will round to 2).
Decimal
Variables cannot be declared with the Decimal data type. To use the Decimal data type, declare a variable as type Variant and use the CDec function. The CDec function returns a Variant with subtype Decimal.
LongLong and LongPtr
To assign a LongLong or a LongPtr to another integral type, the value must be explicitly converted using one of the conversion functions. Implicit conversions do not work for LongLong or LongPtr and will result in a type mismatch error.
Currency and LongLong
Converting between Currency and LongLong is problematic and it is best to avoid doing this. Both LongLong and Currency are 64-bit signed integer types but Currency is scaled to have 4 decimal places. Unexpected behavior can occur when LongLong values that should be outside the range of the Currency type are converted to Currency.
Normally an Overflow error would occur when converting values outside of the type's range but because Currency and LongLong are technically the same size the Overflow error does not occur and erroneous results occur.
Public Sub Example()
'The max value of LongLong is 9,223,372,036,854,775,807
Dim LL As LongLong
LL = 2 ^ 64 / 2 - 1
'The max value of Currency is 922,337,203,685,477.5807
Dim C As Currency
C = CCur(LL)
Debug.Print LL 'Prints 9223372036854775807
Debug.Print C 'Prints -1
End Sub
Comparing a LongLong value with a Variant/Currency value can cause an Overflow error even when the LongLong value is within the Currency type's range of values.
Public Sub Example()
Dim LL As LongLong
LL = 922337203685477^
Dim VC As Variant
VC = 922337203685477.5807@
'Causes Overflow Error
Dim B As Boolean
B = LL < VC
End Sub
Other Conversion Functions
There are additional conversion functions which have special uses.
Function | Description |
---|---|
Int, Fix | Although not technically type conversion functions, the Fix and Int functions convert a decimal number to a whole number by removing the decimal part of the number. Fix and Int always return a value of the same type that was passed in. The difference between Int and Fix is that for negative numbers Int returns the first whole number less than or equal to the number whereas Fix returns the first whole number greater than or equal to the number. The difference with CLngLng, CLngPtr, CLng, CInt, and CByte is that these functions round the decimal whereas Int and Fix cut off the decimal. |
Str | The Str function is used to convert a numeric expression to a string. The Str function only recognizes the period as the decimal separator so CStr must be used in applications where the decimal separator could be something other than a period. |
CVDate | The CVDate function returns a Variant with Subtype Date. This function exists for backward compatibility for when there was not an explicit Date type. |
CVErr | CVErr returns a Variant with Subtype Error. This function can be used to return an error from a UDF. |
Val | Val returns the numeric portion of a string. |
Type Identifier Characters
Type Identifier Characters can be used instead of "As Type" to give variables, constants, parameters, and functions their data types. Literal values can also have type identifier characters to determine their data types. There are no type identifier characters for Boolean, Byte, Date, Object, Variant, LongPtr, Arrays, User-Defined Classes, or User-Defined Types. Type identifier characters must be used to represent literals of type Currency, LongLong, and Single. If no type identifier character exists, type conversion functions can be used.
Data Type | Type Identifier Character | Example |
---|---|---|
Integer | % | Dim i% |
Long | & | Dim i& |
LongLong* | ^ | Dim i^ |
Single | ! | Dim i! |
Double | # | Dim i# |
Currency | @ | Dim i@ |
String | $ | Dim i$ |
*The LongLong type identifier was added in VBA7. LongLong is only available on 64-bit platforms.
Public Sub Example()
'Use type identifier to change a literal's type
'Use conversion functions for types that have no identifier
Debug.Print TypeName(255)
Debug.Print TypeName(255&)
Debug.Print TypeName(CByte(255))
End Sub
Public Function AddTwoNumbers&(Num1&, Num2&)
'Use type identifier instead of "As Type"
Dim TheSum&
TheSum = Num1 + Num2
AddTwoNumbers = TheSum
End Function
Public Sub Example()
'Type identifier must be used for literals of type Currency, LongLong, and Single
Dim C As Currency
C = 922,337,203,685,477.5807@
Dim LL As LongLong
LL = 9,223,372,036,854,775,807^
Debug.Print TypeName(1.0) 'Prints Double
Debug.Print TypeName(1.0!) 'Prints Single
End Sub
Data Types of Literals
Literal values have a default data type. Type identifier characters change the type of a literal value.
Literal | Default Data Type |
---|---|
32767 | Integer |
2147483647 | Long |
3.5 or 2147483648 | Double |
"Hello, World!" | String |
#01/01/20 12:00:00 AM# | Date |
True or False | Boolean |
Public Sub Example()
Debug.Print TypeName(32767)
Debug.Print TypeName(2147483647)
Debug.Print TypeName(3.5)
Debug.Print TypeName(2147483648)
Debug.Print TypeName("Hello, World!")
Debug.Print TypeName(#01/01/20 00:00:00#)
Debug.Print TypeName(True)
End Sub
Hexadecimal, Octal, Binary Literals
Integral literals can be represented in Hexadecimal or Octal. Binary literals are not supported in VBA.
Number Base | Prefix | Valid Digit Values | Example |
---|---|---|---|
Hexadecimal | &H | 0-9, A-F | &HFF |
Octal | &O | 0-7 | &O255 |
Binary (not supported in VBA) | &B | 0-1 | &B11111111 |
The Hex/Hex$ function converts a number to a string representing the number in hexadecimal. The Oct/Oct$ function converts a number to a string representing the number in octal. VBA does not have a built in function to convert to binary but the worksheet function Dec2Bin can be used for numbers within the range -512 to 511. Another option for converting to binary would be to use a user-defined function like the one described here.
DefType
The DefType statement is used to declare the default data type for variables, arguments, and functions in a given module. The DefType statement is declared at the top of a module along with a letter range which specifies that members that start with those letters have that default data type. To specify all identifiers in the module use the letter range A-Z. When the letter range A-Z is specified, international characters are considered part of that range as well. If no DefType statement is declared, the default data type for all variables, arguments, functions, and Property Get procedures is Variant.
Syntax: DefType letterrange, [ letterrange ] . . .
Option Explicit
DefLng A-Z
Public Function Example()
Dim i
Dim j
Dim k
Debug.Print TypeName(i)
Debug.Print TypeName(j)
Debug.Print TypeName(k)
Debug.Print TypeName(Example)
End Function
DefType Statement | Data Type |
---|---|
DefBool | Boolean |
DefByte | Byte |
DefInt | Integer |
DefLng | Long |
DefLngLng | LongLong |
DefLngPtr | LongPtr |
DefCur | Currency |
DefSng | Single |
DefDbl | Double |
DefDec *Not Supported | Decimal |
DefDate | Date |
DefStr | String |
DefObj | Object |
DefVar | Variant |