Byte Arrays in VB6/VBA Visual Basic
To carry out cryptographic operations in classic Visual Basic (VB6 and VBA) we should use the unambiguous Byte
type
instead of the much more convenient String
type.
This page shows how to handle arrays of the Byte
type compared to the simpler operations
we know how to do with the String
type.
Operation | String | Byte Array |
---|---|---|
Dimension | Dim str As String |
' Dynamic array of n bytes (0,1,...,n-1) Dim abArray() As Byte ' ... ReDim abArray(n-1) ' OR for a static array Dim abArray(n-1) ' or, more explicitly, Dim abArray(0 To n-1) |
Assign | str = "xxxx" ' OR (can be slow for long strings) For i = 1 To n str = str & "x" Next ' OR (faster) str = String (' ', n) For i = 1 To n Mid(str, i, 1) = "x" Next |
For i = 0 To n - 1
abArray(i) = x
Next
' OR (safer)
For i = LBound(abArray) To UBound(abArray)
abArray(i) = x
Next
|
Access the ith element | Dim ch As String ch = Mid(str, i, 1) |
Dim b as Byte b = abArray(i - 1) |
Change the ith element | Dim b As Byte b = Asc(Mid(str, i, 1)) |
Dim ch As String ch = Chr(abArray(i - 1)) |
Length | Dim nLen As Long nLen = Len(str) |
Dim nLen As Long nLen = UBound(abArray) - LBound(abArray) + 1 |
Compare | If str1 = str2 Then ... |
' (Fudge, but works)
If StrConv(abArray1, vbUnicode) = _
StrConv(abArray2, vbUnicode) Then ...
See Comparing Byte arrays below.
|
Copy | Dim str1 As String Dim str2 As String str1 = "..." str2 = str1 |
Dim ab1() As Byte
Dim ab2() As Byte
' ...assign data to ab1...
ab2 = ab1
' OR, assuming ab1 has been assigned,
Dim i As Long
ReDim ab2(UBound(ab1))
For i = LBound(ab1) To UBound(ab1)
ab2(i) = ab1(i)
Next
|
Concatenate | Dim str1 As String Dim str2 As String Dim str3 As String str1 = "..." str2 = "..." str3 = str1 & str2 |
Dim ab1() As Byte Dim ab2() As Byte Dim ab3() As Byte Dim i As Long ' ...assign data to ab1 and ab2... ab3 = ab1 ' NB fixes 2022-12-14 ReDim Preserve ab3(UBound(ab1) + UBound(ab2) + 1) For i = 0 To UBound(ab2) ab3(i + 1 + UBound(ab1)) = ab2(i) Next |
Is Empty |
If str = "" Then ...
' OR (better)
If Len(str) = 0 Then ...
|
On Error GoTo EmptyArray nLen = UBound(abArray) - LBound(abArray) + 1 ' If got here then array is not empty ' ... EmptyArray: ' ...will jump to here if empty ' OR create this useful function ' that returns zero if the array is empty Public Function BytesLength(abBytes() As Byte) As Long ' Trap error if array is empty On Error Resume Next BytesLength = UBound(abBytes) - LBound(abBytes) + 1 End Function |
Return from a function | Dim str As String str = MyStrFunc() ' Public Function MyStrFunc() As String MyStrFunc = "A string" End Function |
Dim abArray() As Byte abArray = MyByteFunc() ' Public Function MyByteFunc() As Variant Dim i As Long Dim abBytes() As Byte ReDim abBytes(n-1) For i = 0 To n-1 abBytes(i) = x Next MyByteFunc = abBytes End Function ' CAUTION: Do not dimension abArray as a static array ' e.g. Dim abArray(5) As Byte ' static array abArray = MyByteFunc() ' NO! Will cause a run-time error.See also Returning a Byte array value from a function below. |
Notes
- The byte array examples assume that
Option Base 0
is the default. - The dimensioning of byte arrays in VB6 is a trap for programmers used to C and Java, and is counter-intuitive.
An array of n bytes is dimensioned as
Dim abArray(n-1)
That is the n-byte array[abArray(0), abArray(1), ..., abArray(n-1)]
. You still use indexesFor i = 0 To n-1
like in C, but you dimension the size of the array differently. If you useDim abArray(n)
you have an extra byte at the end, which will come back to "byte" you (sorry). A more intuitive way is to use the full, formal expressionDim abArray(0 To n-1)
-
Always dimension your index variables as
Long
. If you useInteger
it will seem to work OK until one day you have data that is longer than 32767 and you will get a run-time error. There must be a corollary of Simpson's Law here:All tests you can ever think of doing, or at least can be bothered doing, will involve an integer less thanSMALL_INT_MAX
, but one of your users will useSMALL_INT_MAX + 1
within one day of production release.
Returning a Byte array value from a function
To return aByte
array from a function, dimension the function as a Variant
type
(more recent versions of VBA allow you to use Byte()
).
Public Function MyByteFunc(Input) As Variant Dim abBytes() As Byte Dim nLen as Long nLen = CalcLen(Input) ReDim abBytes(nLen - 1) For i = 0 To nLen - 1 abBytes(i) = x Next MyByteFunc = abBytes End Functionand explicitly cast the return value back to a (dynamic)
Byte
array in the calling function.
Dim abArray() As Byte abArray = MyByteFunc(X) Debug.Print "Array Length=" & UBound(abArray) + 1 '...But if you need to return an error condition before you ReDim the
abBytes
array,
you will get a run-time error when you try to read the returned value.
Public Function MyByteFuncBad(Input) As Variant
Dim abBytes() As Byte
Dim nLen As Long
If IsError(Input) Then
Exit Function
End If
nLen = CalcLen(Input)
ReDim abBytes(nLen - 1)
For i = 0 To nLen - 1
abBytes(i) = x
Next
MyByteFuncBad = abBytes
End Function
Dim abArray() As Byte
abArray = MyByteFuncBad(X)
Debug.Print "Array Length=" & UBound(abArray) + 1 ' RUN-TIME ERROR!.
To solve, use this trick
Public Function MyByteFuncGood(Input) As Variant Dim abBytes() As Byte Dim nLen As Long ' Set default return value that won't cause a run-time error MyByteFuncGood = StrConv("", vbFromUnicode) If IsError(Input) Then Exit Function End If nLen = CalcLen(Input) ReDim abBytes(nLen - 1) For i = 0 To nLen - 1 abBytes(i) = x Next MyByteFuncGood = abBytes End Function
Dim abArray() As Byte
abArray = MyByteFuncGood(X)
Debug.Print "Array Length=" & UBound(abArray) + 1 ' Should return 0 on error.
We've not seen this trick of using StrConv
with an empty string documented anywhere. We discovered
it by accident. But it works.
[2018-08-15]: You could also use MyByteFuncGood = vbNullString
.
Comparing Byte arrays
To compare twoByte
arrays, you can use the one-line StrConv
fudge we suggest above.
To do a strict comparison for equality, you can use the following function,
which assumes both byte arrays have been dimensioned.
Public Function ByteArraysAreEqual(data1() As Byte, data2() As Byte) As Boolean On Error GoTo OnError Dim i As Long ByteArraysAreEqual = False If UBound(data1) <> UBound(data2) Then Exit Function End If For i = LBound(data1) To UBound(data1) If data1(i) <> data2(i) Then Exit Function End If Next i ByteArraysAreEqual = True Done: Exit Function OnError: Resume Done End Function
See also
Contact
To comment on this page or ask a question, please send us a message.
This page last updated 9 September 2025