Split Form为它的每个部分创建一个单独的集合



我在MS Access中有一个拆分表单,用户可以在数据表中选择记录,并将其添加到表单中的列表框中,从而创建记录的自定义选择。该过程基于一个集合。选定的记录被转换为自定义对象,该对象被添加到集合中,该集合又用于填充列表框。我有按钮来添加记录,删除记录或清除所有工作良好。

然而,我认为,按下所有这些按钮是有点乏味的,如果你创建一个选择的十几条记录,所以我认为它应该是简单的绑定添加和删除按钮的双击事件的数据表字段和列表框分别。

不幸的是,我错了,因为这打破了形式。虽然双击表单数据表部分中的字段将记录添加到列表框中,但现在无法从底层集合中删除项,从而导致运行时错误5:无效过程调用或参数。此外,清除所有按钮不再正确地重置集合。当尝试清除和添加以前选择的记录时,代码返回我的自定义错误,即记录已经是选择的一部分,并且列表框填充了整个以前的选择,应该删除。这让我相信,由于某种原因,收藏品被复制或沿着这条线。对于潜在问题的任何提示都是非常感谢的。代码如下:

Option Compare Database
Dim PersColl As New Collection
Private Sub AddPerson_Click() 
AddPersToColl Me!ID
FillListbox
End Sub
Private Sub btnClear_Click()
Set PersColl = Nothing
lBoxSelection.RowSource = vbaNullString
End Sub
Private Sub btnRemovePers_Click()
PersColl.Remove CStr(lBoxSelection.Value)
FillListbox
End Sub
Private Sub FillListbox()
Dim Pers As Person        
lBoxSelection.RowSource = vbaNullString        
For Each Pers In PersColl
lBoxSelection.AddItem Pers.ID & ";" & Pers.FullName
Next Pers        
lBoxSelection.Requery
End Sub
Private Function HasKey(coll As Collection, strKey As String) As Boolean
Dim var As Variant
On Error Resume Next
var = IsObject(coll(strKey))
HasKey = Not IsEmpty(var)
Err.Clear
End Function
Private Sub AddPersToColl(PersonId As Long)
Dim Pers As Person        
Set Pers = New Person
Pers.ID = PersonId        
If HasKey(PersColl, CStr(PersonId)) = False Then
PersColl.Add Item:=Pers, Key:=CStr(PersonId)
Else: MsgBox "Person Bereits ausgewählt"
End If
End Sub

这可以单独工作,但是简单地添加这个就会像上面描述的那样破坏它。

Private Sub Nachname_DblClick(Cancel As Integer)
AddPersToColl Me!ID
FillListbox
End Sub

进一步的测试表明,如果我简单地删除私有子AddPerson_Click()

,它不会工作Edit1:澄清:我怀疑有两个不同的事件调用相同的sub会以某种方式复制内存中的集合,因此删除一个事件应该工作。然而,事实并非如此。由button_Click事件调用sub可以正常工作,但由double_click事件调用相同的sub会提示上述行为。因此,问题似乎不在于将sub绑定到多个事件,而在于将它们绑定到Double_Click事件。

编辑2:我找到了问题,但还没有找到解决方案。当涉及到底层vba代码时,看起来拆分表单并没有真正连接。双击数据表视图中的记录将创建一个Collection,而使用表单部件上的按钮将创建另一个Collection。当尝试通过单击窗体上的按钮删除集合项时,会提示错误,因为此集合为空。但是,单击表单部分上的清除所有按钮不会清除与数据表部分关联的集合。

把集合外面到一个单独的模块可能是一个解决方案,但我会感谢任何建议,这将让我保持代码在表单模块。

这种行为是由拆分表单引起的,它为它的每个部分创建了两个单独的集合。根据触发操作集合的事件的位置,其中一个会受到影响。我怀疑拆分表单在本质上不是一个表单,而是同一个表单类的两个实例。

解决方案是在单独的模块中声明一个集合"Coll";

Option Compare Database
Dim mColl as new Collection
Public Function GetColl() as Collection
Set GetColl= mColl
End Function

然后删除SplitFormclass中的集合声明,并在每个函数或子模块中通过引用单独的模块中的集合来声明集合,如下面的例子所示:

Option Compare Database
Private Sub AddPersToColl(PersonId As Long)
Dim Pers As Person
Dim PersColl as Collection
Set PersColl = Coll.GetColl

Set Pers = New Person
Pers.ID = PersonId        
If HasKey(PersColl, CStr(PersonId)) = False Then
PersColl.Add Item:=Pers, Key:=CStr(PersonId)
Else: MsgBox "Person Bereits ausgewählt"
End If
End Sub    

这将强制窗体使用相同的Collection,无论事件是从窗体还是从拆分窗体的数据表部分触发。如果您能提供进一步的信息,我们将不胜感激,但事情现在已经解决了。

感谢大家的宝贵时间

最新更新