【问题标题】:Multiple Instances of same form with isolated recordsets具有独立记录集的相同形式的多个实例
【发布时间】:2014-07-17 13:20:23
【问题描述】:

http://allenbrowne.com/ser-35.html

下面的代码是 Allen Browne 打开同一表单的多个实例的代码。问题是我需要每个表单数据都基于“那个”表单中的下拉列表,而不是第一个。他在表单上有一个表作为记录源,我在表单中嵌入了以下 SQL。我认为关键是 where 语句,或者可能删除 where 语句并使用过滤。现在所有打开的表单都基于第一个表单数据。

My SQL Where 语句 -

WHERE (((tbl_buyer_column.aels_id)=[forms]![frm_baseline]![ael]))

艾伦的密码

Option Compare Database
Option Explicit
Public clnClient As New Collection

Function OpenAClient()
    Dim frm As Form
    Set frm = New Form_frm_baseline
    frm.Visible = True
    frm.Caption = "New Form Opened " & Now()
    clnClient.Add Item:=frm, Key:=CStr(frm.Hwnd)
    Set frm = Nothing
End Function

Function CloseAllClients()
    Dim lngKt As Long
    Dim lngI As Long
    lngKt = clnClient.Count
    For lngI = 1 To lngKt
        clnClient.Remove 1
    Next
End Function

【问题讨论】:

    标签: sql ms-access


    【解决方案1】:

    你在正确的轨道上。这里的诀窍是在您打开表单时跟踪它们。我就是这样做的。您可以看到,当我创建新实例时,我传入了一个参数,该参数指定了我想在该表单上使用的记录集。您也可以将其更改为过滤器。

    这是标准模块中的代码

    Public multiInstanceDic As Dictionary
    
    'returns the window handle (long)
    Public Function OpenNewMyFormSheetInstance(queryForRecordSource As String, Optional inputCaption As String) As Long
    
        If multiInstanceDic Is Nothing Then
            Set multiInstanceDic = New Dictionary
        End If
    
        Dim frm As Form
        Set frm = New Form_MyForm
        frm.Caption = inputCaption
        frm.SetRecordSource queryForRecordSource
        multiInstanceDic.Add frm.Hwnd, frm   'required to keep form alive after function exits
        frm.SetFocus
    
        OpenNewDynamicDataSheetInstance = frm.Hwnd
    End Function
    
    Public Function GetMyFormInstance(frmHandle As Long) As Form_MyForm
        Set GetDynamicDataSheetInstance = multiInstanceDic(frmHandle)
    End Function
    

    我在整个应用程序中都这样使用它

    Dim createdWindowHandle As Long
    createdWindowHandle = Windows.OpenNewMyFormInstance("VW_SomeView", "A wonderful informative caption")
    

    然后,每当我需要更改创建时未处理的表单的其他内容时,我可以方便地使用hwnd,因为我在创建表单时将其返回给调用者。

    Dim dMyForm As Form_MySheet
    Set dMyForm = Windows.GetMyFormInstance(createdWindowHandle)
    
    dMyForm.[change any public property]  
    

    这一切对我来说都很好。我可以同时打开许多具有不同数据的相同表单的实例。这种特殊的形式,当传递一个查询/记录集时,将动态地创建绑定控件。但是,我认为你不需要那个。您只需要显示两个具有不同过滤器的表单。完全有可能。

    【讨论】:

    • 只是好奇,因为我以前从未做过这样的事情,但是表单的新实例上的控件何时呈现?我认为在表单加载之后可能需要Requery,而Hwnd 仍然是焦点,但是我不确定新表单如何知道要过滤什么,因为它们基本上只是在制作第一份表格的副本?
    • @Brad - 谢谢,我发现有人以艾伦的方法作为其他地方的基础来做一些接近我想做的事情。结合您所介绍的内容,我有信心可以完成这项工作。
    • @OverMind 表单的OpenLoad 事件在您调用New Form_MyForm 时被触发。当您调用SetFocus 时,表单实际上是在屏幕上绘制的,其效果与.Visible = true 相同。如果您要更改记录源的 where 子句,则需要重新查询,但由于 OP 只是更改 .Filter 设置 .FilterOn = true 将触发执行过滤器。
    • @OverMind ...每个新表单都是一个新对象,因此它们完全独立于任何其他表单。就像您创建New Dictionary 时一样,它会创建一个类字典的新对象,但任何新对象都与任何旧对象无关,除了它们的公共结构。在这里,我们定义了一个名为Form_MyForm 的类。 Access 通常一次只打开一个实例,因为它自己管理这种结构。所以 DoCmd.OpenForm 每个类只能打开一个表单。
    • 非常有趣,感谢您的回复。回想起来,这一切有必要吗?如果 OP 正在制作 same 表单的新对象,如果 OP 没有更改每个表单上的下拉列表以过滤记录,那么返回的数据会有什么不同?过滤后,我会认为Requery 就足够了。不过,我想我可能很难跟上。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-08
    • 2021-09-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多