PRB: Compare User-Defined Type Variables w/ PEEK or _fmemcmpID: Q101258
|
An attempt to use the relational operators (=, <>, and so on) to compare user-defined type variables results in a "Type mismatch" error.
The relational operators do not support the comparison of user-defined type variables.
This article discusses two alternative methods for comparing user-defined
type variables.
The first method compares user-defined type variables by converting the
variables to strings, and then comparing the strings. It uses PEEK, VARPTR,
and CHR$ to convert the user-defined type variable to a string.
The second method uses the C function _fmemcmp to compare two user-defined
type variables. This second method is much faster than the first,
particularly when comparing large (up to 64k in size) user-defined type
variables. In addition, the second method avoids "out of string space"
errors which can occur with the first method and it can be modified to
compare arrays of numeric, fixed length strings or user-defined types up
to 64k in size.
This behavior is by design.
WARNING: One or more of the following functions are discussed in this article; VarPtr, VarPtrArray, VarPtrStringArray, StrPtr, ObjPtr. These functions are not supported by Microsoft Technical Support. They are not documented in the Visual Basic documentation and are provided in this Knowledge Base article "as is." Microsoft does not guarantee that they will be available in future releases of Visual Basic.
When comparing user-defined type variables, you can check to see if they
are Equal or Not Equal ('=' or '<>'), but don't attempt to use the other
relational operators (<, >, <=, >=) unless the user-defined type variable
contains fixed length strings. This behavior is due to how numeric
variables are stored and how these functions accomplish their comparisons.
These methods treat the numeric variables as unsigned numbers and because
the negative sign is stored in the most significant bit of a numeric
variable, comparing positive and negative numbers would result in the
negative number being seen as greater than the positive number.
DECLARE FUNCTION type2str$ (t AS ANY)
TYPE myType
f1 AS STRING * 2
f2 AS SINGLE
END TYPE
<BR/><BR/>
DIM x AS myType
DIM y AS myType
<BR/><BR/>
x.f1 = "ab"
x.f2 = 2
y = x
<BR/><BR/>
IF type2str(x) = type2str(y) THEN
PRINT "x = y"
ELSE
PRINT "x <> y"
END IF
y.f1 = "ba"
IF type2str(x) > type2str(y) THEN
PRINT "x > y"
ELSE
PRINT "x < = y"
END IF
'
' type2str converts a user-defined type variable to a string.
'
FUNCTION type2str$ (t AS myType)
DEF SEG = VARSEG(t) ' In case the variable is in a dynamic array.
FOR i% = 0 TO LEN(t) - 1
s$ = s$ + CHR$(PEEK(VARPTR(t) + i%))
NEXT
DEF SEG
type2str = s$
END FUNCTION
LIB MLIBCE.LIB*FMEMCMP.OBJ; ' extract fmemcmp object
LIB MLIBCE.LIB*DIFFHLP.OBJ; ' and a support object
LIB TYPECOMP.LIB+FMEMCMP.OBJ+DIFFHLP.OBJ; ' build new library
LINK /Q TYPECOMP.LIB,TYPECOMP.QLB,,VBDOSQLB.LIB; ' build quicklib
' use QBXQLB.LIB
' for Basic PDS or
' BQLB45.LIB for QB45
VBDOS /L TYPECOMP
DEFINT A-Z
' Declare the C function
DECLARE FUNCTION TypeCmp% CDECL ALIAS "__fmemcmp" _
(SEG buf1 AS ANY, SEG buf2 AS ANY, BYVAL Length%)
CONST max = 1000
TYPE RecType ' Set Up the User Defined Type
CustID AS INTEGER
AcctCode AS LONG
Memo AS STRING * 6
Dates(1 TO max) AS STRING * 10
END TYPE
CLS
DIM Rec1 AS RecType ' Dimension 2 variables
DIM Rec2 AS RecType
Rec1.CustID = 2 ' Initialize first record
Rec1.AcctCode = 42356
Rec1.Memo = "mojoho"
FOR i = 1 TO max
Rec1.Dates(i) = "Test" + STR$(i)
NEXT i
Rec2 = Rec1 ' Initialize second record
result% = TypeCmp%(Rec1, Rec2, LEN(Rec1)) ' Compare the records:
IF result% <> 0 THEN ' if result% = 0, Rec1 = Rec2
PRINT "Not Equal" ' if result% > 0, Rec1 > Rec2
ELSE ' if result% > 0, Rec1 < Rec2
PRINT "Rec1 = Rec2"
END IF
Rec2.Memo = "toasty" ' Change information in 2nd record
result% = TypeCmp%(Rec1, Rec2, LEN(Rec1)) ' Compare
IF result% <> 0 THEN ' Print result
PRINT "Not Equal"
ELSE
PRINT "Rec1 = Rec2"
END IF
END
Additional query words:
Keywords : kbVBp
Version : MS-DOS:1.0,4.0,7.1
Platform : MS-DOS
Issue type : kbprb
Last Reviewed: July 20, 1999