问题描述
我有整数数组,每个整数数组都是一个ASCII码,表示字符串的一个字节。
我可以从数组生成字符串,如下所示:
Sub BytesToString()
Dim myArr(): myArr = Array(84, 104, 105, 115, 32, _
105, 115, 32, 97, 32, 116, 101, 115, 116, 33)
Dim c As Variant, myStr As String
For Each c In myArr
myStr = myStr & Chr(c)
Next c
MsgBox myStr
End Sub
.但我觉得这不是"正确的方式",特别是因为可能需要重复转换。数组长度将有所不同。
是否有内置或更有效的方法来使用VBA生成字符串?
推荐答案
事实证明,这是少数几次解决方案如此简单以至于被包括我在内的几个人忽略的情况之一。
"字节数组"和字符串基本上可以互换。
在VBA中,字节数组比较特殊,因为与其他数据类型的数组不同,字符串可以直接分配给字节数组。
在VBA中,字符串是UNICODE字符串,因此当将字符串分配给字节数组时,它会为每个字符存储两位数字。第一个数字将是字符的ASCII值,下一个数字将为0。 (来源:VBA Trick of the Week: Byte Arrays in VBA-有用的嘉安)
几个代码示例可能会演示得比我所能解释的更好:
Sub Demo1()
Dim myArr() As Byte, myStr As String
myStr = "Hi!"
myArr() = myStr
Debug.Print "myStr length: " & Len(myStr) 'returns "3"
Debug.Print "Arr bounds: " & LBound(myArr) &"to"& UBound(myArr) 'returns "0 to 5"
myStr = myArr
Debug.Print myStr 'returns "Hi!"
End Sub
在上面的情况下,字符串的长度为3,因此数组的大小将为6。值将以以下方式存储:
myArr(0) = 72 ' ASCII : code for 'H'
myArr(1) = 0 ' ASCII 'null' character
myArr(2) = 105 ' ASCII : code for 'i'
myArr(3) = 0 ' ASCII 'null' character
...etc...
StrConv
函数。在这种情况下,它将仅存储ASCII值。
myByteArr() = StrConv("StackOverflow", vbFromUnicode)
就像字符串可以直接赋给字节数组一样,字节数组也可以直接赋给字符串。在上面的示例中,如果将myArr
赋给字符串,则它将存储已分配给数组的相同值。
逐个元素填充数组时,或者在我的情况下,通过快速文件操作(见下文)填充数组时,需要使用StrConv
额外的转换步骤。
Sub Demo2()
Dim myArr(0 To 5) As Byte, myStr As String
myArr(0) = 104: myArr(1) = 101: myArr(2) = 108
myArr(3) = 108: myArr(4) = 111: myArr(5) = 33
Debug.Print "myArr bounds: " & LBound(myArr) &"to"& UBound(myArr) 'returns "0 to 5"
'since the array was loaded byte-by-byte, we can't "just put back":
myStr = myArr()
Debug.Print myStr 'returns "???" (unprintable characters)
Debug.Print "myStr length: " & Len(myStr) 'returns "3"
'using `StrConv` to allow for 2-byte unicode character storage
myStr = StrConv(myArr(), vbUnicode)
Debug.Print myStr 'returns "hello!"
Debug.Print "myStr length: " & Len(myStr) 'returns "6"
End Sub
字节数组如何让我的一天过得更好.
我希望使用VBA分析/分析大型文本文件,但找不到加载或逐个字符分析都非常慢的方法。
举个例子,今天我设法在1/10th秒内加载了一个四分之一GB的文件,并将其解析为第二个字节数组:
Dim bytes() As Byte
Open myFileName For Binary Access Read As #1
ReDim bytes(LOF(1) - 1&)
Get #1, , bytes
Close #1
For x = LBound(arrOut) To UBound(arrOut)
Select Case bytes(x)
(..and if I want the character)
bytes2(y) = bytes(x)
y = y + 1
End Select
Next x
ReDim Preserve bytes2(LBound(bytes2) To y - 1)
txtIn = StrConv(bytes2, vbUnicode)
.并且我在总计5秒内完成了字符串。(万岁!)