MS Access - 模块化/解耦重构表单的最佳方法

时间:2014-09-18 13:44:37

标签: refactoring access-vba modularity

所以我最近一直在使用大型访问数据库,并且我一直在考虑开始重构它的最佳方法。重构的主要困难之一是,大多数形式依赖于其他形式的数据。

目前的做法是这样的;

Form1上有一个名为Cmd1的按钮,可以打开一个新表单(DoCmd.OpenForm "Form2")并使用Forms!Form2.Control = Me.Control预先填充表单上的一些控件。关闭Form2时,通过调用Form1将数据返回到Forms!Form1.Control = Me.Control

如果我想更改任何一种表格,这就会出现问题。名称或哪个表单打开弹出窗体。它还要求两个表单都是开放的,当您不能使用模式弹出窗体时,您可以真正依赖它们,因为用户希望能够在表单之间进行交换。

我看到了5种在表单之间来回传递值的方法,每种方法都存在问题,我想知道推荐什么。

  1. 如上所述已经采用的方法。
  2. 使用OpenArgs - 因为你必须解析一个字符串并且是单向的,所以会使很多值变得困难。
  3. 使用全局变量 - 这意味着随机模块中存在大量变量,并提出了一个范围噩梦。
  4. 存储要在临时表中的表单之间传递的值。
  5. 使用

    维护对第一个表单的引用
    Public master As Form
    Private Sub Form_Load()
        Set master = Screen.ActiveForm
        Me.Control = master.Control
    End Sub
    

    有一点很好,因为你可以引用像master.master.control这样的祖父母表格,但如果父表格上的控件将来消失,可能会引起一些重大问题。

  6. 所以是的,有推荐的方法吗?

2 个答案:

答案 0 :(得分:-1)

这是开发专业,可维护的Access应用程序的关键问题。

首先,对您的方法列表进行一些评论:

  • 我同意你对方法#1和#2
  • 的缺点的评估
  • #3和#4共享相同的问题:全局表与全局变量一样全局。您无法从根本上限制对这两种方式的访问。
  • #5将不可避免地让你陷入困境。在某些情况下,对表格的额外长期参考将使其无法结束。

我建议将所有业务逻辑移到单独的模块中,按表单分类。这使您可以避免#3和#4的全局问题,因为模块可以具有私有模块级变量和函数。

例如,名为frmFoo的表单将获得名为modFrmFoo的匹配模块。该模块将包含使用frmFoo的所有公共方法:

这是一个简化的modFrmFoo:

Private mvID As Variant

' read-only (no Let)
Public Property Get frmFoo_ID() As Variant
    frmFoo_ID = mvID
End Property

Public Sub frmFoo_Show(ID As Variant, Name As Variant)
    ' note use of temporary object reference
    Dim rFoo As Form_frmFoo
    mvID = ID
    DoCmd.Open acForm, "frmFoo"
    Set rFoo = Forms("frmFoo")
    rFoo.ShowName Name
End Sub

frmFoo表单模块需要一个公共方法:

' only frmFoo should refer to its internal controls and code
Public Sub ShowName(Name As Variant)
    lblName.Caption = Name
End Sub

并且,查询frmFoo:

SELECT ID, [other stuff] FROM tblFoo WHERE tblFoo.ID = frmFoo_ID() 

查询将结果与属性frmFoo_ID()返回的ID值同步。

从另一种形式展示frmFoo很简单:

' frmBar
Private Sub cmdShowFoo_Click() 
    frmFoo_Show 123, "your name"
End Sub

此方法的优点:

  1. 为表单上的所有公共操作定义公共接口。外部表单调用模块,而不是直接调用表单。
  2. 保留所有表单的私有企业私有 - 表单控件可以重命名或删除,而不会破坏所有依赖它的其他表单。
  3. 在一个调用中定义每个方法工作所需的内容 - 例如,frmFoo_Show()需要ID和Name。
  4. 这就是我如何从头开始新的应用程序。

    对于改造旧的,纠结的应用程序是否实用是您的号召。

答案 1 :(得分:-1)

这可能会有所帮助:

您可以打开表单并在不使用Open Args

的情况下控制它们

您可以通过打开另一个表单来完成此操作,就像它是一个类

一样

创建一个名为GlobalVars的模块,其中包含以下行:

Public Form_MyFormNameToOpen as Form_MyFormNameToOpen

(您打开的表单将保持打开状态,直到此变量“死亡”,因此请将其设置为全局以使其保持活动状态)

MyFormNameToOpen是您要打开的表单的名称,并在我的一些示例代码中包含Form_。这告诉访问获取“表单类”,即您创建的表单之一。

然后在要打开表单的代码中使用:

' Opens the form using it as it were a class
Set GlobalVars.Form_MyFormNameToOpen = New Form_MyFormNameToOpen

' The modify the form you have just opened however you want to.
With Form_MyFormNameToOpen
    .Visible = True

    ' This relies ont he control names never changing
    .Controls("ProviderID") = 10
    .Controls("ProviderFileID") = 11


    ' it's better to use properties created on the called form
    ' eg
    .MyLetProviderID = 10
    .MyProviderFileID = 11
End With

我希望这会有所帮助。

我发现除了最基本的东西之外,使用开放的args是一种真正的痛苦。使用这样的表格可以让生活更轻松。

(也许你可以使用类似的报告,子表格等技术......)