MSAccess(2007) - 弹出窗口和模态窗体 - 通过VBA实例化

时间:2017-02-07 10:04:39

标签: access-vba

我陷入了一件非常恼人的事情。

我需要在类模块中打开一个表单,将类本身传递给表单,以便表单可以使用所有类属性和方法。 我说的是表格,而不是关于用户形式。 (在第二种情况下,问题不存在)。 表单必须是popup和modal。

因此,我们假设这个代码在打开表单的调用类方法中使用:

sub OpenFormMethodOfTheCallingClass
    set MyForm = new [Form_FormToBeOpened]
    with MyForm
        set .MyFatherClass = Me
        .SetFocus ' ... this opens the form
        MsgBox "Ok, user has closed the form ..."
    end with
end sub

通过这种方式,代码流程开始了“停止”#34;停止" T"停止"在表格内。 我的意思是消息"好的,用户关闭了表单..."立刻出现,"在前面"打开的表格。 然后,很明显,方法结束,形式(再次,显然)消失,因为它是结束方法的一个实例。

在设计视图中,Popup和Modal表单都设置为TRUE。

以这种方式在调用过程中设置两个属性:

with MyForm
    .Modal = True
    .PopUp = True
    (...)

......根本没有帮助,因为: - MODAL不会影响代码流行为 - 无法设置POPUP(!):它返回运行时错误。

我找到实现目标的唯一方法是以这种方式开放:

DoCmd.OpenForm "FormToBeOpened", WindowMode:=acDialog

这样,代码流程就会卡住"进入表单,只有当用户关闭表单本身时,流程才会返回到调用过程及其后续指令。 但问题是我无法将调用类传递给表单。 好吧,有人可以反对:因为我的表单是MODAL,用户不能打开表单的多个同期实例,因此我可以通过其他方式将调用类的任何属性传递给表单(" bridge-public-variables",或OpenArgs中的JSON ......)。但它真的太可怕了。

我担心,不知道为什么,这是一个非常愚蠢的问题,答案很简单。 :)

让我们看看。

THKS,

FL

2 个答案:

答案 0 :(得分:1)

这是设计的。 Access运行单个线程,因此对话框意味着对话框。

您可以将OpenArgs的静态值传递给对话框表单,但您也可以让它 - 在打开时 - 从调用表单中提取数据和属性。

该代码不一定是丑陋的。

.Net和Visual Studio的WinForms可能更适合您的需求。

答案 1 :(得分:0)

使用.Modal和.Popup = True创建表单类Form_Popup。

在Form_Popup的模块中

  • 添加属性变量,类型为Fils_Class的propFils_Class(如果不允许,则为Variant)
  • 添加Public Sub Let Fils_Class (inputFils_Class as Variant)Public Sub Get Fils_Class (inputFils_Class as Variant)过程以设置和检索propFils_Class
    • 我假设您需要输入变量作为变体,但您可以将它们作为Fils_Class类型传递,但不确定。
  • 在需要Form_Popup的代码中:

    Dim frm as Form, varFils_Class as Fils_Class
    
    '<set up varFils_Class here>
    
    Set frm = New Form_Popup 
    'or Docmd.OpenForm "Popup" hidden etc., then you need to directly reference the form, e.g. Set frm = Forms("Popup")
    
    frm.Fils_Class = varFils_Class
    
    frm.Visible = True
    
    Do While frm.Visible
      Sleep 1
      DoEvents
      '<at some point actions on Form_Popup set .Visible to False>
    Loop
    
    varFilsClass = frm.FilsClass
    
    '<do other actions with frm as needed>
    set frm = Nothing