According to this answer one should always use Variant
when assigning values in a cell to a variable in the code. Is this correct? I seem to recall reading elsewhere that using Variant
indiscriminately is not a good practice.

- 1
- 1

- 57
- 1
- 3
- 9
-
2Unless you know exactly what type will be in the cell then `Variant` is the best method. Also if you are trying to assign a range to an array the only way is Variant, unless you loop and put each in one at a time. But the minute you try to load anything that does not fit the type it will cause the code to crash. So Variant is the safest. – Scott Craner Mar 28 '17 at 19:35
3 Answers
You can read a cell value into any type you want, VBA will (try to) implicitly convert it to that type for you.
There are dozens of questions on this site involving run-time errors raised from reading cell values into a specific data type - perhaps you've seen this error message before?
Type mismatch
That's the error you get when you try to read a cell containing an error value (e.g. #REF!
) into anything other than a Variant
.
So if you read a cell value into, say, a Double
, everything will work fine as long as you're reading something that VBA can coerce into that data type. The problem is that, well, data is never 100% clean, worksheets do break down, users delete columns and break formulas, lookups fail and the person that wrote the formula didn't bother wrapping it with IFERROR
, etc.
That's why you read cell values into a Variant
.
That doesn't mean you work with a Variant
.
Dim cellValue As Variant
cellValue = someRange.Value
If IsError(cellValue) Then Exit Sub 'bail out before we blow up
Dim workingValue As String
workingValue = CStr(cellValue)
By assigning to another data type, you effectively cast the Variant
to that more specific type - here a String
. And because you like explicit type conversions, you use VBA's conversion functions to make the conversion explicit - here CStr
.
Now, in real code, you probably wouldn't even bother reading it into a Variant
- you can use IsError
to test the cell value:
If IsError(someRange.Value) Then Exit Sub 'bail out before we blow up
Dim cellValue As String
cellValue = someRange.Value ' or cellValue = CStr(someRange.Value)
The flipside here is that you're accessing the cell twice. Whether or not that's better that reading it into a Variant
is for you to decide; performance-wise, it's usually best to avoid accessing ranges as much as possible though.

- 69,817
- 8
- 107
- 235
-
Great answer, I didn't know about type conversions. [Here](https://msdn.microsoft.com/en-us/library/s2dy91zy.aspx) is the MSDN page for them if anyone is interested. – partiallyfulltime Mar 28 '17 at 19:49
-
1Thanks for the downvote. Mind telling me what's wrong with this answer so I can improve it? /edit: added a note about not *really* needing to read the cell value into a variable. Hope I'm a good mind reader. – Mathieu Guindon Mar 28 '17 at 20:23
-
1*(+1) from my side.* Yet, maybe you want to add one more thing to your answer to make it possibly better: I don't think it has been made abundantly clear that a `variant` will (in the end) hold as many different variable types as is necessary (and `variant` is the only one offering that kind of variety). That means if `A1` contains nothing, `A2` contains a string, `B1` contains a date, and `B2` contains `=1/0` (resulting in an error) then the resulting array `arr = Range("A1:B2").Value2` will contain a string, a double, an error, and an `empty` as data types: `Debug.Print TypeName(arr(1, 1))`. – Ralph Mar 28 '17 at 21:45
-
@Ralph thanks - I'll edit with a quote+link from the relevant docs.so topic when I get a chance. – Mathieu Guindon Mar 28 '17 at 21:52
The value you get from a cell (which is a Range
) is a Variant
according to the documentation:
Range.Value Property (Excel)
Returns or sets a Variant value that represents the value of the specified range.
Since a Variant
can represent different data types, you could loose information if you would assign a cell's value to -- for instance -- a variable of type String
.
The mere fact that there is data type information in a Variant
already means you lose that type of information. If for instance the original type was numeric and you store it in a String
variable, there is no way to know from that string value what the original data type was. You could also lose precision (on Date
milliseconds for instance).
Furthermore, a Variant
type value cannot always be cast to the data type of your variable, and so you could get a Type mismatch error. In practice this often happens with the Error
sub data type.
Only when you know beforehand what the data type is of a certain cell's value, it would be good to define your receiving variable in that data type.
Not strictly answering your question, but thought I'd add this for reference anyway.
With native Excel functions you can usually provide either a range object or a value directly to a function. For example, you can either write =AVERAGE(A1,A2,A3)
or =AVERAGE(10,20,30)
. If you want to do something similar for any user defined functions, you will need to check the type of object passed to your function:
Function test(input As Variant)
Dim var As Variant
If TypeName(input) = "Range" Then
var = input.Value
Else
var = input
End If
You may also want to check for other objects if your function can accept them, but doing this will make your functions behave more like users expect them to.

- 1,015
- 1
- 9
- 25