473,609 Members | 1,831 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

VBA Class Basics

NeoPa
32,566 Recognized Expert Moderator MVP
Introduction
For this article I'll be using a very simple database which has Form (clsForm) & Report (clsReport) classes that simply handle making the calling Form invisible until the Form, or all of the Reports, opened by it have been closed, and then makes that (calling) Form visible again. All Forms are shown in Restore mode while Reports are shown in Maximise mode. Some selections point to Forms that don't exist and show an error message. One of the selections allows one or more Reports to be run. The main Form (frmMainMenu) and the one that opens the Reports (frmReports) illustrate the fact they're aware the called Form or Report(s) have been closed by showing a Message Box on the screen immediately. It looks untidy as the previous object can still be seen on the screen at the same time, but it's there purely to illustrate the capabilities available.

Hopefully, the relatively simple nature of the process will allow you to understand the concept without too much fluff getting in the way.


Working Attachment
Please find attached, a ZIP file that contains the working example called "UKAUG202311.Ac cDb". Feel free to download it now and have a play with it; make sure you understand what it's doing. You may have no desire to do what it does. What I'm hoping to show is the concept behind it and how classes are used in this case - in order that you understand where, and how, they can be used to do things you want to do.


VBA Classes with Objects
Although VBA classes do not support the generally-understood concept of Encapsulation, they do allow for objects to be contained within the class code, as well as, importantly, their Events to be handled by the class.

There is a caveat to this however, and that is that Events can only be handled by the class, that already have Event procedures in the objects themselves. Thus you could have two different Forms used by two different instances of a class (or even the same instance at different times) where one could have its Event handled by the class but the other not, if the first form had a procedure for the Event but the second did not.


Class/Object Events
User Defined Classes can also define their own Events. Events support passing parameters and, by using the ByRef keyword, these can be used to pass information both ways. A class needs to both define the Event, as well as Raise it (using RaiseEvent). Be aware that IntelliSense is a little less helpful than usual with this statement (RaiseEvent)so you may have to type it out in full in order to use it. Examples of defining & raising the Events can be found in the code below at lines #17, #18, #96 & #97.


Class/Object Properties
Coding Propertys within a Class is done using the three Property procedure types shown below. Each comes with an example definition & usage :
  1. Property Let
    This allows a Class-User to assign a value to this Property in the same way they would assign a value to any normal variable. This does not support objects - just as you can't simply say A = B with object variables (but have to use Set).
    Expand|Select|Wrap|Line Numbers
    1. Definition
    2. Private lngVar As Long
    3.  
    4. Public Property Let Y(Z As Long)
    5.     lngVar = Z
    6. End Property
    7.  
    8. Usage (from outside of the Class module)
    9. Dim X As YourClass
    10.  
    11. X.Y = 326
    Notice how the 326 is passed as Z in the Property Let definition and that the variable is referenced within the Class module as lngVar rather than Y.
  2. Property Get
    This is essentially the reverse of Property Let, except it also works for Objects.
    Expand|Select|Wrap|Line Numbers
    1. Definition
    2. Private lngVar As Long
    3.  
    4. Public Property Get Y() As Long
    5.     Y = lngVar
    6. End Property
    7.  
    8. Usage (from outside of the Class module)
    9. Dim lngA As Long
    10. Dim X As YourClass
    11.  
    12. lngA = X.Y
  3. Property Set
    This is like Property Let except for assigning Objects.
    Expand|Select|Wrap|Line Numbers
    1. Definition
    2. Private frmVar As Form
    3.  
    4. Public Property Set Y(Z As Form)
    5.     Set frmVar = Z
    6. End Property
    7.  
    8. Usage (from outside of the Class module)
    9. Dim X As YourClass
    10.  
    11. Set X.Y = Forms("frmMain")

