【问题标题】:VBA: Unexpected Behaviour of Variant Data TypeVBA:变体数据类型的意外行为
【发布时间】:2016-09-12 19:09:25
【问题描述】:

根据MSDN,对于 Variant 数据类型:

“数值数据可以是任何整数或实数值,负值从 -1.797693134862315E308 到 -4.94066E-324,正值从 4.94066E-324 到 1.797693134862315E308。”

但是,即使计算后的所有最终值都在可接受的范围内,以下代码也会出错:

Sub Test()

Dim v1, v2, v3, v4

v1 = 569847501 + 54678                  '  OKAY
v2 = 7784687414# + 98565821345#         '  OKAY
v3 = 7784687414# + 1132747441           '  OKAY
v4 = 1132747441 + 1788441323            '  FAILS

End Sub

MSDN 也指出:

” 但是,如果对包含 Byte、Integer、Long 或 Single 的 Variant 执行算术运算,结果超出原始数据类型的正常范围,则结果在 Variant 内提升为下一个更大的数据类型。 Byte 提升为 Integer,Integer 提升为 Long,Long 和 Single 提升为 Double。”

文档指出,当算术运算超出原始数据类型的正常范围时,应提升该类型。为什么v4 不升级为Double

【问题讨论】:

  • 请注意,这根本不是 Variant 独有的。 Dim d As Double : d = 1132747441 + 1788441323 做同样的事情。

标签: vba


【解决方案1】:

您正在使用不是变体的数字文字。尽管Byte 值默认为Integer 类型,但它们被编译器解释为容纳文字值的最小必要类型。

Debug.Print TypeName(1132747441) 'Long
Debug.Print TypeName(1788441323) 'Long

正如@ComIntern 指出的那样,您在表达式中分配了 2 个 long 的结果,表达式在分配给 Variant v4 之前溢出了

正如@dazedandconfused 所指出的,您可以将文字值强制转换为更合适的类型,表达式将计算,并且可以分配变体。

为了获得 Microsoft 为 Variant 类型记录的行为,您需要将文字值强制转换为变体,在表达式中使用它们之前。这两个变体都将包含 Longs,但您将获得文档声明的自动重新键入。

Sub Test()

  Dim v1, v2, v3, v4

  Debug.Print TypeName(1132747441) 'Long
  Debug.Print TypeName(1788441323) 'Long

  Dim v5, v6

  v5 = 1132747441
  v6 = 1788441323

  Debug.Print TypeName(v5) 'Long
  Debug.Print TypeName(v6) 'Long

  v4 = v5 + v6 'OKAY
  Debug.Print TypeName(v4) 'Double

  v4 = 0
  Debug.Print TypeName(v4) 'Integer

  v4 = CVar(1132747441) + CVar(1788441323) ' OKAY
  Debug.Print TypeName(v4) 'Double


  v1 = 569847501 + 54678                  '  OKAY
  v2 = 7784687414# + 98565821345#         '  OKAY
  v3 = 7784687414# + 1132747441           '  OKAY
  v4 = 1132747441 + 1788441323            '  FAILS

End Sub

【讨论】:

    【解决方案2】:

    来自https://support.microsoft.com/en-us/kb/199809 - 见粗体声明

    此语句会产生溢出错误,因为 24 * 24 * 60 = 34560,超过 2 字节整数 (32767) 的最大大小。 Visual Basic 不会计算整个表达式来检查 结果的大小,但继续使用 2 字节临时 计算的空间。如果您发生相同的溢出错误 将前面的值声明为常量并乘以常量。

    为了解决此问题,务必始终 在数值计算中使用它们时显式键入数字或 定义常量时。如果前面的表达式改为 以下:

    所以改成...

    v4 = 1132747441# + 1788441323#
    

    ...确实有效,但确实有气味。

    【讨论】:

      猜你喜欢
      • 2011-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-06
      • 1970-01-01
      • 2016-10-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多