为什么Len和VBA.Len会返回不同的结果?

时间:2015-04-20 18:36:36

标签: vba excel-vba excel

当我运行以下宏时:

Sub try()

Dim num As Integer

num = 123

MsgBox Len(num)

MsgBox VBA.Len(num)

End Sub

第一个Msgbox显示2,第二个Msgbox显示3。 如果我删除第一行Dim num As Integer,则两个框都会显示3。 任何人都可以解释原因吗?

3 个答案:

答案 0 :(得分:6)

它与VB存储整数的方式以及Len()函数如何处理非字符串的参数有关。

当一个非字符串的数据类型传递给Len()函数时,它返回用于存储数据的标称字节数(VB使用2个字节来存储整数)。请参阅documentation for the Len function

Len()函数将自动转换变量变量(通过为变量赋值而不首先声明它来创建)作为字符串。返回没有改变,因为存储分配发生了变化(虽然它确实存在;变体需要16个字节的存储空间,最小)。由于隐式声明的变量实际上是变体类型,VB将根据情况自动更改其类型。在这种情况下,Len()需要一个字符串,因此VB使变量成为一个字符串。

如果你的意图是返回整数值中的字符数,你可以使用Msgbox Len(Cstr(num))将整数变量强制转换为Len函数。

答案 1 :(得分:6)

LenLenB 不只是普通的函数,它们是关键字,因此可以在 list of VBA keywords 中找到(虽然 LenB 仅在您点击到Len)。
Mid 将是这种伪装成函数的关键字的另一个例子,而例如Left 根本不在列表中,因为那只是一个普通的函数。

它必须是一个关键字,因为它的工作之一是执行确定变量存储大小的编译时任务。例如。对于私有的用户定义类型,普通函数根本无法做到这一点:

Private Type foo
    a As Long
    b As String
End Type

Sub TestLens()
    Dim f As foo
  
    MsgBox Len(f)     ' OK
    MsgBox VBA.Len(f) ' Compile time error
End Sub

当您在 VBA.Len 上按 Shift+F2 时,对象浏览器会将您带到 Len(f),这一事实既正确又具有误导性。
这里的 Len(f) 实际上并没有调用确定字符串大小的 VBA.Len 函数,它根本不能这样做,因为它需要将私有结构强制转换为 Variant。相反,它在编译时计算 foo 的大小,并将结果作为文字常量替换到可执行文件中。

在您的示例中,Len(num) 计算变量 num(即 2)的编译时大小并将常量 2 代入结果对象代码,而 VBA.Len(num)num值打包成 Variant 并将该变体传递给 VBA.Len,在那里它进一步转换为字符串 {{1 }} 并返回其长度。

答案 2 :(得分:0)

您可以创建自己的len函数:

Function CountChar(ByVal Mystring As String)
Dim alphabet As Variant

alphabet = Array("A", "a", "B", "b", "C", "c", "D", "d", "E", "e", "F", "f", "G", "g", "H", "h", _
"I", "i", "J", "j", "K", "k", "L", "l", "M", "m", "N", "n", "O", "o", "P", "p", "Q", "q", _
"R", "r", "S", "s", "T", "t", "U", "u", "V", "v", "W", "w", "X", "x", "Y", "y", "Z", "z", 0, 1, 2, 3 _
, 4, 5, 6, 7, 8, 9)

j = 0
For i = 0 To 61
' // Find alphabet and numbers then Replace with "-"
    Do While InStr(Mystring, alphabet(i))
        Mystring = Replace(Mystring, alphabet(i), "-")
        j = j + 1
    Loop
Next i
CountChar = j
d = MsgBox(Mystring)
End Function