The older I get, the more allergic I get to if-then-else trees, especially if they are nested...

(I rarely even use else nowadays.)
So my OCD kicked in and I remade your code to be more my style. I very much like to "peel away" thin cases as I like to go along, which I find makes the code not only simple to write, but also simple to understand when I later return to it. Might not be true for all coders though. (I do know that this style does irritate some forum members, who consider the principle "only one exit point in each function" important - I obviously don't agree to that. Not in an aggressive way, just in a "that's not my preferred style"-way.)
So, bottom line, this might not be an improvement, depending on your stance.
Sub GetColumnDataType_3(arrString() As String) As String
Dim r As Int
Dim strOld As String
For r = 0 To arrString.Length - 1
Try
If arrString(r) = Null Then Continue
If arrString(r).Length = 0 Then Continue
'this can make this about twice as fast if there is a sorted
'column and if the rows to be tested are not taken randomly
'-----------------------------------------------------------
If arrString(r) = strOld Then Continue
strOld = arrString(r)
If Not(IsNumber(arrString(r))) Then Return ("T")
If arrString(r).Contains(".") Or arrString(r).Contains(",") Then Return "R"
Catch
'this won't happen with a string array, but will work if a ResultSet is passed in a similar routine
Return "B"
End Try
Next
Return "I"
End Sub
Note: I have not tested this, not even once. It's possible a bug found its way in there, but it should be fairly simple to squash it if that's the case.
EDIT: Oh right, I should also mention that I didn't fully understand the magic values used and so I felt brave enough to cut out the last lines of code thinking, "it looks so small, surely it can't be important!" ;-)