clsForm Code
Here is the code from that class (clsForm). Feel free to copy it to somewhere more visible, and thus have it to hand, while you go through this section.
NB. When I refer to parts of the code I will do so via the line numbers as shown here below.
Expand|Select|Wrap|Line Numbers
  1. Option Compare Database
  2. Option Explicit
  3.  
  4. '21/1/2004  Added Private Set & Public Get code for frmTo.
  5. '21/9/2004  Removed ResumeTo functionality. _
  6.             Now handled by the OnTimer() subroutine in the calling form _
  7.             checking for (Visible) which indicates the called form is finished.
  8. '24/2/2005  Added function Uninitialised to show if instance of this object _
  9.             has yet been initialised with the callers info. _
  10.             It also checks this before it tries to open a new form.
  11. '31/3/2008  Added varOpenArgs as optional parameter to ShowForm.  Simply to be _
  12.             passed directly to the opened form using DoCmd.OpenForm(). _
  13.             Also set .OpenForm() to treat Cancel of the open as NOT an error.
  14. '3/11/2023  Added the Closed Event which allows the calling code to handle the _
  15.             associated Form being closed.
  16.  
  17. 'Public Event Closed()
  18. Public Event Closed(ByVal strName As String)
  19.  
  20. Private Const conUnInitMsg As String = _
  21.                   "Object uninitialised - unable to show form."
  22.  
  23. Private frmParent As Form
  24. Private WithEvents frmCalled As Form
  25.  
  26. Public Property Set frmFrom(frmValue As Form)
  27.     Set frmParent = frmValue
  28. End Property
  29.  
  30. Private Property Get frmFrom() As Form
  31.     Set frmFrom = frmParent
  32. End Property
  33.  
  34. Private Property Set frmTo(frmValue As Form)
  35.     Set frmCalled = frmValue
  36. End Property
  37.  
  38. Public Property Get frmTo() As Form
  39.     Set frmTo = frmCalled
  40. End Property
  41.  
  42. 'Uninitialised returns True if frmFrom not yet initialised.
  43. Public Function Uninitialised() As Boolean
  44.     Uninitialised = (frmParent Is Nothing)
  45. End Function
  46.  
  47. 'ShowForm opens form strTo and hides the calling form.  Returns True on success.
  48. Public Function ShowForm(strTo As String, _
  49.                          Optional strFilter As String = "", _
  50.                          Optional varOpenArgs As Variant = Null) As Boolean
  51.     ShowForm = True
  52.     'Don't even try if caller hasn't initialised Form object yet
  53.     If Uninitialised() Then
  54.         ShowForm = False
  55.         Call ShowMsg(strMsg:=conUnInitMsg, strTitle:="clsForm.ShowForm")
  56.         Exit Function
  57.     End If
  58.     Call DoCmd.Restore
  59.     'Handle error on OpenForm() only.
  60.     On Error GoTo ErrorSF
  61.     Call DoCmd.OpenForm(FormName:=strTo, _
  62.                         WhereCondition:=strFilter, _
  63.                         OpenArgs:=varOpenArgs)
  64.     On Error GoTo 0
  65.     Set frmCalled = Forms(strTo)
  66.     frmFrom.Visible = False
  67.     Exit Function
  68.  
  69. ErrorSF:
  70.     ShowForm = False
  71.     ' If open is cancelled (either by user or code - 2501) then simply exit
  72.     With Err
  73.         If .Number <> 2501 Then
  74.             Call ErrorHandler(strName:=strTo, _
  75.                               strFrom:=frmFrom.Name & ".ShowForm", _
  76.                               lngErrNo:=.Number, _
  77.                               strDesc:=.Description)
  78.  
  79.             'Call .Raise(Number:=.Number _
  80.                       , Source:=frmFrom.Name & ".ShowForm" _
  81.                       , Description:=.Description)
  82.         End If
  83.     End With
  84. End Function
  85.  
  86. '************************* Contained Object Method(s) *************************
  87. 'For these subroutines to be activated the contained object must have the
  88. ''On Close' property set to a valid subroutine within the contained object.
  89. Private Sub frmCalled_Close()
  90.     Dim strName As String
  91.  
  92.     frmParent.Visible = True
  93.     Call DoCmd.Restore
  94.     strName = frmCalled.Name
  95.     Set frmCalled = Nothing
  96.     'RaiseEvent Closed
  97.     RaiseEvent Closed(strName)
  98. End Sub
  99. '******************************************************************************
Lines #17 - #18 define the Event named Closed which is exposed by the class. Line #17 shows the simpler usage and #18 is used to illustrate how you can pass information to & from the class while handling the Event.

Lines #20 - #21 define an error message used when the class is invoked inappropriately .

Lines #23 - #24 show two different ways to define objects in VBA. #24 is different & special as it allows Events from the object (In this case a Form obviously.) to be handled in the class itself. See lines #86 through #99 of this module for the format of a class's handling of (one of) its WithEvents objects. Notice the name of the Event Procedure includes the name of the specified object as declared in line #24.

Lines #26 - #40 show examples of Property Let/Get/Set procedures. These are explained above under Class/Object Properties. Notice how frmCalled, as defined on line #24, is how the object is referred to internally, yet when presented to users of this class, it is as the Property frmTo.

Lines #42 - #45 show the Uninitialised() Method. Any user of the class must set the value of frmParent using the frmFrom() Property before anything else can work sensibly. This function is provided to test that. It is Public so it can also be called from outside of the class module itself.

Lines #47 - #84 show the ShowForm() Method. This roughly mirrors the DoCmd.OpenForm( ) Method - at least the parameters I ever use. It explicitly handles the Form failing to open but passes any other errors onto the main error handler, which I don't cover here (as irrelevant). However, the code can be found in the attached example database if interested.

