【问题标题】:MSAccess (2007) - popup and modal form - instancing via VBAMS Access (2007) - 弹出和模态表单 - 通过 VBA 实例化
【发布时间】:2017-06-24 12:34:34
【问题描述】:

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

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

所以让我们假设打开表单的调用类方法中的这段代码:

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

这样,代码流不会在表单内“停止”。 我的意思是消息“好的,用户已经关闭了表单......”立即出现在打开的表单的“前面”。 然后,很明显,方法结束并且表单(同样,显然)消失了,因为它是关闭方法的一个实例。

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

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

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

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

我发现实现目标的唯一方法就是这样打开:

DoCmd.OpenForm "FormToBeOpened", WindowMode:=acDialog

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

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

让我们看看。

谢谢,

FL

【问题讨论】:

    标签: ms-access vba


    【解决方案1】:

    这是设计使然。 Access 运行单线程,所以对话框就是对话框。

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

    该代码不一定是丑陋的。

    .Net 和 Visual Studio 的 WinForms 可能会更好地满足您的需求。

    【讨论】:

    • 是的,对不起,我的意思是对话。已更正。
    • 谢谢 Gustav:我完全同意你关于“哲学”言论的看法(我的意思是 Access 不是结构化编码的正确环境)。但是,我的问题是我不需要“从调用 FORM 中提取数据和属性”,而是从调用 CLASS 中提取数据和属性。如果您再次阅读我的问题(不要这样做!,:D 哲学建议获胜),您会发现我无法将 CALLED 表单准备为以正确“干净”方式传递调用类的对象,但我只能用 DoCmd 打开它,这会阻止我从调用类与其交互。
    • 那么,我想,您唯一的选择就是保存(副本)将 Modal 和 PopUp 设置为 True 的表单。
    • 甚至不是那个(!)。根据我所做的实验(如果我记得很清楚的话),以“正确”(?)方式实例化一个表单(我重复一遍:一个表单,而不是用户表单),我的意思是创建一个对象,设置它的属性然后显示它,使“模态功能”在任何情况下都不起作用。我唯一的选择是让表单显示为 DoCmd.OpenForm "FormToBeOpened", WindowMode:=acDialog ... 但它阻止我“预先设置”表单用户对象属性。因此:“object-bridge-global-variable”......似乎没有其他可能性。 (丑。)
    【解决方案2】:

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

    在 Form_Popup 的模块中

    • 添加属性变量 propFils_Class 类型为 Fils_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
      

    【讨论】:

    • 你是对的。在我的问题中,我忘了说我实际上时不时使用“do-loop方法”来解决这个问题,但我真的不喜欢它,因为它涉及到资源的浪费。
    猜你喜欢
    • 2013-04-18
    • 1970-01-01
    • 2016-10-09
    • 1970-01-01
    • 1970-01-01
    • 2014-05-15
    • 2018-06-24
    • 2017-01-16
    • 1970-01-01
    相关资源
    最近更新 更多