我做在Excel 2007中的某些VBA编程,并有一个工作簿,所有的数据表是从,被复制到另一个工作表。 新表将有几个标题行,我想跟踪它们位于何处,所以我没有在其中找到的话不断。
是使用类,并让他们运行时的Excel文档是开放的最简单的事情? 还是将使其沉重和难以处理,我应该保持与子程序工作? 什么是使用类的好处是什么? 它不象我有几个对象,仅在列表和验证。
我做在Excel 2007中的某些VBA编程,并有一个工作簿,所有的数据表是从,被复制到另一个工作表。 新表将有几个标题行,我想跟踪它们位于何处,所以我没有在其中找到的话不断。
是使用类,并让他们运行时的Excel文档是开放的最简单的事情? 还是将使其沉重和难以处理,我应该保持与子程序工作? 什么是使用类的好处是什么? 它不象我有几个对象,仅在列表和验证。
使用类,而不是仅仅子程序的优点是类创建了一个抽象,使您能够编写更干净的代码的水平。 诚然,如果你从来没有在VBA之前使用的类,有一个学习曲线,但我相信它肯定是值得的弄明白的时间。
你应该改用类的一个关键指标是,如果你一直在不断增加参数,你的函数和子例程。 在这种情况下,它几乎总是最好使用类。
我已经复制类的解释,从我以前的堆栈溢出的答案之一 :
以下是如何使用一个类可以帮助你长的例子。 虽然这个例子是冗长的,它会告诉你面向对象编程的几个原则如何能真正帮助你清理你的代码。
在VBA编辑器,进入Insert > Class Module
。 在属性窗口(左下默认屏幕),改变模块的名称WorkLogItem
。 下面的代码添加到类:
Option Explicit
Private pTaskID As Long
Private pPersonName As String
Private pHoursWorked As Double
Public Property Get TaskID() As Long
TaskID = pTaskID
End Property
Public Property Let TaskID(lTaskID As Long)
pTaskID = lTaskID
End Property
Public Property Get PersonName() As String
PersonName = pPersonName
End Property
Public Property Let PersonName(lPersonName As String)
pPersonName = lPersonName
End Property
Public Property Get HoursWorked() As Double
HoursWorked = pHoursWorked
End Property
Public Property Let HoursWorked(lHoursWorked As Double)
pHoursWorked = lHoursWorked
End Property
上面的代码将会给我们一个强类型的对象是特定的,以与我们正在使用的数据。 当使用多维阵列来存储数据,代码类似于此: arr(1,1)
是ID, arr(1,2)
是PERSONNAME,和arr(1,3)
是HoursWorked。 使用语法,很难知道什么是什么。 让我们假设你仍然是你的对象加载到一个数组,而是使用WorkLogItem
我们上面创建。 这个名字,你就能够做到arr(1).PersonName
得到这个人的名字。 这使得你的代码更容易阅读。
让我们继续用这个示例的移动。 相反,在存储阵列中的对象,我们会尝试使用collection
。
接下来,添加一个新的类模块,并调用它ProcessWorkLog
。 将下面的代码有:
Option Explicit
Private pWorkLogItems As Collection
Public Property Get WorkLogItems() As Collection
Set WorkLogItems = pWorkLogItems
End Property
Public Property Set WorkLogItems(lWorkLogItem As Collection)
Set pWorkLogItems = lWorkLogItem
End Property
Function GetHoursWorked(strPersonName As String) As Double
On Error GoTo Handle_Errors
Dim wli As WorkLogItem
Dim doubleTotal As Double
doubleTotal = 0
For Each wli In WorkLogItems
If strPersonName = wli.PersonName Then
doubleTotal = doubleTotal + wli.HoursWorked
End If
Next wli
Exit_Here:
GetHoursWorked = doubleTotal
Exit Function
Handle_Errors:
'You will probably want to catch the error that will '
'occur if WorkLogItems has not been set '
Resume Exit_Here
End Function
上面的类将被用来“做什么”用的colleciton WorkLogItem
。 最初,我们只是将它设置为计算的工作小时数。 我们的测试中,我们写的代码。 创建一个新的模块(不是类模块这段时间,只是一个“普通”模块)。 粘贴在模块中下面的代码:
Option Explicit
Function PopulateArray() As Collection
Dim clnWlis As Collection
Dim wli As WorkLogItem
'Put some data in the collection'
Set clnWlis = New Collection
Set wli = New WorkLogItem
wli.TaskID = 1
wli.PersonName = "Fred"
wli.HoursWorked = 4.5
clnWlis.Add wli
Set wli = New WorkLogItem
wli.TaskID = 2
wli.PersonName = "Sally"
wli.HoursWorked = 3
clnWlis.Add wli
Set wli = New WorkLogItem
wli.TaskID = 3
wli.PersonName = "Fred"
wli.HoursWorked = 2.5
clnWlis.Add wli
Set PopulateArray = clnWlis
End Function
Sub TestGetHoursWorked()
Dim pwl As ProcessWorkLog
Dim arrWli() As WorkLogItem
Set pwl = New ProcessWorkLog
Set pwl.WorkLogItems = PopulateArray()
Debug.Print pwl.GetHoursWorked("Fred")
End Sub
在上面的代码, PopulateArray()
简单地创建的集合WorkLogItem
。 在你真正的代码,你可以创建类来分析你的Excel工作表或数据对象,以填补一个集合或数组。
该TestGetHoursWorked()
代码简单演示了如何在类中使用。 您注意到ProcessWorkLog
被实例化一个对象。 它被实例化后,集合WorkLogItem
成为部分pwl
对象。 该行你注意到这个Set pwl.WorkLogItems = PopulateArray()
接下来,我们简单地调用我们写的功能作用在集合WorkLogItems
。
这是为什么有用吗?
我们假设你的数据的变化,你想添加一个新方法。 假设你WorkLogItem
现在包括一个字段HoursOnBreak
,你想添加一个新的方法来计算。
所有你需要做的就是添加一个属性来WorkLogItem
像这样:
Private pHoursOnBreak As Double
Public Property Get HoursOnBreak() As Double
HoursOnBreak = pHoursOnBreak
End Property
Public Property Let HoursOnBreak(lHoursOnBreak As Double)
pHoursOnBreak = lHoursOnBreak
End Property
当然,你需要改变你的方法用于填充您的收藏(我使用的样本方法是PopulateArray()
但你可能应该只为这一个单独的类)。 然后你只需要添加新的方法,以您的ProcessWorkLog
类:
Function GetHoursOnBreak(strPersonName As String) As Double
'Code to get hours on break
End Function
现在,如果我们要更新我们TestGetHoursWorked()
方法返回的结果GetHoursOnBreak
,所有我们必须做的是添加以下行:
Debug.Print pwl.GetHoursOnBreak("Fred")
如果您在代表你的数据值的数组过去了,你就必须找到代码中,你使用的阵列,然后相应地更新它的每一个地方。 如果您使用的类(和它们的实例化对象),而不是,您可以更轻松地更新你的代码修改工作。 此外,当您允许类以多种方式被消耗(也许是一个功能只需要4对象的属性,而其他功能将需要6个),他们仍然可以引用同一个对象。 这使您不必为不同类型的功能的多个阵列。
对于进一步的阅读,我会极力推荐的一个副本VBA开发人员手册,第2版 。 这本书充满了极大的实例和最佳做法,并吨的示例代码。 如果你正在投入大量的时间到VBA一个严重的项目,这是值得你花时间来看看这本书。
如果有很多子程序或子程序的很长,然后在结构化的类可以帮助代码。 如果只有一对夫妇的子程序,说,每个只有10行代码的每一那么这就是超必杀。 构建中类代码的好处是,它更容易阅读和改变,当你回来下来就行了。 因此,另一个原因构建代码为阶级是如果代码是可能需要改变的路线
还有,你可以添加到其他的贡献者已经所述的优点(抱歉,如果它和在地方奔麦科马克出色的答案,我错过了)另一件事情。 类可以有它们的用处,如果你的VBA脚本很可能在某个时候进行重新编程。
举例来说,我设计一个排序顺序管理体系。 这是由几个同事相当长一段时间使用,但可能需要重新预设电台,如果排序规则的改变。 因此我设计了一个基本的股票项目类,收集所有关于股票项目的信息。 这个数据是如何分析任意顺序的规则,但是,写在方便和很好的注释子例程。 通过这样做,我希望未来的VBA编程人员可以很容易地改变用来生成订单的数学规则,而不必处理所有的数据是如何收集的关于特定股票项目(这是所有在类中子程序和函数完成,其中,当所述类被切换一库存数被激活)。 一个类的公共属性,由智能感知也有所回升,允许下一个程序员,以及你自己,能有更简单一些。
我猜的一点是,类可以使生活更方便以后用户通过这种方式,如果它们编码的一些基本信息集,或一些概念性的对象,那就是总是可能相关的程序使用的上下文。