【问题标题】:Why does VarType() ALWAYS return 8204 for Arrays为什么 VarType() 总是为数组返回 8204
【发布时间】:2020-11-25 09:07:21
【问题描述】:

在 VBScript 的 VarType 函数的 VarType MSDN Microsoft 文档中,它说(加粗强调):

"备注 VarType 函数从不返回 Array 的值 本身。它总是被添加到某个其他值以指示一个数组 特定类型。 Variant 的值仅在具有 已添加到 Array 的值中,以指示 VarType 函数是一个数组。 例如,返回的值 整数数组计算为 2 + 8192 或 8194。如果一个对象有 一个默认属性,VarType(object) 返回其默认的类型 属性。”

但是

代码如

Dim A,I1, I2, I3
I1 = 1
I2 = 2
I3 = 3
A = Array(I1,I2,I3)

Dim A2
A2 = Split("Test,Test,Test",",")

AT = VarType(A)
AT2 = VarType(A2)
IT1 = VarType(I1)
IT2 = VarType(I2)
IT3 = VarType(I3)

WScript.Echo IT1
WScript.Echo IT2
WScript.Echo IT3
WScript.Echo AT & " - 8192 = " & AT - 8192
WScript.Echo AT2 & " - 8192 = " & AT2 - 8192
WScript.Echo CStr(VarType(A(2)))

返回

2 
2
2
8204 - 8192 = 12 
8204 - 8192 = 12
2

I1 - I3 ALL 返回其正确的 vbInteger 并且,当在其数组中单独引用时,也返回 vbInteger,但该数组坚持认为它是 vbVariant 的数组。

除非我在这里完全遗漏了一些东西,否则似乎在文档中没有办法创建一个数组,其中所有的项目都是相同的类型,并且VarType 将其识别为除了数组之外的任何东西vbVariant.

我觉得这应该已经是一个问题,但是我在这里进行了空搜索,所以如果我错过了现有问题,请随时链接。

【问题讨论】:

    标签: arrays vbscript


    【解决方案1】:

    来自documentation

    在 VBScript 中,变量始终是一种基本数据类型, 变体。

    变量中包含的数据可以是任何类型,但变量本身总是Variant 类型。使用VarType 检查数组位置的内容将返回包含的数据类型。但数组本身是Variant 类型的“单元”的复合体

    因此,在您的情况下,VarType 将返回 vbArray (8192) + vbVariant (12) = 8204

    【讨论】:

    • 文档应该说:“Arrays 的类型总是vbVariant + vbArray”。非数组变量和数组元素可以是任何 Variant 子类型。
    • @Bond,不,文档是正确的。 VarType 返回数组的类型。您不能在 VBScript 本身中创建整数数组,但对属性的查询或对 COM 组件的方法调用可以返回它,VarType 将正确识别数据类型。
    • 对。我认为我们在同一页上。 VBScript 本身 只能创建vbArray + vbVariant 数组(Array() 函数、Dim、VBScript 函数返回的数组等),无论元素是否同质。我并不是说你不能以其他方式得到一个非 vbVariant 数组。 ADO Stream 对象,例如可以返回 vbArray + vbByte (UI1) 数组。
    • 我只是认为您回答中的文档引用令人困惑,因为它没有解释为什么 VBScript 不能创建除 vbVariant 之外的任何其他类型的数组。当然一切都是一个变体(正如你的报价所说),你可以用VarType查询它的子类型,但你的报价没有解释为什么不能为特定的变体子类型创建arrays
    • @TofuBug 这不是关于“获得正确的类型”。这是关于创建正确的类型。 VBScript 本质上不能创建 vbArray + vbVariant 以外的任何东西,即使您的数组只包含vbInteger 或其他一些Variant 子类型。
    【解决方案2】:

    这只是文档中的一个错误:

    ==>type D:\VB_scripts\SO\30511987.vbs
    option explicit
    Dim ii, aA(3)
    aA(1)=5
    aA(2)="string"
    aA(3)=Now
    
    Wscript.Echo "array", VarType(aA), TypeName(aA)
    
    For ii=0 To UBound(aA)
      Wscript.Echo "aA(" & CStr(ii) & ")", VarType(aA(ii)), TypeName(aA(ii))
    Next
    
    ==>cscript D:\VB_scripts\SO\30511987.vbs
    array 8204 Variant()
    aA(0) 0 Empty
    aA(1) 2 Integer
    aA(2) 8 String
    aA(3) 7 Date
    
    ==>
    

    【讨论】:

    • 我什至从未想到过“显而易见”的答案。
    • 不,文档中没有错误。假设您在 COM 组件中有一个属性,其定义类似于 Public Property Get Items() as Integer()。返回的数组将是整数类型,VarType 会将其报告为8194。但是从 VBScript 创建的数组总是 Variant
    • @MCND 有一个错误(或者是 错误),请参阅您提供的链接中的 2 + 8192 示例...但是,在您回答之前,我从来没有了解 vbVariant 常量描述:12 Variant (used only with arrays of Variants)。我确实知道,但现在我明白了!!!谢谢..
    • @MCND 这就是为什么我给出了一个 heterogeneous 数组的示例,而 homogeneous 则在那个错误的2 + 8192 示例中提及跨度>
    • @JosefZ,我同意。它至少是模棱两可的... for an array of integers ... 的使用会导致混淆。
    【解决方案3】:

    虽然 VBscript 缺少声明“变体的变体数组”以外的任何类型的数组的语法,但它的变体类型和变体数组类型不受此限制。变体类型是 COM 类型,AKA 是 Visual Basic 4+ 类型,AKA 是 Excel xloper 的版本(Excel 单元格类型)。

    您可以通过在外部创建的数组上使用 VBscript "vartype" 来返回任何其他类型的数组类型:

    obj = CreateObject("System.IO.MemoryStream")
    obj.SetLength 0
    obj.WriteByte 1
    obj.WriteByte 2
    
    A = obj.ToArray() 
    wscript.echo vartype(A)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-25
      • 2021-01-24
      • 2012-03-07
      • 2014-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多