Visual Basic

Using the Variant as a General Numeric Data Type

Don't get sidetracked by irrelevant machine-specific details. Almost all the time, we want to deal with numbers. For example, consider your thought process when you choose between declaring a variable to be of type Integer or type Long. You might consider what the likely values of the variable are going to be, worry a little bit about the effect on performance or memory usage, and maybe check to see how you declared a similar variable elsewhere so that you can be consistent. Save time-get into the habit of declaring all these variables as Variants.


All variables in my code are either Variants or references to classes. Consequently, a lot of code starts to look like this.

Dim Top As Variant
  Dim Left As Variant
  Dim Width As Variant
  Dim Height As Variant
After a time I started to take advantage of the fact that Variants are the default, so my code typically now looks like this:
Dim Top, Left, Width, Height
I see no problem with this, but your current Visual Basic coding standards will more than likely prohibit it. You might think about changing them.

Variants do not always work well when passed by reference, and can give rise to some hard-to-spot bugs. The problem is illustrated in the following example:

Private Sub Form_Load()
      Dim i As Integer
      i = 3
      subByVal i
      subByRef i
  End Sub
  Private Sub subByVal(ByVal x As Variant)
      x = 6.4
      Debug.Print x     'shows 6.4
  End Sub
  Private Sub subByRef(x As Variant)
      x = 6.4
      Debug.Print x     'shows 6
  End Sub

Notice that the only difference between the procedures subByVal and subByRef is that the parameter is passed ByVal in subByVal and ByRef in subByRef. When subByVal is called, the actual parameter i is of type Integer. In subByVal, a new parameter x is created as a Variant of subtype Integer, and is initialized with the value 3. In other words, the subtype of the Variant within the procedure is defined by the type of the variable that the procedure was actually called with. When x is then set to a value of 6.4, it converts to a Variant of subtype Double with value 6.4. Straightforward.

When subByRef is called, Visual Basic has a bit more of a problem. The Integer is passed by reference, so Visual Basic cannot allow noninteger values to be placed in it. Instead of converting the Integer to a Variant, Visual Basic leaves it as an Integer. Thus, even in the procedure subByRef itself, where x is declared as a Variant, x is really an Integer. The assignment of x = 6.4 will result in an implicit CInt call and x ends up with the value 6. Not so straightforward.

Procedures like subByVal are powerful because they can perform the same task, whatever the data type of the actual parameters. They can even perform different tasks depending on the type of the actual parameter, though this can get confusing.

Procedures like subByRef lead to bugs-avoid them by avoiding passing by reference.