Arrays 字符串是VBA中可以迭代的数组吗?
字符串是VBA中的数组吗 例如,我可以像在C/C++中一样迭代它吗 这样做:Arrays 字符串是VBA中可以迭代的数组吗?,arrays,vba,excel,Arrays,Vba,Excel,字符串是VBA中的数组吗 例如,我可以像在C/C++中一样迭代它吗 这样做: char myArray[10]; for (int i = 0; i < length; i++) { cout << myArray[i]; } charmyarray[10]; for(int i=0;i
char myArray[10];
for (int i = 0; i < length; i++)
{
cout << myArray[i];
}
charmyarray[10];
for(int i=0;i cout我认为VBA不允许在不转换字符串的情况下将其作为数组处理
但是,您可以使用MID
一次获取一个字符
代码是OTTOMH
declare i as integer
declare strlen as int
strlen = Len (YourIncomingString)
for i = 0 to strlen
print Mid (YourIncomingString, i, 1)
简单回答:不,字符串不是VBA中的对象。您必须在使用mid和len函数时按字符将其分开。它不是数组,但可以使用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
另请参见,以了解更多优点
编辑
实际上,还有第二种方法可以迭代字符串,即将字符串转换为一个单位数字符串数组,然后进行迭代。为此,我们首先必须将原始字符串转换为unicode格式,以便将空字符用作分隔符。下面是一个可重复的示例:
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,速度更快):
结果:
Time Mid: 4.62962998426519e-05
Time Split: 1.15740767796524e-05
因此,拆分方法似乎要快一些
VBA字符串被实现为。可以找到此数据类型的详细信息。Mid
用于获取任何字符串中的第n个字符,但返回一个变量
,该变量会隐式转换为字符串
使用“强类型”版本:Mid$
。字符串是一个字节数组,如果您知道如何实现字符串的两个字节(或Unicode,通常每个字符2个字节,但可以更多:如果字符串源于VBA,则始终是2个字节),则可以对其进行迭代
当我说是时,我的意思是:不需要类型转换,这将很好地工作:
Public子TestByteString()
作为字符串的暗字符串
Dim arrBytes()作为字节
作为整数的Dim i
strChars=“敏捷的棕色狐狸”
arrBytes=strChars
调试。打印strChars
调试。打印
对于i=LBound(arrBytes)到UBound(arrBytes)步骤2
调试。打印Chr(arrBytes(i))&vbTab&“Byte”&i&“=”&arrBytes(i)
接下来我
arrBytes(0)=Asc(“?”)
arrBytes(2)=Asc(“!”)
arrBytes(4)=Asc(“*”)
strChars=arrBytes
调试。打印
调试。打印strChars
删除arrBytes
端接头
您的输出将如下所示:
敏捷的棕色狐狸
T字节0=84
h字节2=104
字节4=101
字节6=32
q字节8=113
u字节10=117
i字节12=105
c字节14=99
字节16=107
字节18=32
字节20=66
r字节22=114
o字节24=111
w字节26=119
n字节28=110
字节30=32
F字节32=70
o字节34=111
x字节36=120
?!*快速棕色狐狸
请注意循环中的“第2步”:我将每隔一个字节丢弃一个字节,因为我知道它是普通的拉丁字符,对于未初始化的用户来说是“ASCII”文本
当你必须处理阿拉伯语和拼音文本时,它会变得很有趣:你永远不应该在现实世界的工作表中假设你总是在处理普通的美国ASCII码,就像我在那篇演示文章中所做的那样
要获得更全面的示例和更详细的解释,请尝试以下内容:
字节数组优化位于底部,位于该标题下:Adler-32校验和的VBA实现,在字节数组上运行,而不是使用VBA字符串处理
字符串的基本性质似乎并不像它应该的那样广为人知:这不是您在代码中经常使用的东西,而是Unicode和非拉丁字母表的许多问题,当人们对代码中的变量有了更深入的了解时,这些问题就变得更容易解决了。仍然可以创建您的o自定义可枚举字符串
可枚举字符串的使用方式如下:
char myArray[10];
for (int i = 0; i < length; i++)
{
cout << myArray[i];
}
将此代码保存在名为EnumerableString.cls
a的文件中,并将其导入VBA项目
生成Excel,例如ASCII、ANSI和Unicode UTF-8字符:
@timbram这就是你想要做的事情我唯一不喜欢的是计时方法-VBA中的基准测试非常糟糕。单元测试的计算时间只有毫秒,由.net秒表计算(我知道,我写了它;)…我打算试一试,但我想我应该让你知道我的宠物项目,因为我认为它与此相关。我启动了单元测试-正如你所看到的,我已将大部分设置代码提取到ModuleInitialize
中,以便测试只测试相关部分。TestMid
运行时间为17-22毫秒,TestSplit
运行在7-10毫秒内(运行了几次),所以是的,明确的赢家:)我建议谷歌搜索“VBA中的字符串优化”。任何分配和重新分配字符串变量的函数都会很慢:拆分到数组是一种有效的优化,就像一个(效率极低的)函数一样分配已经结束,您不再在循环中进行分配;但是有很多更好的方法可以做到这一点。从这篇文章开始,继续阅读:@Nile,非常感谢链接,这是一篇很好的阅读,性能比较非常有用。我过去使用过ByteArray,但并不广泛。我同意在使用字节数组时,使用字节数组比拆分或中间分隔更有效。我对您的代码进行了+1-ed,其中唯一需要更改的是,尽管在大多数情况下,差异非常小。如果您真的需要,可以将字符串赋给字节数组并循环使用,但随后您必须将字节转换回字符。我编辑了您的标题。请参见“”,其中共识是“不,他们不应该”。请参见下面的详细答案。字符串是字节数组,反之亦然。不是“可以转换为字节数组的变量”,而是
The quick Brown Fox
T 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
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
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
END
Attribute VB_Name = "EnumerableString"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Explicit
Private m_characters As Collection
Public Property Get NewEnum() As IUnknown
Attribute NewEnum.VB_UserMemId = -4
Attribute NewEnum.VB_MemberFlags = "40"
Set NewEnum = m_characters.[_NewEnum]
End Property
Public Property Let Value(ByVal newValue As String)
Dim pos As Integer
Set m_characters = New Collection
For pos = 1 To Len(newValue)
m_characters.Add Mid$(newValue, pos, 1)
Next pos
End Property
Public Function Length() As Long
Length = m_characters.Count
End Function
Public Function Item(ByVal index As Variant) As String
Attribute Item.VB_UserMemId = 0
Item = m_characters(index)
End Function
Private Sub Class_Initialize()
Set m_characters = New Collection
End Sub