Vba MS Access—模块化/解耦表单以进行重构的最佳方式
所以我最近一直在处理一个大型access数据库,我一直在考虑开始重构它的最佳方法。重构的主要困难之一是大多数表单依赖于其他表单中的数据 目前的做法是这样的Vba MS Access—模块化/解耦表单以进行重构的最佳方式,vba,ms-access,refactoring,modularity,Vba,Ms Access,Refactoring,Modularity,所以我最近一直在处理一个大型access数据库,我一直在考虑开始重构它的最佳方法。重构的主要困难之一是大多数表单依赖于其他表单中的数据 目前的做法是这样的 Form1上有一个名为Cmd1的按钮,它打开一个新表单(DoCmd.OpenForm“Form2”),并使用表单预先填充表单上的一些控件!Form2.Control=Me.Control。关闭Form2时,通过调用Forms将数据返回到Form1!Form1.Control=Me.Control 如果我想更改窗体的名称,或者更改打开弹出窗体的
Form1
上有一个名为Cmd1
的按钮,它打开一个新表单(DoCmd.OpenForm“Form2”
),并使用表单预先填充表单上的一些控件!Form2.Control=Me.Control
。关闭Form2
时,通过调用Forms将数据返回到Form1
!Form1.Control=Me.Control
如果我想更改窗体的名称,或者更改打开弹出窗体的窗体,则会出现问题。它还要求两个表单都是打开的,当您不能使用模式弹出表单时,您不能真正依赖于此,因为用户希望能够在表单之间进行交换
我看到了5种在表单之间来回传递值的方法,每种方法都有问题,我想知道推荐的方法是什么
Public master As Form
Private Sub Form_Load()
Set master = Screen.ActiveForm
Me.Control = master.Control
End Sub
这有点好,因为您可以引用祖辈表单,如master.master.control
,但如果父表单上的控件将来消失,则可能会导致一些重大问题是的,有推荐的方法吗?对于开发专业的、可维护的访问应用程序来说,这是一个非常关键的问题 首先,对您的方法列表进行一些评论:
- 我同意你对方法1和方法2缺点的评估
- #3和#4有着相同的问题:全局表和全局变量一样全局。从根本上说,你不能限制对这两个网站的访问
- #5将不可避免地使你陷入困境。在某些情况下,对表单的超长引用将阻止其关闭
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
这种方法的优点:
Public Form_MyFormNameToOpen as Form_MyFormNameToOpen
(您打开的表单将一直保持打开状态,直到该变量“死亡”,因此将其设置为全局以保持其活动状态)
MyFormNameToOpen是要打开的表单的名称,在我的一些示例代码中,它前面有form_uu。这告诉access获取一个“表单类”,即您创建的表单之一
然后在要打开表单的代码中使用:
' 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
我希望这有帮助
我发现除了最基本的事情外,使用openargs真的很痛苦。使用这样的表格会使生活更轻松
(也许您可以对报表、子表单等使用类似的技术。)既然您的所有数据都保存在某个地方,为什么不准备查询并在表单之间拉/推数据?我的意思是,与其阅读一个表单,将其发送到另一个表单进行编辑和检索,不如告诉第二个表单在哪里找到要编辑和编辑的数据?在第二个表单关闭后,只需刷新第一个表单即可获得更改?不幸的是,我不再处理此项目,但我们不这样做的原因是,所讨论的数据是我们计算其他数据的中间数据,而不是我们实际存储的数据。@wackozacko:如果你有时间,请阅读我的答案。我想要你的反馈!我不喜欢这种方法。我看不出有什么好处。表单模块可以有私有过程和变量。表单模块实际上是表单类的一部分,如果代码多次打开同一表单,它将被实例化多次(使用第二个模块将破坏执行此操作的能力)。您仍然可以将过程添加到表单模块以供外部程序使用(需要一个“规则”来不直接引用表单控件-我同意),但这比第二个模块更简单。也许将这些过程命名为“aa_myProcname”,它们将位于任何列表的顶部。。。。另请参阅我关于使用开放args的回答(在我看来,这是一种垃圾处理方式,应该改用上面提到的表单模块程序)@HarveyFrench:2点:(1)实例化多个访问表单对象的麻烦要多得多。如果你必须这样做