首页 > 解决方案 > Excel VBA 代码 - 全局模块/子 OOP 友好?

问题描述

我一直在编写一些 Excel VBA 代码,希望使其可扩展、可维护且易于阅读。代码中的某些变量需要唯一的硬编码范围,而其他变量则存储常见/重复信息。我将通用/重复代码移至全局模块,以减少需要使用相同信息定义的次数,但我担心这会使跟踪代码变得太困难或让代码在以后出现错误通过拥有公共变量。这是进行编码的好方法,还是有更有效/用户友好的方法来使它成为 OOP?

片段如下。

模块:mCommon

Option Explicit

Public wrkshtInput As Object
Public rngPartSize As Range
Public rngPart2Size As Range

Sub CommonDefinitions()

    Set wrkshtInput = Worksheets("INPUT (BOM)")
    Set rngPartSize = Range("C5")
    Set rngPartSize2 = Range("C6")
End Sub

模块:mUI

Option Explicit

Sub PartToggle()
'OBJECT REF(S):     Sheet2 (INPUT (BOM))
'METHOD REF(S):     mCommon.CommonDefinitions
'VARIABLE REF(S):   mCommon.wrkshtInput, mCommon.rngPartSize

    'COMMON VARIABLE DEFINITIONS:
    Call mCommon.CommonDefinitions

    'DEFINE VARIABLES:
    Set rngBlueACM = Range("H129:H134, H136:H141, H144:H147")
    Set rngRedACM = Range("H149:H154, H156:H161, H164:H167")

    'PART TOGGLE: ON
    If mCommon.wrkshtInput.tglbtnPartToggle.Value = True Then
        mCommon.rngPartSize.Value = ""
        rngBlueACM.Value = "MANUAL"
        rngRedACM.Value = "MANUAL"
    End If

    'PART TOGGLE: OFF
    If mCommon.wrkshtInput.tglbtnPartToggle.Value = False Then
        mCommon.rngPartSize.Value = "--"
        rngBlueACM.Value = "--"
        rngRedACM.Value = "--"
    End If
    
End Sub

Sub Part2Toggle()
'OBJECT REF(S):     Sheet2 (INPUT (BOM))
'METHOD REF(S):     mCommon.CommonDefinitions
'VARIABLE REF(S):   mCommon.wrkshtInput, mCommon.rngPart2Size

    'COMMON VARIABLE DEFINITIONS:
    Call mCommon.CommonDefinitions

    'DEFINE VARIABLES
    Set rngWhiteACM = Range("H107:H108")

    'PART2 TOGGLE: ON
    If mCommon.wrkshtInput.tglbtnPart2Toggle.Value = True Then
        mCommon.rngPart2Size.Value = ""
        rngWhiteACM.Value = "MANUAL"
    End If

    'PART2 TOGGLE: OFF
    If mCommon.wrkshtInput.tglbtnPart2Toggle.Value = False Then
        mCommon.rngPart2Size.Value = "--"
        rngWhiteACM.Value = "--"
    End If
    
End Sub

标签: vbareadabilitymaintainability

解决方案


这个

Set rngPartSize = Range("C5") 

有一个缺陷,它没有工作表限定符,因此将返回一个范围从恰好是活动工作表的任何内容。

您的“通用”代码也不需要在您想要使用其中的一部分时进行初始化 - 让这些调用在您的代码中传播有点尴尬。

如果您想成为“面向对象”,那么更好的方法(IMO)是:

首先:更改工作表的代号,而不是经常需要运行以下内容:

Set wsData = ThisWorkbook.Worksheets("Data")

你可以直接在你的代码中引用DataLists等等。

下一步:使用工作表代码模块定义“属于”这些工作表的方法。一个很好的例子是输入各种参数的“输入”表。所以说你有“帐号”,你可以把它放在你的工作表模块中Inputs

Const RNG_ACCT_NUM As string = "D10"

Property Get Accountnumber()
    Accountnumber = Me.Range(RNG_ACCT_NUM).Value
End Property
Property Let Accountnumber(v)
    Me.Range(RNG_ACCT_NUM).Value = v
End Property

现在您可以在代码中使用它:

Dim acct
acct = Inputs.AccountNumber
'or
Inputs.AccountNumber = "AB3456"

代替

Dim wsInputs As Worksheet, acct 
Set wsInputs = ThisWorkbook.Worksheets("Inputs")

acct = wsInputs.Range("D10")
'....
wsInputs.Range("D10") = "AB3456"

推荐阅读