Fundamentally, it checks the class instance has been properly initialised then, if it has, Restores the window before opening the Form, using the parameters as passed. Once this has succeeded it sets frmCalled to this Form and hides the parent/calling Form.

Lines #86 - #99 handle the Close event of the called Form (internally referenced as frmCalled - hence the name of frmCalled_Close ()). Once it closes, this procedure ensures frmCalled is reset to Nothing and the parent/calling Form is made visible again. For good measure it Restores the window again. The working basis is that Forms look better in Restore mode while Reports look better Maximised. It also raises the clsForm.Closed Event which allows the calling code, if it handles that Event, to be informed that the called Form has just closed. In this example, for illustration only, it also passes the name of the Form that has just closed. Calling code will ignore this if no Procedure has been defined for this Event.


Conclusion
While the attached example database also includes a clsReport class, along with the clsForm one as shown here, the fundamentals of class usage, & I hope I've kept to the very basics in order to show how straightforward it is getting into the subject, are covered here.

Feel free to leave comments below, but please post any related questions separately (in the Access Questions Forum). Also, feel free to use any parts of this work. Attribution is purely voluntary.
Attached Files
File Type: zip UKAUG202311.Zip (498.1 KB, 77 views)
Oct 24 '23 #1
3 37908
Nauticalgent
100 New Member
Excellent contribution, more to come?
Nov 2 '23 #2
NeoPa
32,566 Recognized Expert Moderator MVP
Thank you :-)

I'm working on a description & breakdown of the clsReport class - also included in the attached database (already).
Nov 2 '23 #3
NeoPa
32,566 Recognized Expert Moderator MVP
For anyone interested, I've just reposted an updated version. This new version contains information on how to get a class to define & raise Events. Thanks are due to John Colby who presented recently at AUG Pacific on some of what he's been doing with classes.

I have also caught up with myself and posted the VBA Class Basics (Report Class) companion article that deals with the clsReport class found in this same database.
Nov 6 '23 #4

Sign in to post your reply or Sign up for a free account.

Similar topics

1
5603
by: Steven Lien | last post by:
I wrote a simple vector class that can store Cards, and my question is if i had Card class, should i "new" it to store into vector , or simply use copy structure?. if i need the vector class to be dynamic?... IE: vector<Card>* p = new vector<Card>(52); or
2
1789
by: Kurien Baker Fenn | last post by:
I would like to show the progress of an application using the progress bar in visual basics using the timer.Please help me. Thanks in advance.
2
1778
by: D | last post by:
Hello I'm learning C++ and having done some Asm and C. I would like input on the following. If I understand what I'm reading then Objects of a type of class gets a copy of it's class' (including inherited classes) data members in memory for each instance of an object. But all the code, of objects of a type of class (including inherited classes) is just one copy in memory to be shared by all the Objects of that type of class. Even with...
5
1203
by: Stephen Russell | last post by:
In the past public void has worked. But I need to return an XMLDocument, and this class needs a string param for the SP to call. public void makeXML (string lcStatement) wont allow me to return a doc. I guess too many beers last night? XmlDoc = new XmlDataDocument(); XmlDoc.LoadXml(XmlRdr.ReadOuterXml());
5
1004
by: Simon Harris | last post by:
Hi All, Being a classic ASP programmer, I'm trying to get to grips with OOP, specifically using classes. I have setup my class with various properties, so far so good. What I dont quite get is the logic of using the properties. E.g. If I want to get the RoadName property of my address class into a database, do I do something like this...
3
5302
by: Peskov Dmitry | last post by:
Hi, What is the memory layout of an object, and the derived object. For example : class A { private: int prv_data; protected: int pro_data;
0
3225
by: babu8880 | last post by:
www.convensysglobal.com/elearn You can login and attend courses and similar resources ask your doubts from experienced engineers in iphone and Objective C Domain You can attend live classes through our website with experienced teachers available world wide. Some among you can also be teachers while others will be your students. This is fun and adds knowledge in the domain of i-Phone Development. We request all users to be active in...
1
9663
by: perto1 | last post by:
Hi, I am a first semester student, learning the OOPs basics. I need help for a program: class Message{ public: void input(); int output(); private: long token_number;// next token to be given to client };
0
31134
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be focusing on the Report (clsReport) class. This simply handles making the calling Form invisible until all of the Reports opened by it have been closed, when it then makes that (calling) Form visible again. This article is released as a companion to the VBA Class Basics one that focuses on opening Forms. All Forms are shown in Restore mode while Reports are shown in Maximise mode. Working Attachment...
0
8139
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8579
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8555
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8232
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8408
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7024
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5524
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4032
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
1686
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.