1

I need to tell if variant Array element is a number as string or number as integer. When I run this sub:

Public Sub arrTest1()

    Dim fldValues() As Variant

    fldValues = Array("1", 1)
        
    For i = LBound(fldValues) To UBound(fldValues)
        Debug.Print fldValues(i), IsNumeric(fldValues(i))
    Next i

End Sub

I get this result in immediate window:

1             True
 1            True

because of indentation I am assuming that VBA knows the difference, but both appear numeric. How do I tell them apart?

1
  • 1
    The left-aligned is a String, the one with a leading space is numeric - that space is there to accommodate a - negative sign. Commented May 12, 2021 at 14:06

2 Answers 2

3

One option is TypeName:

Debug.Print fldValues(i), TypeName(fldValues(i))

Output:

1             String
 1            Integer

Another (better) option is VarType; VarType(fldValues(i)) would return:

1              8 
 1             2 

where 8 corresponds to vbString and 2 corresponds to vbInteger.

Sign up to request clarification or add additional context in comments.

2 Comments

@Monardo note that VarType is the superior option, by far. Avoid "stringly-typed" solutions when possible.
0

A good solution is a robust library which covers these awkwardnesses in VBA. So here's a starter for 10.

Module Types

Option Explicit

Public Const NumberTypes As String = "Byte,Currency,Date,Decimal,Double,Integer,Long,LongLong,LongPtr,Single"
    

'@Description("Returns true if the variant is empty or contains an uninitialised array")
Public Function VarEmpty(ByVal ipVariant As Variant) As Boolean

    If IsArray(ipVariant) Then
    
        VarEmpty = UBound(ipVariant) = -1
        
    Else
    
        VarEmpty = IsEmpty(ipVariant)
        
    End If
    
End Function

'@Description("Sugar for 'Is Not x = nothing'")
Public Function IsSomething(ByVal ipValue As Object) As Boolean
    IsSomething = Not ipValue Is Nothing
End Function


Public Function IsBoolean(ParamArray ipArgs() As Variant) As Boolean
    IsBoolean = GetVarType(CVar(ipArgs), vbBoolean)
End Function

Public Function IsByte(ParamArray ipArgs() As Variant) As Boolean
    IsByte = GetVarType(CVar(ipArgs), vbByte)
End Function

Public Function IsCurrency(ParamArray ipArgs() As Variant) As Boolean
    IsCurrency = GetVarType(CVar(ipArgs), vbCurrency)
End Function

Public Function IsDataObject(ParamArray ipArgs() As Variant) As Boolean
    IsDataObject = GetVarType(CVar(ipArgs), vbDataObject)
End Function

Public Function IsDate(ParamArray ipArgs() As Variant) As Boolean
    IsDate = GetVarType(CVar(ipArgs), vbDate)
End Function

Public Function IsDecimal(ParamArray ipArgs() As Variant) As Boolean
    IsDecimal = GetVarType(CVar(ipArgs), vbDecimal)
End Function

Public Function IsDouble(ParamArray ipArgs() As Variant) As Boolean
    IsDouble = GetVarType(CVar(ipArgs), vbDouble)
End Function

Public Function IsInteger(ParamArray ipArgs() As Variant) As Boolean
    IsInteger = GetVarType(CVar(ipArgs), vbInteger)
End Function

Public Function IsLong(ParamArray ipArgs() As Variant) As Boolean
    IsLong = GetVarType(CVar(ipArgs), vbLong)
End Function

Public Function IsLongLong(ParamArray ipArgs() As Variant) As Boolean
    IsLongLong = GetVarType(CVar(ipArgs), vbLongLong)
End Function

'Public Function IsLongPtr(ParamArray ipArgs() As Variant) As Boolean
'    IsLongPtr = IsVarType(CVar(ipArgs), vbLongptr)
'End Function

Public Function IsSingle(ParamArray ipArgs() As Variant) As Boolean
    IsSingle = GetVarType(CVar(ipArgs), vbSingle)
End Function

Public Function IsString(ParamArray ipArgs() As Variant) As Boolean
    IsString = GetVarType(CVar(ipArgs), vbString)
End Function

Public Function IsUserDefinedType(ParamArray ipArgs() As Variant) As Boolean
    IsUserDefinedType = GetVarType(CVar(ipArgs), vbUserDefinedType)
End Function

'@Description("Returns true if the values in ipArgs() are of types listed in ipTypes")
Public Function IsOfType(ByVal ipTypes As String, ParamArray ipArgs() As Variant) As Boolean

    IsOfType = False
    
    Dim myItem As Variant
    For Each myItem In ipArgs
    
        If InStr(ipTypes, TypeName(myItem)) = 0 Then Exit Function
    
    Next
    
    IsOfType = True
    
End Function
    
Private Function GetVarType(ByVal ipArgs As Variant, ByVal ipVartype As VbVarType) As Boolean

    GetVarType = False
    
    Dim myItem As Variant
    For Each myItem In ipArgs
    
        If Not VarType(myItem) = ipVartype Then Exit Function
        
    Next
    
    GetVarType = True

End Function


End Module

So your code would become

Public Sub arrTest1()

    Dim fldValues() As Variant

    fldValues = Array("1", 1)
        
    For i = LBound(fldValues) To UBound(fldValues)
        Debug.Print fldValues(i), IsOfType(NumberType,fldValues(i))
        'Or 
        'Debug.Print fldvalues(i),IsInteger(fldValues(i)
    Next i

End Sub

2 Comments

Honestly, I don't see any benefit from doing the like varType(fldValues(i)) = vbString, and I cannot see any awkwardness in there.
Not sure I understand that comment

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.