Title | Compare two variables of a user-defined type (UDT) to see if they hold the same values |
Description | |
Keywords | UDT, user-defined type, data type, compare |
Categories | Syntax |
|
|
You can compare the structures one field at a time but that requires a bunch of If statements.
This program includes a function that uses the CopyMemory API function to copy the two structures into byte arrays. It then compares the bytes.
|
|
' Return True if these structures contain the same data.
Private Function MyTypesTheSame(a As MyType, b As MyType) _
As Boolean
Dim i As Integer
Dim a_bytes() As Byte
Dim b_bytes() As Byte
Dim different As Boolean
' Copy the data into arrays of bytes.
ReDim a_bytes(1 To Len(a))
ReDim b_bytes(1 To Len(b))
CopyMemory a_bytes(1), a, Len(a)
CopyMemory b_bytes(1), b, Len(b)
' Compare the bytes.
For i = 1 To Len(a)
If a_bytes(i) <> b_bytes(i) Then
MyTypesTheSame = False
Exit Function
End If
Next i
MyTypesTheSame = True
End Function
|
|
Robert Heinig points out that this will not work if the UDTs contain strings or object references. In that case, this method would compare only the addresses of the objects not the objects themselves. Other cases such as variants (where some bytes are irrelevant so it's conceivable that VB would not initialize them in the same way every time) may also cause trouble. For these reasons, you should use this technique with some care.
Robert also rounds the size of the UDTs up to the next multiple of 4 bytes so he can make the comparison using 4-byte integers instead of bytes. That will make things faster for large UDTs.
Mike Williams discovered a problem with this method. Because of byte alignment issues, Len doesn't always return enough bytes to compare the two structures properly. Consider the following structure:
|
|
Private Type MyType
' StringValue As String * 10
IntegerValue As Integer
LongValue As Long
End Type
|
|
Now consider the following test:
|
|
Dim a As MyType
Dim b As MyType
With b
.IntegerValue = 123
.LongValue = 0
End With
With a
.IntegerValue = 123
.LongValue = 65536
End With
|
|
The MyTypesTheSame function returns True even though the two structures have different LongValues.
You can fix this by replacing Len with LenB in the MyTypesTheSame function. Unfortunately then MyTypesTheSame doesn't work if the UDTs contain fixed-length strings. I guess in the worst case you'll have to compare the types one field at a time.
|
|
|
|