字符串是否为VBA中的数组?
例如,我可以像在C / C ++中那样迭代它吗?
做这样的事情:
char myArray[10];
for (int i = 0; i < length; i++)
{
cout << myArray[i];
}
VBA中的等价物是什么?它没有像我期望的那样表现。在VBA之前从未尝试过操纵过很多字符串! :)
答案 0 :(得分:13)
字符串是一个字节数组,如果您知道绕过字符串的双字节实现(或者Unicode,通常每个字符2个字节,但可以更多:并且它总是如此),您可以遍历它如果你的字符串来自VBA,那将是2字节。)
当我说是时,我的意思是:不需要进行类型转换,这样就可以了:
Public Sub TestByteString()
Dim strChars As String
Dim arrBytes() As Byte
Dim i As Integer
strChars = "The quick Brown Fox"
arrBytes = strChars
Debug.Print strChars
Debug.Print
For i = LBound(arrBytes) To UBound(arrBytes) Step 2
Debug.Print Chr(arrBytes(i)) & vbTab & "Byte " & i & " = " & arrBytes(i)
Next i
arrBytes(0) = Asc("?")
arrBytes(2) = Asc("!")
arrBytes(4) = Asc("*")
strChars = arrBytes
Debug.Print
Debug.Print strChars
Erase arrBytes
End Sub
您的输出将如下所示:
The quick Brown FoxT Byte 0 = 84 h Byte 2 = 104 e Byte 4 = 101 Byte 6 = 32 q Byte 8 = 113 u Byte 10 = 117 i Byte 12 = 105 c Byte 14 = 99 k Byte 16 = 107 Byte 18 = 32 B Byte 20 = 66 r Byte 22 = 114 o Byte 24 = 111 w Byte 26 = 119 n Byte 28 = 110 Byte 30 = 32 F Byte 32 = 70 o Byte 34 = 111 x Byte 36 = 120
?!* quick Brown Fox
请注意循环中的“第2步”:我正在丢弃所有其他字节,因为我知道它是普通的拉丁字符 - “ASCII”文本给不熟悉的人。
当你必须处理阿拉伯语和拼音文本时,它会变得很有趣:你永远不应该在现实世界的工作表中假设你总是要处理普通的美国ASCII,正如我在那个演示中所做的那样片。
有关更全面的示例,有更详细的解释,请从Excellerando尝试:
Writing an Excel range to a csv file: optimisations and unicode compatibility
字节数组优化位于此标题的下方:
字符串的基本特性似乎并不像它应该的那样广为人知:它不是你在代码中经常使用的东西,而是Unicode和非拉丁字母表中的许多问题。当人们对代码中的变量有更深入的了解时,人们会变得更容易。
答案 1 :(得分:12)
它不是数组,但您可以使用MID
Sub test()
Dim strSentence As String
Dim lngCount As Long
strSentence = "This is a string"
For lngCount = 1 To Len(strSentence)
Debug.Print Mid(strSentence, lngCount, 1)
Next lngCount
End Sub
另请参阅Mat's Mug answer了解其他优点。
实际上有第二种方法来遍历字符串,即将字符串转换为单位数字符串数组然后遍历它们。为此,我们必须将原始字符串转换为unicode格式,以便可以将Null字符作为分隔符。这是一个可重复的例子:
Sub test2()
Dim strSentence As String
Dim lngCount As Long
Dim strArray() As String
strSentence = "This is a string"
strSentence = StrConv(strSentence, vbUnicode)
strArray = Split(strSentence, vbNullChar)
For lngCount = 0 To UBound(strArray)
Debug.Print strArray(lngCount)
Next lngCount
End Sub
出于好奇,我比较了两种方法(使用Mat的Mid版本,速度更快):
Sub test_sub()
Dim strTest(1 To 5000) As String
Dim lngStringIter As Long
Dim lngChars As Long, dblTick As Double
' Generate some long strings first
For lngStringIter = 1 To 5000
strTest(lngStringIter) = vbNullChar
For lngChars = 1 To 10
strTest(lngStringIter) = strTest(lngStringIter) & _
Chr(Int((90 - 65 + 1) * Rnd + 65)) & strTest(lngStringIter)
Next lngChars
Next lngStringIter
' Lets see what happens..
dblTick = CDbl(Now())
For lngStringIter = 1 To 5000
test strTest(lngStringIter)
Next lngStringIter
Debug.Print "Time Mid: ", CDbl(Now()) - dblTick
dblTick = CDbl(Now())
For lngStringIter = 1 To 5000
test2 strTest(lngStringIter)
Next lngStringIter
Debug.Print "Time Split: ", CDbl(Now()) - dblTick
End Sub
结果:
Time Mid: 4.62962998426519e-05
Time Split: 1.15740767796524e-05
所以看起来Split方法有点快。
VBA字符串实现为BSTR datatype。可以在here和here找到此数据类型的更多信息。
答案 2 :(得分:11)
Mid
用于在任何字符串中获取n th 字符,但返回Variant
,这会导致隐式转换为String
。
使用“强类型”版本:Mid$
代替。
答案 3 :(得分:5)
我认为VBA不允许您将字符串视为数组而不进行转换。
但是,您可以使用MID
一次获取一个字符。
代码是OTTOMH
declare i as integer
declare strlen as int
strlen = Len (YourIncomingString)
for i = 0 to strlen
print Mid (YourIncomingString, i, 1)
答案 4 :(得分:4)
简单回答:不,字符串不是VBA中的对象。你必须使用mid和len函数在角色上分开它。
答案 5 :(得分:1)
仍然可以创建自己的自定义可枚举字符串。
可以使用这样的可枚举字符串:
config/application.rb
将此代码保存在名为
Dim es As EnumerableString Set es = New EnumerableString es.Value = ActiveCell.Value Dim ch As Variant For Each ch In es ActiveCell.Offset(1, 0).Activate ActiveCell.Value = ch Next ch
的文件中,并将其导入VBA项目。
EnumerableString.cls
Excel中的结果,例如ASCII,ANSI和Unicode UTF-8字符: