- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
变量的完整类型是指您在即时窗口中获得的信息类型:
我想使用 VBA 动态确定类型信息。函数TypeName()
不做我想要的,因为它返回变体的子类型并且不区分例如一个变量变量保存一个范围,一个对象变量保存一个范围,一个范围变量保存一个范围。
作为初步步骤,我编写了一个函数来检测是否有变体传递给它。它通过利用传递引用语义来工作。该代码使用其参数执行只能使用变体完成的操作,因此如果传递的变量实际上不是变体,则会触发错误:
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
即使我认为相同的传递引用语义使
IsVariant
工作也应该使
IsTypeObject
工作(您不能将集合分配给范围)。我尝试了各种调整,但似乎无法区分通用对象变量和特定对象变量(例如范围变量)。
最佳答案
是的,您可以这样做:它需要对指针和“取消引用”的概念有一点了解......
这是执行此操作的代码:
Public Function VariantTypeName(ByRef MyVariant) As String
' Returns the expanded type name of a variable, indicating
' whether it's a simple data type (eg: Long Integer), or a
' Variant containing data of that type, eg: "Variant/Long"
Dim iType As Integer
Const VT_BYREF = &H4000&
CopyMemory iType, MyVariant, 2
' iType now contains the VarType of the incoming parameter
' combined with a bitwise VT_BYREF flag indicating that it
' was passed by reference. In other words, it's a pointer,
' not the data structure of the variable (or a copy of it)
' So we should have VT_BYREF - and we'd always expect to
' when MyVariant is a Variant, as variants are a structure
' which uses a pointer (or pointers) to the stored data...
' However, the VBA implementation of a variant will always
' dereference the pointer - all the pointers - passing us
' straight to the data, stripping out all that information
' about references...
If (iType And VT_BYREF) = VT_BYREF Then
' Bitwise arithmetic detects the VT_BYREF flag:
VariantTypeName = TypeName(MyVariant)
Else
' No VT_BYREF flag. This is a Variant, not a variable:
VariantTypeName = "Variant/" & TypeName(MyVariant)
End If
End Function
CopyMemory
API 函数的声明在后面几段)。
ByRef
中。和
ByVal
我们在声明函数时用于传入参数的标识符。
VarType
和
TypeName
检测我们已经被传递了一个值,或者一个对它的引用;甚至是对引用的引用,对引用的引用。
varType
从来没有告诉我们我们通过指针定义的连续地址通过几跳间接到达那里。
VT_BYREF
表示这是对存储数据类型的引用或指针,而不是数据本身。所以这段代码会可靠地告诉你你的 var 类型,当我们不希望它不是时,稍微横向思考一下克服 VBA 是有帮助的:
Public Function DereferencedType(ByRef MyVar) As Long
Dim iType As Integer
Const VT_BYREF = &H4000&
' The first two bytes of a variable are the type ID with a
' bitwise OR to VT_BYREF if we were passed the variable by
' reference... Which is exactly what this function does:
CopyMemory iType, MyVar, 2
DereferencedType = iType ' Mod VT_BYREF
'Use "Mod VT_BYREF" to separate out the type if you want
End Function
乍一看,这个函数似乎是弄巧成拙:我通过引用传递变量 - 变体或简单类型,所以它总是会与
VT_BYREF
结合使用。 .无论如何,我已经注释掉了“模”算法......
Dim str1 As String
str1 = "One Hundred"
Debug.Print "String Variable: " & DereferencedType(str1)
...你得到输出
vbString OR VT_BYREF
:
String Variable: 16392
Dim varX As Variant
varX = "One Hundred"
Debug.Print "String Variant: " & DereferencedType(varX)
...你得到输出:
String Variant: 8
VT_BYREF
对返回的值进行 OR 或 NOT 操作编码。 , 为您的 Variant/String 和 Variant/Long 输出的扩展字符串描述符提供“Variant/”标签。
VariantTypeName
]
#If VBA7 And Win64 Then ' 64 bit Excel under 64-bit Windows
' Use LongLong and LongPtr
Private Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(Destination As Any, _
Source As Any, _
ByVal Length As LongLong)
#ElseIf VBA7 Then ' 64 bit Excel in all environments
' Use LongPtr only, LongLong is not available
Private Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(Destination As Any, _
Source As Any, _
ByVal Length As Long)
#Else ' 32 bit Excel
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(Destination As Any, _
Source As Any, _
ByVal Length As Long)
#End If
VarX is set equal to a range object variable: varX: type=8204 Range Dereferenced Type=9 rng1: type=8204 Range Dereferenced Type=16393
VarX is set equal to a range object's value, a 2-dimensional array: varX: type=8204 Variant() Dereferenced Type=8204 arr1: type=8204 Variant() Dereferenced Type=8204
The array variable is erased to Empty(). Inspect varX: varX: type=8204 Variant() Dereferenced Type=8204 arr1: type=8204 Variant() Dereferenced Type=8204
VarX is set equal to an 'object' variable, which has been set to a range: varX: type=8204 Range Dereferenced Type=9 obj1: type=8204 Range Dereferenced Type=16393
Here's the code that generated that, and the full output:
Public Sub TestVar()
Dim varX As Variant
Dim str1 As String
Dim lng1 As Long
Dim rng1 As Excel.Range
Dim arr1 As Variant
Dim obj1 As Object
Debug.Print "Uninitialised:"
Debug.Print
Debug.Print vbTab & "varX: type=" & VarType(varX) & vbTab & vbTab & TypeName(varX) & vbTab & "Dereferenced Type=" & DereferencedType(varX)
Debug.Print vbTab & "str1: type=" & VarType(str1) & vbTab & vbTab & TypeName(str1) & vbTab & "Dereferenced Type=" & DereferencedType(str1)
Debug.Print vbTab & "lng1: type=" & VarType(lng1) & vbTab & vbTab & TypeName(lng1) & vbTab & "Dereferenced Type=" & DereferencedType(lng1)
Debug.Print
varX = "One Hundred"
str1 = "One Hundred"
lng1 = 100
Debug.Print "varX and str1 are populated with the same literal:"
Debug.Print
Debug.Print vbTab & "varX: type=" & VarType(varX) & vbTab & vbTab & TypeName(varX) & vbTab & "Dereferenced Type=" & DereferencedType(varX)
Debug.Print vbTab & "str1: type=" & VarType(str1) & vbTab & vbTab & TypeName(str1) & vbTab & "Dereferenced Type=" & DereferencedType(str1)
Debug.Print vbTab & "lng1: type=" & VarType(lng1) & vbTab & vbTab & TypeName(lng1) & vbTab & "Dereferenced Type=" & DereferencedType(lng1)
Debug.Print
varX = 100
lng1 = 100
Debug.Print "varX and lng1 are populated with the same integer:"
Debug.Print
Debug.Print vbTab & "varX: type=" & VarType(varX) & vbTab & vbTab & TypeName(varX) & vbTab & "Dereferenced Type=" & DereferencedType(varX)
Debug.Print vbTab & "str1: type=" & VarType(str1) & vbTab & vbTab & TypeName(str1) & vbTab & "Dereferenced Type=" & DereferencedType(str1)
Debug.Print vbTab & "lng1: type=" & VarType(lng1) & vbTab & vbTab & TypeName(lng1) & vbTab & "Dereferenced Type=" & DereferencedType(lng1)
Debug.Print
varX = str1
Debug.Print "VarX is set equal to str1:"
Debug.Print
Debug.Print vbTab & "varX: type=" & VarType(varX) & vbTab & vbTab & TypeName(varX) & vbTab & "Dereferenced Type=" & DereferencedType(varX)
Debug.Print vbTab & "str1: type=" & VarType(str1) & vbTab & vbTab & TypeName(str1) & vbTab & "Dereferenced Type=" & DereferencedType(str1)
Debug.Print
varX = lng1
Debug.Print "VarX is set equal to lng1:"
Debug.Print
Debug.Print vbTab & "varX: type=" & VarType(varX) & vbTab & vbTab & TypeName(varX) & vbTab & "Dereferenced Type=" & DereferencedType(varX)
Debug.Print vbTab & "lng1: type=" & VarType(lng1) & vbTab & vbTab & TypeName(lng1) & vbTab & "Dereferenced Type=" & DereferencedType(lng1)
Debug.Print
Set varX = ActiveSheet.Range("A1:C3")
Debug.Print "VarX is set equal to a range:"
Debug.Print
Debug.Print vbTab & "varX: type=" & VarType(varX) & vbTab & vbTab & TypeName(varX) & vbTab & "Dereferenced Type=" & DereferencedType(varX)
Debug.Print
Set rng1 = ActiveSheet.Range("A1:C3")
Set varX = Nothing
Set varX = rng1
Debug.Print "VarX is set equal to a range object variable:"
Debug.Print vbTab & "varX: type=" & VarType(varX) & vbTab & vbTab & TypeName(varX) & vbTab & "Dereferenced Type=" & DereferencedType(varX)
Debug.Print vbTab & "rng1: type=" & VarType(rng1) & vbTab & vbTab & TypeName(rng1) & vbTab & "Dereferenced Type=" & DereferencedType(rng1)
Debug.Print
arr1 = rng1.Value2
Set varX = Nothing
varX = arr1
Debug.Print "VarX is set equal to a range object's value, a 2-dimensional array:"
Debug.Print vbTab & "varX: type=" & VarType(varX) & vbTab & vbTab & TypeName(varX) & vbTab & "Dereferenced Type=" & DereferencedType(varX)
Debug.Print vbTab & "arr1: type=" & VarType(rng1) & vbTab & vbTab & TypeName(arr1) & vbTab & "Dereferenced Type=" & DereferencedType(arr1)
Debug.Print
Erase arr1
Debug.Print "The array variable is erased to Empty(). Inspect varX:"
Debug.Print vbTab & "varX: type=" & VarType(varX) & vbTab & vbTab & TypeName(varX) & vbTab & "Dereferenced Type=" & DereferencedType(varX)
Debug.Print vbTab & "arr1: type=" & VarType(rng1) & vbTab & vbTab & TypeName(arr1) & vbTab & "Dereferenced Type=" & DereferencedType(arr1)
Debug.Print
Set obj1 = ActiveSheet.Range("A1:C3")
Set varX = Nothing
Set varX = obj1
Debug.Print "VarX is set equal to an 'object' variable, which has been set to a range:"
Debug.Print vbTab & "varX: type=" & VarType(varX) & vbTab & vbTab & TypeName(varX) & vbTab & "Dereferenced Type=" & DereferencedType(varX)
Debug.Print vbTab & "obj1: type=" & VarType(rng1) & vbTab & vbTab & TypeName(obj1) & vbTab & "Dereferenced Type=" & DereferencedType(obj1)
Debug.Print
End Sub
关于vba - 确定变量的完整类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33941363/
我正在使用 Selenium Web 驱动程序 3.0,并且想要从打开的两个对话框(一个在后台,第二个在前台)的 Activity 对话框中单击“确定”按钮。如何从 html 下面的父 div 单击前
actions: [ FlatButton( onPressed: () {
我有一个问题有点超出我的范围(我真的很高兴我是 Beta)涉及重复项(所以 GROUP BY, HAVING, COUNT),通过将解决方案保留在 SQLite 附带的标准函数中而变得更加复杂。我正在
使用DBI是否可以确定SELECT语句的已执行语句句柄是否返回任何行而不从中获取行? IE。就像是: use DBI; ... my $sth = $dbh->prepare("SELECT ..."
是否可以为“确定”和“关闭”按钮指定回调函数? 如果是JQuery Modal,则可以在初始化时使用按钮字典指定回调函数。 Semantic-ui模态是否提供类似的功能?按下确定后,我该如何寻求其他逻
我想阅读警报中的消息。 示例:如果警报显示“错误的电子邮件地址”。怎么读呢?意味着我想将该消息存储在字符串中。 如何在“警报”中单击“确定”...?? 如何使用 Selenium 来做到这一点? 最佳
我有一个删除按钮: 我试图首先查明是否已选择一个网站,如果已选择一个网站,我需要确定是否已选择一个或多个列表项,如果是,则继续删除这些项目。 我的 if 语句不断返回“您必须首先选择您的列表”,即使它
部分出于好奇——我们想知道在我们的应用程序中发生了什么——部分是因为我们需要在我们的代码中找到一些潜在的问题,我喜欢在我们的网络应用程序运行时跟踪一些一般值。这尤其包括某些对象图的分配内存。 我们的应
我将 SweetAlert 与 Symfony 结合使用,我希望用户在完成删除操作之前进行确认。 发生的情况是,当用户单击删除按钮时,SweetAlert 会弹出,然后立即消失,并且该项目被删除。 在
我们有一个应用程序可以生成不包括字母 O 的随机基数 35 [0-9A-Z]。我正在寻找一种解决方案来查找包含任何淫秽英语单词的代码,而无需搜索包含 10,000 个条目的列表每个生成的代码。每秒生成
这是我做的: #include #include int betweenArray(int a, int b){ int *arr,i,range; range = b - a +
我知道如何创建 警报和确认框,但我不知道如何做的是实际单击“确定”。我有一个弹出确认框的页面。 我想使用 Java Script 插件单击“确定”。基本上,我希望我的代码单击页面上的链接,然后在出现提
代码: swal('Your ORDER has been placed Successfully!!!'); window.location="index.php"; 甜蜜警报工
>>> import re >>> s = "These are the words in a sentence" >>> regex = re.compile('are|words') >>> [m
使用确定的理想散列函数给出随机期望线性时间算法两个数组 A[1..n] 和 B[1..n] 是否不相交,即 A 的元素是否也是 B 的元素。 谁能告诉我如何做到这一点,甚至如何开始考虑它? 最佳答案
我在计算机科学课上有这段代码: int input=15; while (input < n ) { input = input *3;} 这段代码有 log3(n/15) 次循环的上限。我们怎样才能
我有一个允许 2 位玩家玩 TicTacToe 的程序。在每个玩家移动之后,它应该在那个点显示棋盘并返回一个名为 Status 的枚举,显示玩家是否应该继续,如果玩家赢了,还是平局。但是,该算法要么返
给定一个 y 值数组,例如 [-3400, -1000, 500, 1200, 3790],我如何确定“好的”Y 轴标签并将它们放置在网格上? ^ ---(6,000)-|---
假设我有一个检查用户登录的 SQL 语句: SELECT * FROM users WHERE username='test@example.com', password='abc123', expi
teradata中有返回表中哪一列被定义为主索引的命令吗?我没有制作一些我正在处理的表,也没有尝试优化我对这些表的连接。谢谢! 最佳答案 有dbc.IndicesV,其中IndexNumber=1表示
我是一名优秀的程序员,十分优秀!