Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to use a Class in VBA?

Tags:

oop

class

vba

When is it appropriate to use a class in Visual Basic for Applications (VBA)?

I'm assuming the accelerated development and reduction of introducing bugs is a common benefit for most languages that support OOP. But with VBA, is there a specific criterion?

like image 915
Curtis Inderwiesche Avatar asked Sep 23 '08 02:09

Curtis Inderwiesche


People also ask

How do you use classes in VBA?

To add a new VBA Class go to the menu and select Insert then select Class Module . Classes in VBA are similar to regular VBA modules. They have their own namespace and can consist of procedures, functions, variables etc. There are other things you will find in a VBA Class, but we will get to that.

What is the difference between a module and a class?

What is the difference between a class and a module? Modules are collections of methods and constants. They cannot generate instances. Classes may generate instances (objects), and have per-instance state (instance variables).

What's the difference between a module and a class module in VBA?

A class is more of a unit, and a module is essentially a loose collection of stuff like functions, variables, or even classes. In a public module, classes in the project have access to the functions and variables of the module. You don't have to specify the module name to address one.

What is class and object in VBA?

A class describes the variables, properties, procedures, and events of an object. Objects are instances of classes; you can create as many objects you need once you have defined a class.


2 Answers

It depends on who's going to develop and maintain the code. Typical "Power User" macro writers hacking small ad-hoc apps may well be confused by using classes. But for serious development, the reasons to use classes are the same as in other languages. You have the same restrictions as VB6 - no inheritance - but you can have polymorphism by using interfaces.

A good use of classes is to represent entities, and collections of entities. For example, I often see VBA code that copies an Excel range into a two-dimensional array, then manipulates the two dimensional array with code like:

Total = 0 For i = 0 To NumRows-1     Total = Total + (OrderArray(i,1) * OrderArray(i,3)) Next i 

It's more readable to copy the range into a collection of objects with appropriately-named properties, something like:

Total = 0 For Each objOrder in colOrders     Total = Total + objOrder.Quantity * objOrder.Price Next i 

Another example is to use classes to implement the RAII design pattern (google for it). For example, one thing I may need to do is to unprotect a worksheet, do some manipulations, then protect it again. Using a class ensures that the worksheet will always be protected again even if an error occurs in your code:

--- WorksheetProtector class module ---  Private m_objWorksheet As Worksheet Private m_sPassword As String  Public Sub Unprotect(Worksheet As Worksheet, Password As String)     ' Nothing to do if we didn't define a password for the worksheet     If Len(Password) = 0 Then Exit Sub      ' If the worksheet is already unprotected, nothing to do     If Not Worksheet.ProtectContents Then Exit Sub      ' Unprotect the worksheet     Worksheet.Unprotect Password      ' Remember the worksheet and password so we can protect again     Set m_objWorksheet = Worksheet     m_sPassword = Password End Sub  Public Sub Protect()     ' Protects the worksheet with the same password used to unprotect it     If m_objWorksheet Is Nothing Then Exit Sub     If Len(m_sPassword) = 0 Then Exit Sub      ' If the worksheet is already protected, nothing to do     If m_objWorksheet.ProtectContents Then Exit Sub      m_objWorksheet.Protect m_sPassword     Set m_objWorksheet = Nothing     m_sPassword = "" End Sub  Private Sub Class_Terminate()     ' Reprotect the worksheet when this object goes out of scope     On Error Resume Next     Protect End Sub 

You can then use this to simplify your code:

Public Sub DoSomething()    Dim objWorksheetProtector as WorksheetProtector    Set objWorksheetProtector = New WorksheetProtector    objWorksheetProtector.Unprotect myWorksheet, myPassword     ... manipulate myWorksheet - may raise an error  End Sub  

When this Sub exits, objWorksheetProtector goes out of scope, and the worksheet is protected again.

like image 126
Joe Avatar answered Sep 21 '22 01:09

Joe


I think the criteria is the same as other languages

If you need to tie together several pieces of data and some methods and also specifically handle what happens when the object is created/terminated, classes are ideal

say if you have a few procedures which fire when you open a form and one of them is taking a long time, you might decide you want to time each stage......

You could create a stopwatch class with methods for the obvious functions for starting and stopping, you could then add a function to retrieve the time so far and report it in a text file, using an argument representing the name of the process being timed. You could write logic to log only the slowest performances for investigation.

You could then add a progress bar object with methods to open and close it and to display the names of the current action, along with times in ms and probable time remaining based on previous stored reports etc

Another example might be if you dont like Access's user group rubbish, you can create your own User class with methods for loging in and out and features for group-level user access control/auditing/logging certain actions/tracking errors etc

Of course you could do this using a set of unrelated methods and lots of variable passing, but to have it all encapsulated in a class just seems better to me.

You do sooner or later come near to the limits of VBA, but its quite a powerful language and if your company ties you to it you can actually get some good, complex solutions out of it.

like image 34
ajp Avatar answered Sep 20 '22 01:09

ajp