如果用[5]这样的方括号写一个数字是什么意思

Fun*_*mas 9 vba

我正在研究一个传统的VBA/Excel应用程序,偶然发现了一些代码行,其中一个长字符串(从文件中读取)被分割成碎片.这些行看起来像这样:

 Range("E16").Value = Mid(line, 49, [6])
Run Code Online (Sandbox Code Playgroud)

显然,写作[6]意味着需要6个字符,但我从来没有看到这种语法在数字上加上方括号.

我做了一些测试,发现放置那些方括号对数字没有任何明显的影响

Dim x As Double
x = 5.1
Debug.Print [2], [3.1], [-5], x
Debug.Print [3.1] * [x] * [-5]

>>  2             3.1          -5             5.1 
>> -79.05 
Run Code Online (Sandbox Code Playgroud)

所以,没有截断,没有舍入,没有abs值.
我做了一些更多的测试来检查它是否有一些魔法,类似于在变量周围放置括号以防止修改通过引用传递的值,但事实并非如此:

    x = 5.1: test2 x: Debug.Print x
    x = 5.1: test2 (x): Debug.Print x
    x = 5.1: test2 [x]: Debug.Print x

Sub test2(ByRef y As Double)
    y = y * 2
End Sub

>> 10.2 
>> 5.1
>> 10.2
Run Code Online (Sandbox Code Playgroud)

很惊讶编译器甚至接受这种语法:使用这些括号是什么意思?

Mat*_*don 12

VBA/VB6中的方括号用于访问"外部标识符",即不合法的标识符.例如:

Public Enum Foo
    Some
    Thing
    [Some Thing] ' please don't do this
End Enum
Run Code Online (Sandbox Code Playgroud)

名称以下划线开头的隐藏成员:

Public Property Get NewEnum() As IUnknown
    Set NewEnum = myCollection.[_NewEnum]
End Property
Run Code Online (Sandbox Code Playgroud)

然而,在这个问题的代码的上下文中,正如Scott所指出的那样,方括号基本上是简写符号[_Global].Evaluate,最终解析为Application.Evaluate...假设我们不在Worksheet模块的代码隐藏中,在这种情况下它是简写Worksheet.Evaluate- 并且都返回a Variant,这意味着任何链接的成员调用都是盲目的,在运行时解析的后期绑定调用:Option Explicit无法将您从错字中解救出来.

这就是为什么Rubberduck(一个开源VBIDE加载的项目,我管理/贡献)解决他们作为"运行时表达式":

Rubberduck的上下文相关工具栏将'A1'显示为'运行时表达式'

换句话说:

Range("E16").Value = Mid(line, 49, [6])
Run Code Online (Sandbox Code Playgroud)

也可以像这样写:

[E16] = Mid(line, [49], [6])
Run Code Online (Sandbox Code Playgroud)

...这可以说是可怕的代码,有大量冗余的隐式操作正在进行中.

永远不会有任何理由对一个整数文字进行方括号:它只不过是将Integer文字转换成一个相当迂回的方式Double(因为工作表的数值是Variant/Double):

Debug.Print TypeName(42)
Integer

Debug.Print TypeName([42])
Double
Run Code Online (Sandbox Code Playgroud)

使用显式转换可以做得更好:

Debug.Print TypeName(CDbl(42))
Double
Run Code Online (Sandbox Code Playgroud)

......甚至是(喘息)类型提示:

Debug.Print TypeName(42#)
Double
Run Code Online (Sandbox Code Playgroud)

  • 在Excel中值得注意的是,`Application.Evaluate`返回一个`Variant`,因此它有一个令人讨厌的小副作用,即隐式删除强类型.另一个副作用是数字的文字在传递给evaluate之前被隐式转换为`String`,因此你最终得到的数字取决于语言环境设置. (3认同)
  • 这是非常挑剔的,但在工作表的代码隐藏之外的隐式引用实际上访问`[_Global] .Evaluate()`,而不是`Application.Evaluate()`.我确定它解析为相同的实现,但是想要指出这一点,因为1)这是另一个隐式操作级别,2)当一个上下文中的`Evaluate()`执行X但在其他上下文中时,它可能会导致意外,是吗 (2认同)