VBA - 试图了解如何调用类模块
Posted
技术标签:
【中文标题】VBA - 试图了解如何调用类模块【英文标题】:VBA - Trying to understand how to call Class Modules 【发布时间】:2020-09-15 17:49:28 【问题描述】:我正在通过 Google、YouTube 等学习 VBA。我遇到了 Class Modules。
我有一个Tracker Template
。
每隔几天我就会收到一份报告 ("Ice cream FG Inv.xlsm"
)
在尝试理解Class Modules
时,我发现了一个模板,该模板创建了一个类模块(在跟踪器模板中)WBIceCreamFGINVxlsm
,为Ice Cream FG Inv.xlsm Workbook
中的所有工作表创建了一个代码名。
例子:
Public Property Get wsinventory() As Worksheet
Set wsinventory = Workbook.Worksheets("Inventory")
End Property
在我的模块中,我想引用 wsinventory
,但不了解如何“调用”类模块..
两个工作簿都是打开的。
我试着从:
Dim Data As Variant
Data = wsinventory.Range("A1").CurrentRegion.Value (**Variable not Defined**)
然后我尝试了:
Dim wsinventory As Worksheets
With wsinventory
Dim Data As Variant
Data = .Range("A1").CurrentRegion.Value (**Object variable or With variable not set**)
End With
我还需要使用吗:
Dim DataSource As Workbook
Set DataSource = Workbooks("Ice Cream FG Inv.xlsm")
With DataSource.Worksheets("Inventory")
End With
如果是这样,使用类模块的原因是什么?
【问题讨论】:
看来你过于复杂了。 我很有可能!我疯狂地在谷歌上搜索 VBA,试图找到最好/有效的做事方式。所以,什么时候可以使用类模块。 不是这个场合...我会先专注于学习 Excel 对象模型。 相关或重复:***.com/a/1740020/13813219 【参考方案1】:您需要先创建一个类对象,然后才能访问该类的属性。
假设你有这个类并将其命名为TestClass
:
Private pwsinventory As Worksheet
Public Sub init()
Set pwsinventory = Worksheets("Inventory")
End Sub
Public Property Set wsinventory(lwsinventory As Worksheet)
Set pwsinventory = lwsinventory
End Property
Public Property Get wsinventory() As Worksheet
Set wsinventory = pwsinventory
End Property
您可以像这样设置/获取属性:
Sub test()
Dim datacls As TestClass
Dim data As Worksheet
Set datacls = New TestClass
Set datacls.wsinventory = Worksheets("inventory")
Set data = datacls.wsinventory
Debug.Print data.Name
End Sub
然而,这有点奇怪,当你有一个不想设置的属性(你需要传递一个参数)时,你应该使用一个启动函数。不幸的是,如果不在创建类对象后手动调用该 sub,我就无法做到这一点。
Sub Test2()
Dim datacls As TestClass
Set datacls = New TestClass
datacls.init
Debug.Print datacls.wsinventory.Name
End Sub
我使用类的最常见情况是更好的容器。通常在数组/字典中存储许多相同的类类型,因此很清楚我在调用什么,特别是如果我需要为每个实例以相同的方式修改数据。
【讨论】:
【参考方案2】:我将再举一个例子。创建一个类定义并命名为ArrayData
,并定义多个初始化子程序
ArrayData.cls
Private m_data() As Variant
Private Sub Class_Initialize()
End Sub
Public Sub IntializeEmpty(ByVal rows As Long, ByVal columns As Long)
ReDim m_data(1 To count, 1 To columns)
End Sub
Public Sub InitializeFromRange(ByRef target As Range)
If target.rows.count > 1 Or target.columns.count > 1 Then
m_data = target.Value2
Else
ReDim m_data(1 To 1, 1 To 1)
m_data(1, 1) = target.Value
End If
End Sub
Public Sub InitializeFromArray(ByRef data() As Variant)
m_data = data
End Sub
Public Property Get RowCount() As Long
RowCount = UBound(m_data, 1) - LBound(m_data, 1) + 1
End Property
Public Property Get ColCount() As Long
ColCount = UBound(m_data, 2) - LBound(m_data, 2) + 1
End Property
Public Property Get Item(ByVal row As Long, ByVal col As Long) As Variant
Item = m_data(row, col)
End Property
Public Property Let Item(ByVal row As Long, ByVal col As Long, ByVal x As Variant)
m_data(row, col) = x
End Property
模块
要测试代码模块中的代码,请使用 New
关键字初始化类,然后调用自定义初始化子例程之一。
Public Sub TestArray()
Dim arr As New ArrayData
arr.InitializeFromRange Sheet1.Range("A2").Resize(10, 1)
Dim i As Long
For i = 1 To arr.RowCount
Debug.Print arr.Item(i, 1)
Next i
End Sub
PS。另请阅读this article,了解如何将一个属性指定为默认属性。在上面的示例中,如果Item
是默认属性,那么您可以编写如下代码
Debug.Print arr(5,2)
而不是
Debug.Pring arr.Item(5,2)
【讨论】:
以上是关于VBA - 试图了解如何调用类模块的主要内容,如果未能解决你的问题,请参考以下文章