ash*_*awg 5 arrays excel vba byte ascii
我有整数数组,每个数组都是一个 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
Run Code Online (Sandbox Code Playgroud)
...但我觉得这不是做到这一点的“正确方法”,尤其是因为可能需要重复转换。数组长度会有所不同。
是否有内置或更有效的方法来使用 VBA 生成字符串?
事实证明,这是解决方案如此简单以至于被包括我自己在内的几个人所忽视的罕见时期之一。
在 VBA 中,字节数组很特殊,因为与其他数据类型的数组不同,字符串可以直接分配给字节数组。
在 VBA 中,字符串是UNICODE字符串,因此当将字符串分配给字节数组时,它会为每个字符存储两位数字。第一个数字是字符的 ASCII值,接下来是 0。
(来源:VBA 本周技巧:VBA 中的字节数组-有用的 Gyaan)
几个代码示例可能会比我解释的更好:
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
Run Code Online (Sandbox Code Playgroud)
在上述情况下,字符串的长度为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 值。Run Code Online (Sandbox Code Playgroud)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
Run Code Online (Sandbox Code Playgroud)
我有大文本文件,我一直想用 VBA 解析/分析这些文件,但找不到在加载或逐字符解析中都不会太慢的方法。
作为一个例子,今天我设法加载四分之一千兆字节文件1 / 10个的第二的,并解析它变成一个第二字节数组:
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)
Run Code Online (Sandbox Code Playgroud)
...我在不到 5 秒的时间内完成了我的完整字符串。(万岁!)