Vba 将对象链接到用户界面
将类链接到用户表单的最佳方法是什么 很抱歉,这是假设性的,但使用实际的代码将导致一个页面长的问题 假设我有一个类,它保存关于一个人的数据Vba 将对象链接到用户界面,vba,userform,Vba,Userform,将类链接到用户表单的最佳方法是什么 很抱歉,这是假设性的,但使用实际的代码将导致一个页面长的问题 假设我有一个类,它保存关于一个人的数据 <<class Person>> Public FirstName as String Public LastName as String Public PhoneNumber as String <<end class>> 从上述代码中的项到实际对象的最佳方式是什么?我应该为每个对象添加一个GUID,并将其放
<<class Person>>
Public FirstName as String
Public LastName as String
Public PhoneNumber as String
<<end class>>
从上述代码中的项到实际对象的最佳方式是什么?我应该为每个对象添加一个GUID,并将其放在listitem的标记中,然后查找它吗?我是否应该将listview中的listitem添加到类中,这样我就可以遍历所有人,然后查看来自_ItemClick的项目是否等于来自对象的项目?最简单的方法是使用listitem的Index属性(如果没有唯一标识符),或者使用Key属性(如果有) 如果选择使用Index属性,则无法(或者至少会使其变得非常复杂)添加任何功能来重新排列列表项的顺序 您可以通过ListView.ListItems.Add方法基于集合/记录集中的对象填充ListView。可以使用Index属性根据ListItems中的项目顺序返回到原始对象,ListItems中的项目顺序对应于原始对象集合中的项目顺序 或者,如果您更喜欢使用唯一键的更大灵活性,但不希望修改底层对象,那么您可以在将每个对象添加到ListItems时构造一个唯一键(最简单的是CStr(一些递增的数字)),将键存储在对象旁边 然后可以使用ListItem的.Key属性。这里的好处是,用户可以修改其中的项目、删除内容等,而无需使控件无效并重新添加所有对象,以保持源中的索引和列表中的索引之间的链接 例如: 最后,如果在DB返回的记录集中有它们,另一种方法是添加一个新字段(我假设您有一个现有的对象字段),并对记录运行更新查询,并用递增的数字填充它(这只会影响本地记录集(当然,首先检查记录集设置!)。用这个作为钥匙
您在对问题的评论中提到,您从SQL获取数据。对于列表框的所有正常用途,可能仍然最容易通过集合对象运行它们,如上所述,但是如果记录集中的记录有SQL中的4个字段,那么就没有能够调用其属性的“对象”。如果您这样做,请在您的问题或对此的评论中指定,因为可能有更好的方法来回答您的问题,或者实际的更新操作可能需要不同的语法或语义(特别是如果您需要将任何更新传播回源):我将使用事件驱动的方法
Person
将具有属性而不是变量,分配这些属性将引发事件
用户表单将有with events Person
,因此相关人员的更改将触发用户表单代码
人员类别:
Public Event Changed()
Private pFirstName As String
Private pLastName As String
Private pPhoneNumber As String
Public Property Get FirstName() As String
FirstName = pFirstName
End Property
Public Property Let FirstName(ByVal v As String)
pFirstName = v
RaiseEvent Changed
End Property
Public Property Get LastName() As String
LastName = pLastName
End Property
Public Property Let LastName(ByVal v As String)
pLastName = v
RaiseEvent Changed
End Property
Public Property Get PhoneNumber() As String
PhoneNumber = pPhoneNumber
End Property
Public Property Let PhoneNumber(ByVal v As String)
pPhoneNumber = v
RaiseEvent Changed
End Property
以用户形式捕获事件:
Public WithEvents ThisPerson As Person
Private Sub ThisPerson_Changed()
'Update user form
End Sub
因此,无论何时分配
YourForm.RelatedObject=SomePerson
,对SomePerson
所做的任何更改都将触发YourForm
中的代码,因为您无法更改返回的ListItem
,我有另一个解决方案:
将相关的列表项
添加到您的人员
类:
Public FirstName as String
Public LastName as String
Public PhoneNumber as String
Public RelatedObject As Object
填充TreeView
时,为其分配:
Set SomeListItem = SomeTreeView.ListItems.Add(...)
Set SomePerson.RelatedObject = SomeListItems
因此,每当您在列表项中进行更改时:
Private Sub SomeListView_ItemClick(ByVal Item As MSComctlLib.ListItem)
Dim p As Person
For Each p In (...)
If p.RelatedObject Is Item Then
'Found, p is your person!
p.PhoneNumber = ...
End If
Next
End Sub
或者,如果您不想更改Person
类,可以将其封装在另一个类中,例如PersonToObject:
Public Person As Person
Public RelatedObject As Object
并将PersonToObject
用作链接对象。添加GUID或任何其他ID都是唯一标识个人对象的好方法,在您的示例中,电话号码可能对每个人都是唯一的,并且可以用作ID。如果您希望每个人都有一个以上的电话号码,那么这将不起作用,或多人拨打一个电话号码。您的数据存储在Excel工作表、Access数据库或Word中的列表中吗?人员信息来自何处?本例中的数据是从SQL加载的。我真的在寻找一种通用方法来识别/链接UI元素到对象。这不会有帮助吗?@mehow,我同意这个问题很广泛,但这是有目的的,我想问是否有最好的方法来做某事。对于如何改进这个问题,我非常感谢任何建设性的批评。重要的是,你是如何拥有“人”的?我假设你有适当的“对象”,因为你提到了一个类的人,所以这是有帮助的,我想更新数据库超出了问题的范围。不管怎样,我的建议有帮助吗?如果没有,请说明原因,供我参考。Thanks@lfrandom嗯,任何答案都将主要基于观点。没有<代码>最佳方式,因为它总是依赖于代码设计、实现和VBA技能等。你的问题太宽泛,难以回答,因为任何回答者都必须考虑其解决方案的利弊。一个会同意,另一个会不同意,所以你的问题没有完美的解决方案。你的问题也有点不清楚,所以努力理解你想要达到的目标是至关重要的
Private Sub SomeListView_ItemClick(ByVal Item As MSComctlLib.ListItem)
Dim p As Person
For Each p In (...)
If p.RelatedObject Is Item Then
'Found, p is your person!
p.PhoneNumber = ...
End If
Next
End Sub
Public Person As Person
Public RelatedObject As Object