Ms access 如何检查Access 2010表单的实例是否仍处于打开状态? 前言

Ms access 如何检查Access 2010表单的实例是否仍处于打开状态? 前言,ms-access,vba,ms-access-2010,Ms Access,Vba,Ms Access 2010,我需要创建一个搜索表单的多个副本(在Access 2010中),该表单向调用返回一个值(也是创建表单实例的表单) 如前所述,这些表单可以且将同时运行多个副本,例如,用户可能希望将公司添加到某个内容中,以便: 单击“选择公司”并打开公司搜索屏幕的实例 然后打开公司编辑器(保持原始公司搜索/选择屏幕打开),因为他们注意到公司有一个尚未添加的母公司 然后单击“选择母公司”按钮,打开搜索和选择屏幕的另一个实例 他们找到了母公司 选择它将关闭第二个搜索屏幕,母公司将添加到第一个公司 然后,用户使用原始搜

我需要创建一个搜索表单的多个副本(在Access 2010中),该表单向调用返回一个值(也是创建表单实例的表单)

如前所述,这些表单可以且将同时运行多个副本,例如,用户可能希望将公司添加到某个内容中,以便:

  • 单击“选择公司”并打开公司搜索屏幕的实例
  • 然后打开公司编辑器(保持原始公司搜索/选择屏幕打开),因为他们注意到公司有一个尚未添加的母公司
  • 然后单击“选择母公司”按钮,打开搜索和选择屏幕的另一个实例
  • 他们找到了母公司
  • 选择它将关闭第二个搜索屏幕,母公司将添加到第一个公司
  • 然后,用户使用原始搜索屏幕选择修改后的公司,该屏幕再次关闭原始搜索屏幕,并将所选公司返回到他们最初初始化第一次搜索的任何形式
这一切都允许用户在发现错误时更新和更正数据,从而减少忘记的可能性,并使其更快

现在大多数情况都很好,但是我遇到了很多问题,表单实例无法作为“acDialog”打开,因此在搜索完成之前停止运行调用代码(有关更多信息,请参阅)我采用的解决方案是,通过使用一个无休止的循环来模拟调用代码的暂停,并检查搜索屏幕的瞬间是否仍然可见。然后,当用户在搜索屏幕上选择某个内容时,它会立即将该值放入搜索屏幕中的隐藏字段中,并隐藏其自身(未关闭)。然后调用函数看到它的隐藏,从隐藏字段中获取值并卸载即时消息

问题 我可以使用FormInstant.Visable检查表单是否隐藏,但如果用户关闭表单,则会导致错误,我通常用于检查表单是否存在的代码需要表单名称,并且由于它是表单的即时名称,因此所有表单都具有相同的名称!我确实有一个对表单的引用,因为它存储在本地“表单”对象中。。。我通常使用的代码是:

CurrentProject.AllForms("FormName").IsLoaded

那么,我如何检查一个表单是否仍在加载呢?

哈哈,我刚刚在重新阅读我的消息时意识到,我可能会捕获错误,以确定表单是否已打开

我很快就写了这篇文章,似乎效果不错:

Public Function IsFormLoaded(ByRef FormToTest As Form, _
                            Optional ByRef bIsVisable As Boolean = False) As Boolean
    Dim lErrorNum As Long
    bIsVisable = False
    On Error Resume Next
        bIsVisable = NewFormClone.Visible
        lErrorNum = Err.Number
    On Error GoTo 0

    If (lErrorNum = 0) Then
        IsFormLoaded = True
    Else
        IsFormLoaded = False
    End If
End Function
我猜谁来回答这个问题并不重要,只要它被回答了,下一个男人/女孩就可以使用它了!:)


我会把这个问题留一段时间,如果没有人找到更好的答案,我会把它标记为…

我喜欢你的答案。至于循环/等待的想法?更好的方法是在每个表单中始终包含一个引用。我通常声明名为frmPrevious的表单模块变量

Create instance of form
Instance.frmPrevious = me
现在我们有了表单“调用”一些代码,当表单关闭时,它代替了一些“可见的”+循环代码设置

因此,在表格的结束代码中,我们有:

frmPrevious.FunctionCodeToRun
上面的方法解决了很多问题,但其中一个问题是您不需要dialog(正如您所注意到的,dialog不能使用),并且您也不需要从调用代码中编写“loop+wait”代码


但是,这并不意味着您的代码将在调用表单中的新函数中继续。因此,我通常将该函数放在调用表单中调用代码的正下方。我还倾向于为该函数使用标准名称。与循环/等待和在同一代码例程中继续相比,我觉得这种折衷是值得的(我确实同意在代码中“继续”通常是可取的,但再次强调,必须编写循环和等待代码并不是很干净)。

一个老问题,但经验告诉我:如果一,二。。。FormDefn实例打开,然后用户关闭一个实例(Master是唯一可以设计的实例),Forms(FormName)给出错误,Forms(Form)给出错误的对象, 但是表单(NumberIndex)仍然存在。Name=FormName

OpenForm创建Forms(FormName)对象。一旦关闭表单(FormName),就会出现错误。任何“Set xForm=New Form_xxx”都会在表单集合中创建表单,这些表单只能通过集合编号索引访问,无法设计

因此,要在以后查找多实例表单,请使用以下内容:

Dim FormIdx     As Integer
Dim lForm       As Access.Form
For FormIdx = 0 To Application.Forms.Count - 1
    Set lForm = AccessFunc.Appl.Forms(FormIdx)
    If lForm.Name = pFormName Then
        IsFormOpened = True
        Set rForm = lForm
        GoTo IsFormOpened_Exit
    End If
Next
也试试这个

Function IsLoaded(strFrmName As String) As Boolean

    '  Determines if a form is loaded.

    Const conFormDesign = 0
    Dim intX As Integer

    IsLoaded = False
    For intX = 0 To Forms.Count - 1
        If Forms(intX).FormName = strFrmName Then
            If Forms(intX).CurrentView <> conFormDesign Then
                IsLoaded = True
                Exit Function  ' Quit function once form has been found.
            End If
        End If
    Next

End Function

您可能还想看看哪个引用了
SysCmd acSysCmdGetObjectState
,再次感谢您。我以前遇到过这个问题,但据我所知,您必须给它传递一个表单名称。由于这是一个表单的实例,表单名称不能唯一地标识它,因此没有任何用处,除非您知道如何使用SysCmd并将表单对象而不是表单名称传递给它?这不是对这个问题的回答,而是导致它的问题。;)我确实首先尝试了这个方法((无法使用输入发布评论!),正如我说的,我确实首先使用了这个方法,但我不喜欢这样一个事实,即您还需要传递返回函数名,然后使用字符串调用它们,这感觉比循环方法更混乱。我最后使用了循环,它工作得非常好。
If Not isLoaded("MyForm") Then
 MsgBox "MyForm is Not Loaded"
End If