【发布时间】:2019-08-07 14:32:49
【问题描述】:
我正在尝试重构一些 Excel VBA 代码(Excel 2016,VBA 7.1)以消除重复的子例程以实现可维护性目的。几个子例程的区别仅在于它们使用的全局常量组,所以我基本上想要做的是将全局变量组合成一个类似结构的数据结构,这样我就可以将它们作为参数传递给一个公共函数。
请注意,全局常量组有一些共同点,但不是全部,例如:
Global Const GROUP1_SHEET As String = "Sheet1"
Global Const GROUP1_FIRST_ROW As Long = 2
Global Const GROUP1_LAST_COL As Long = 15
Global Const GROUP1_SOME_COL_OFFSET = 4
Global Const GROUP2_SHEET As String = "Sheet2"
Global Const GROUP2_FIRST_ROW As Long = 2
Global Const GROUP2_LAST_COL As Long = 8
Global Const GROUP2_ANOTHER_COL_OFFSET = 2
每个组都有不同的子程序,例如:
在 Sheet1 中:
Private Sub DoSomething()
Set w = Worksheets(GROUP1_SHEET)
'some code
End Sub
在 Sheet2 中:
Private Sub DoSomething()
Set w = Worksheets(GROUP2_SHEET)
'same code as above
End Sub
有几十个。不用说,这段代码连读起来都是一场噩梦,更不用说维护了。
我现在要做的是将组拆分为单独的模块并将它们设置为属性,类似于this question 中描述的内容。问题是我不知道如何将模块(即全局变量组)作为参数传递给函数。
在新模块 GROUP1 中:
Public Property Get SHEET() As String
SHEET = "Sheet1"
End Property
这可以按我的意愿工作:
Public Sub ShowPopup()
MsgBox GROUP1.SHEET
End Sub
但将其作为参数传递不会:
Public Sub Popup(inModule As Object)
MsgBox inModule.SHEET
End Sub
Public Sub ShowPopUp()
Popup GROUP1
End Sub
在上面的示例中,我没有尝试过代替“对象”。我会得到“ByRef 参数类型不匹配”或“预期的变量或过程,而不是模块”,具体取决于我放在那里的内容。
那么,我可以传递这样的模块吗(可能作为字符串并以某种方式对其进行评估?),还是应该使用其他方式对全局变量进行分组?
【问题讨论】:
-
将其设为
Class Module而不是简单的Module,您将能够做到这一点。见cpearson.com/excel/classes.aspx 或stackoverflow.com/q/2161666/8597922 -
谢谢!由于它现在是一个类模块,它必须被实例化,并且由于对象不能是全局常量,所以我必须在 ShowPopUp 中对对象进行 Dim 和 Set 才能将其传入,对吗?如果你回答我会接受。
-
查看CallByName 以调用使用字符串Passing a property as an argument for userform controls 的方法。我不知道你的设计是否被推荐,但你应该问codereview.stackexchange.com