如何处理弹出窗口,模态,可调整大小的形式

时间:2017-10-07 02:15:12

标签: ms-access access-vba ms-access-2010

我需要为屏幕不像其他用户大的用户调整大小 - 将表单设置为Popup和Modal以及BorderStyle Resizable有一个主要限制 - 启动弹出窗口的表单中的代码现在不等待表格返回。

那么如何让一个表单变得不可见?我尝试使用sleep和doevents进行循环,但这会使弹出窗口形式响应不快并且会使cpu周期变得很糟糕。我已经尝试设置启动表单的form.gotfocus事件,但这不会触发,这意味着我必须从弹出窗体关闭后执行的代码中拆分打开弹出窗体的代码。

什么是最佳解决方案?

由于

3 个答案:

答案 0 :(得分:0)

您可以使用acDialog选项打开表单:

DoCmd.OpenForm "MyFormName", WindowMode:=acDialog

它将等到表单关闭或隐藏。

答案 1 :(得分:0)

这里的问题是弹出窗口,而模态窗体不会“停止调用代码。”

但更糟糕的是你需要暂停调用代码。这需要一个对话框表格。

更糟糕的是,对话框表格不允许重新调整大小。

你不想在这里混淆3种类型的表格。

模态表单 - 它们与弹出表单不同,与对话框表单截然不同。

Popup表单也是如此。它们不是对话形式,事实上它们也不是模型。

如果您将Access应用程序设置为使用选项卡式文档或重叠窗口,则还必须考虑。 (这将再次限制你的选择)。

如果您使用选项卡式界面,那么如果您想要具有可调整大小的能力,则必须使用弹出窗体 - 但这种类型的窗体不会暂停调用代码。

如果您使用重叠窗口,那么我建议使用模态窗体。 (但它不会停止调用代码,但会允许重新调整大小)。

虽然你“可以”在调用形式中采用一些循环代码来“等待”第二种形式被解雇,但是这样的循环是处理器占用并且经常导致鼠标和打字方面的“差”响应。

所以我建议改变你的代码方法。让调用表单以弹出形式启动表单(如果不使用选项卡式界面,则为模态)。

然后当您关闭表单时,它会调用您想要在调用表单中运行的更多代码。这意味着您必须在关闭第二个表单后拆分要运行的代码 - 并使结束表单调用+运行该代码。

“一般”方法应该避免对表单名称进行硬编码,因为“很多”例程和表单可以调用您的第二种表单,并且设备可以重复使用这些表单。

所以试试这个: 在第二种形式中,创建一个模块级表单变量,如下所示:

Option Compare Database
Option Explicit

Dim frmPrevious     As Form

在此表单的on-open事件中,GRAB将调用表单引用如下:

Set frmPrevious = screen.ActiveForm

现在在窗体关闭事件中,执行以下操作:

frmPrevious.AfterClose

在调用表单中,创建一个名为

的公共函数

AfterClose

因此,在第一种形式的公共函数中,放置关闭第二个表单时要运行的代码。这是" less"理想的然后很好的程序代码调用第二种形式,等待并继续 - 但我认为它仍然是最好的选择。

在关闭之前,您可以传递或“设置”值以返回调用表单,如:

frmPreviuos.SomePubicVar = me!LastNameSelected
frmPrevious!Company = me!CompanySelected
frmPrevious.AfterClose

在上面的第一行中,在调用表单中设置一个公共变量(如果你想这样做并将值传递回第一种形式的模块级变量)。下一行设置调用表单中控件的值(如果要将值传递回调用表单上的某些控件)。

第3行在调用表单中执行MyClose代码。如果您在第二种形式中有某种“确定”或选择按钮,则将上面的代码移到该按钮后面 - 因为如果表单有取消按钮,您可能不希望这样的代码运行(因此取消按钮会简单关闭表单 - 但不要调用+以第一种形式运行上面的代码)。击中X也将被假定为取消或退出。所以你的"保存"或者"确定"或"选择"按钮会有上面的代码。

答案 2 :(得分:0)

我从未遇到DoEvents / Sleep 50循环的任何问题。 CPU负载保持最小,表单响应。

使用非常旧的计算机,也许使用Sleep 100

示例代码:

Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Sub TestOpenForm()

    If FormOpenWait("frmPopup") Then
        MsgBox "Form was hidden.", vbInformation
    Else
        MsgBox "Form was closed.", vbInformation
    End If

End Sub

' Open fName, wait until it is
' - closed : return False
' - hidden : return True
Public Function FormOpenWait(fName As String, Optional sOpenArgs As String = "") As Boolean

    If IsFormLoaded(fName) Then DoCmd.Close acForm, fName, acSaveNo

    DoCmd.OpenForm FormName:=fName, OpenArgs:=sOpenArgs

    ' default: signal "closed"
    FormOpenWait = False

    ' Wait until form is closed or made invisible
    Do While IsFormLoaded(fName)
        If Not Forms(fName).Visible Then
            ' Signal "hidden"
            FormOpenWait = True
            Exit Do
        End If

        ' Wait 50ms without hogging the CPU
        DoEvents
        Sleep 50
    Loop

End Function

Public Function IsFormLoaded(fName As String) As Boolean
    IsFormLoaded = (SysCmd(acSysCmdGetObjectState, acForm, fName) And acObjStateOpen) > 0
End Function