Под полным типом переменной подразумевается информация, которую вы получаете в ближайшем окне:
Я хочу динамически определять информацию о типе с помощью VBA. Функция TypeName()
не делает то, что я хочу, так как она возвращает подтип варианта и не различает, например. переменная варианта, содержащая диапазон, переменную объекта, содержащую диапазон, и переменную диапазона, содержащую диапазон.
В качестве предварительного шага я написал функцию, которая определяет, передается ли ему вариант. Он работает, используя семантику pass-by-reference. Код делает вещи со своим аргументом, которые могут быть выполнены только с вариантом и, таким образом, вызывают ошибку, если переданная переменная на самом деле не вариант:
Function IsVariant(var As Variant) As Boolean
Dim temp As Variant
Dim isVar As Boolean
If IsObject(var) Then
Set temp = var
Else
temp = var
End If
On Error Resume Next
Set var = New Collection
var = "test"
If Err.Number > 0 Then
isVar = False
Else
isVar = True
End If
On Error GoTo 0
If IsObject(temp) Then
Set var = temp
Else
var = temp
End If
IsVariant = isVar
End Function
Основываясь на этом, я написал:
Function FullType(var As Variant) As String
If IsVariant(var) Then
FullType = "Variant/" & TypeName(var)
Else
FullType = TypeName(var)
End If
End Function
Код тестирования:
Sub TestTypes()
Dim R As Range
Dim Ob As Object
Dim i As Integer
Dim v1 As Variant
Dim v2 As Variant
v1 = 10
i = 10
Set v2 = Range("A1")
Set Ob = Range("A2")
Set R = Range("A3")
Debug.Print "v1: " & FullType(v1)
Debug.Print "i: " & FullType(i)
Debug.Print "v2: " & FullType(v2)
Debug.Print "Ob: " & FullType(Ob)
Debug.Print "R: " & FullType(R)
End Sub
Вывод:
v1: Variant/Integer
i: Integer
v2: Variant/Range
Ob: Range
R: Range
Это почти то, что я хочу - но не различает переменную объекта, содержащую диапазон, и переменную диапазона, содержащую диапазон. Я попытался написать функцию под названием IsTypeObject
, которая работает аналогично IsVariant
, но не может заставить ее работать:
Function IsTypeObject(var As Variant) As Boolean
Dim temp As Variant
Dim isGeneric As Boolean
If (Not IsObject(var)) Or IsVariant(var) Then
IsTypeObject = False
Exit Function
End If
Set temp = var
On Error Resume Next
Set var = New Collection
Set var = ActiveWorkbook
If Err.Number > 0 Then
isGeneric = False
Else
isGeneric = True
End If
On Error GoTo 0
Set var = temp
IsTypeObject = isGeneric
End Function
Тест:
Sub test()
Dim R As Range
Set R = Range("A1")
Debug.Print IsTypeObject(R)
End Sub
Но это печатает True
, хотя я думаю, что одна и та же семантика pass-by-reference, которая делает работу IsVariant
, также должна работать IsTypeObject
(вы не можете назначить коллекцию диапазону). Я пробовал различные твики, но не могу отличить общие переменные объекта и конкретные переменные объекта, такие как переменные диапазона.
Итак - любые идеи о том, как динамически получить полный тип переменной? (Мотивация является частью утилиты debug-log)