Оказывается, это один из тех редких случаев, когда решение было настолько простым, что его игнорировали несколько человек, включая меня.
? "Байтовые массивы" и Строки в основном взаимозаменяемы.
В VBA байтовые массивы являются особыми, потому что, в отличие от массивовдругие типы данных, строка может быть непосредственно назначена байтовому массиву.
В VBA строки - это строки UNICODE , поэтому при назначении строки байтумассив затем хранит две цифры для каждого символа.Первая цифра будет ASCII значением символа, а следующая будет 0.
(Источник: VBA Trick of Week: Массивы байтов в 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
В приведенном выше случае длина строки равна 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
Как Byte Array сделал мой деньнемного лучше ...
У меня есть большие текстовые файлы, которые я хотел проанализировать / проанализировать с помощью VBA, но не смог найти метод, который не был бы мучительно медленным ни при загрузке, ни при посимвольномРазбор символов.
Например, сегодня мне удалось загрузить файл размером в четверть гигабайта за 1 / 10 th секунды,и проанализировал его в второй массив байтов:
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 секунд всего. (Ура!)
Дополнительная информация: