在VBA中,如何比较用户定义类型(UDT)的两个实例?I';我得到一个类型不匹配
我有一个定义UDT的模块,如下所示:在VBA中,如何比较用户定义类型(UDT)的两个实例?I';我得到一个类型不匹配,vba,user-defined-types,type-mismatch,Vba,User Defined Types,Type Mismatch,我有一个定义UDT的模块,如下所示: Private Type UserData uName As String 'user name uDate As Date 'date/time of last interaction End Type Sub TestCheck() Dim testRec(1) As UserData testRec(0).uName = "a" testRec(0).uD
Private Type UserData
uName As String 'user name
uDate As Date 'date/time of last interaction
End Type
Sub TestCheck()
Dim testRec(1) As UserData
testRec(0).uName = "a"
testRec(0).uDate = Date
testRec(1) = testRec(0)
If testRec(1) = testRec(0) Then
Debug.Print "Records match"
Else
Debug.Print "Records don't match"
End If
End Sub
Sub TestCheck()
Dim testRec(1) As UserData
testRec(0).uName = "a"
testRec(0).uDate = Date
testRec(1) = testRec(0)
If UserDataEqual(testRec(1), testRec(0)) Then
Debug.Print "Records match"
Else
Debug.Print "Records don't match"
End If
End Sub
我尝试使用一个简单的测试函数来比较UDT的两个不同实例,如下所示:
Private Type UserData
uName As String 'user name
uDate As Date 'date/time of last interaction
End Type
Sub TestCheck()
Dim testRec(1) As UserData
testRec(0).uName = "a"
testRec(0).uDate = Date
testRec(1) = testRec(0)
If testRec(1) = testRec(0) Then
Debug.Print "Records match"
Else
Debug.Print "Records don't match"
End If
End Sub
Sub TestCheck()
Dim testRec(1) As UserData
testRec(0).uName = "a"
testRec(0).uDate = Date
testRec(1) = testRec(0)
If UserDataEqual(testRec(1), testRec(0)) Then
Debug.Print "Records match"
Else
Debug.Print "Records don't match"
End If
End Sub
我得到编译错误:testRec(1)=testRec(0)上的类型不匹配
我真的不想为了检查等价性而遍历每个实例的每个成员。UDT不应该充当变量吗?如果我必须循环每个实例的每个成员来比较它们,那么使用UDT确实不会为我节省任何东西。有没有一种方法可以在不经过成员循环的情况下进行比较?根据Brian M Stafford的评论,对于任何有相同问题的人,简单的答案是否定的。
然而,这里有一个简单的函数来完成这项工作:
Private Function UserDataEqual(ByRef varA As UserData, ByRef varB As UserData) As Boolean
If varA.uName = varB.uName _
And varA.uDate = varB.uDate Then
UserDataEqual = True
Else
UserDataEqual = False
End If
End Function
其用途如下:
Private Type UserData
uName As String 'user name
uDate As Date 'date/time of last interaction
End Type
Sub TestCheck()
Dim testRec(1) As UserData
testRec(0).uName = "a"
testRec(0).uDate = Date
testRec(1) = testRec(0)
If testRec(1) = testRec(0) Then
Debug.Print "Records match"
Else
Debug.Print "Records don't match"
End If
End Sub
Sub TestCheck()
Dim testRec(1) As UserData
testRec(0).uName = "a"
testRec(0).uDate = Date
testRec(1) = testRec(0)
If UserDataEqual(testRec(1), testRec(0)) Then
Debug.Print "Records match"
Else
Debug.Print "Records don't match"
End If
End Sub
谢谢你回答我的问题,布莱恩。这类活动是上课的目的。使用适当的方法创建类,而不是用户定义的类型。在这里,我们定义了一个名为UserData的类,它具有一个预先声明的Id,以便我们可以将该类用作UserData工厂。在这个例子中,我们有 用户数据类
' User Rubberduck annotations to set the predecalredId to True
'@PredeclaredId
Option Explicit
Public Enum UserDataType
udDate
udName
End Enum
Private Type Properties
UserData As Object
End Type
Private p As Properties
Public Function Make(ByVal ipName As String, ByVal ipDateAndTime As Date) As UserData
With New UserData
Set Make = .Self(ipName, ipDateAndTime)
End With
End Function
Public Function Self(ByVal ipName As String, ByVal ipDateAndTime As Date) As UserData
' Use late bound crreation of a scripting dictionary to avoid reference issues
Set p.UserData = CreateObject("Scripting.Dictionary")
With p.UserData
.Add udName, ipName
.Add udDate, ipDateAndTime
End With
Set Self = Me
End Function
Public Property Get Item(ByVal ipEnum As Long) As Variant
Item = p.UserData.Item(ipEnum)
End Property
Public Property Let Item(ByVal ipEnum As Long, ByVal ipValue As Variant)
p.UserData.Item(ipEnum) = ipValue
End Property
Public Function SameAs(ByVal ipUserData As UserData) As Boolean
SameAs = False
Dim myIndex As Long
For myIndex = 0 To p.UserData.Count - 1
If Me.Item(myIndex) <> ipUserData.Item(myIndex) Then Exit Function
Next
SameAs = True
End Function
如你所见。你可以看到。要更改不同成员集的UserData类,只需更改枚举(前提是保留简单变量)。您需要逐个成员进行比较。您可以创建一个方法来简化此任务。@BrianMStafford谢谢。天哪,这正是我害怕的。不幸的是,上面的例子是对我的实际UDT的简化,我需要为每个单独的UDT成员使用函数,除非有办法将UDT视为类型变量的数组。你说的是多少UDT成员?它是嵌套的,所以有一个包含4个成员的“顶级”UDT。其中2名成员是其他UDT。其中一个是上面列出的一个(有2名成员),另一个有3名成员。因此,总共需要进行7次比较。该方法特定于UDT。这意味着每个UDT都会有自己的方法。是的,我一开始就在讨论如何使用类路径,但我避免了它,因为我希望类型对它们的模块是私有的,并且不打算让它们变得太复杂。那是在我意识到你不能测试他们是否平等之前。不管怎样,看起来您也必须在类中为它编写函数。谢谢你的意见。简化对象创建的类的极好示例。