当我运行以下宏时:
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
。
任何人都可以解释原因吗?
答案 0 :(得分:6)
它与VB存储整数的方式以及Len()
函数如何处理非字符串的参数有关。
当一个非字符串的数据类型传递给Len()
函数时,它返回用于存储数据的标称字节数(VB使用2个字节来存储整数)。请参阅documentation for the Len
function。
Len()
函数将自动转换变量变量(通过为变量赋值而不首先声明它来创建)作为字符串。返回没有改变,因为存储分配发生了变化(虽然它确实存在;变体需要16个字节的存储空间,最小)。由于隐式声明的变量实际上是变体类型,VB将根据情况自动更改其类型。在这种情况下,Len()
需要一个字符串,因此VB使变量成为一个字符串。
如果你的意图是返回整数值中的字符数,你可以使用Msgbox Len(Cstr(num))
将整数变量强制转换为Len
函数。
答案 1 :(得分:6)
Len
和 LenB
不只是普通的函数,它们是关键字,因此可以在 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