我应该何时将VBA代码从表单模块移动到单独的模块?

时间:2012-04-26 08:35:43

标签: ms-access ms-access-2007 access-vba

我有很多实例,我从一个基本子表单开始,然后我有3个其他子表单构建在它上面,每个子表单添加一些不同的基本子元素。这意味着我有一个每个子表单的代码页,有很多重复。是否可以将公共元素放入单独的模块中,并且只在其代码页上留下与每个子表单相关的附加代码?这有什么性能问题吗?

3 个答案:

答案 0 :(得分:1)

简短回答,是的,这样做,拆分每个表单之间重复的代码。

更长的答案,但在我看来,删除重复到单独的模块或类中的代码是更好的方法。

类使您的代码更易于管理且更易于维护。如果您的代码在多个地方相似,则会使维护变得更加困难,因为您必须在每个位置更改它。将它放在一个地方可以更容易管理和维护。

优势列表取自Chicago Access Users Group (CAUG) talk - "Class Modules in Access"

Advantages of using classes/objects:
 - let's you create more complex objects than tables or queries provide
   alone
 - using classes within classes let's you restrict function visibility
 - class methods & attributes are more descriptive than module's
   function list alone
 - let's you use Intellisense for more efficient coding
 - no "ambiguous name" errors with multiple copies of the same class
   module
 - can copy class modules without worry of creating ambiguous function
   names
 - static variables are implicit in class objects, and so are easier to
   manage
 - isolating access layers within wrapper classes promote
   portability/maintainability
 - better support for separation of UI/business logic/data access =
   n-tier development
 - promotes modular thinking in analysis, design
 - easier to adapt many publicly-available object models to Access apps
 - prepares you for transition to .NET and other fully object-oriented
   architectures

答案 1 :(得分:1)

如果我理解这个问题,是的,您可以将一定数量的代码集中到标准代码模块中。可能有很多方法可以做到这一点,但更好的方法之一是将表单对象传递给您的函数。这是一个例子:

Private Sub Form_BeforeUpdate(Cancel As Integer)
    If ValidateContact = False Then Cancel = True
End Sub

'This code goes in a standard code module not associated with any form
Public Function ValidateContact(ByRef frm as Form) as Boolean
    Dim bValid as Boolean
    bValid = True
    If Nz(frm!FirstName, "") = "" Then
        MsgBox "First Name cannot be blank."
        bValid = False
    ElseIf Nz(frm!LastName, "") = "" Then
        MsgBox "Last Name cannot be blank."
        bValid = False
    End If
    ValidateContact = bValid
End Function

另外,如果我理解正确,你的问题根本就不是使用类模块/类对象,至少不是明确的。 (事实上​​,你在Access中编写的代码基本上都是使用类对象,通常是隐式的。)另一个SO用户已经发布了一个很好的答案,关于在Access中使用Class对象的好处,所以我不会解释更多关于此。实际上,标准代码模块基本上是一个Singleton类,不必像类对象那样实例化。有一些原因可以解释为什么单独/标准代码模块是首选的,至少在某些方面是这样,如果没有其他原因,那么它更容易调用函数。但是,如果您发现自己编写的函数包含大约四个或更多参数,那么您可能会将其更改为类对象,从而可以在调用相关方法之前设置属性。

答案 2 :(得分:1)

关于问题的最后一部分,“这是否有任何性能问题?

我知道有两个后果:

  1. 表单加载时间
  2. 内存使用
  3. 作为一个假设的例子,假设您有一个带有制表符控件的表单。该选项卡控件包含10个页面,每个页面包含一个子窗体。如果这些子表单包含相同VBA代码的副本,则必须为每个子表单再次加载该公共代码。这需要时间并增加内存使用。

    如果将公共代码移动到标准模块并从子表单引用它,则只需加载一次...减少表单加载时间和内存消耗。

    因此,最终结果是您正在考虑的方法可以使您的应用程序更具响应性......这可能会让用户感到更快乐。

    然而,即使这种方法没有产生显着的性能提升,我仍然会这样做,因为这意味着你只需要维护一个公共代码的副本。