473,320 Members | 2,146 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes and contribute your articles to a community of 473,320 developers and data experts.

Class Module to Handle Opening Forms Hierarchically

NeoPa
32,556 Expert Mod 16PB
Overview

This article shows how to set up and use a Class Module, as well as, more specifically, how to open forms such that they appear as a hierachical menu structure. Form A opens Form B and, while Form B is still open, remains hidden from view. As and when Form B terminates, Form A comes back into view and reassumes the focus.

The code for classForm below includes examples of setting class properties as well as various methods. Of particular interest among the methods is the encapsulated event handler frmCalled_Close(), which is able to be triggered due to the WithEvents keyword used in line #19 (See code below).


Module Code

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.  
  15. Private Const conUnInitMsg As String = _
  16.                   "Object uninitialised - unable to show form."
  17.  
  18. Private frmParent As Form
  19. Private WithEvents frmCalled As Form
  20.  
  21. Public Property Set frmFrom(frmValue As Form)
  22.     Set frmParent = frmValue
  23. End Property
  24.  
  25. Private Property Get frmFrom() As Form
  26.     Set frmFrom = frmParent
  27. End Property
  28.  
  29. Private Property Set frmTo(frmValue As Form)
  30.     Set frmCalled = frmValue
  31. End Property
  32.  
  33. Public Property Get frmTo() As Form
  34.     Set frmTo = frmCalled
  35. End Property
  36.  
  37. 'Uninitialised returns True if frmFrom not yet initialised.
  38. Public Function Uninitialised() As Boolean
  39.     Uninitialised = (frmParent Is Nothing)
  40. End Function
  41.  
  42. 'ShowForm opens form strTo and hides the calling form.  Returns True on success.
  43. Public Function ShowForm(strTo As String, _
  44.                          Optional strFilter As String = "", _
  45.                          Optional varOpenArgs As Variant = Null) As Boolean
  46.     ShowForm = True
  47.     'Don't even try if caller hasn't initialised Form object yet
  48.     If Uninitialised() Then
  49.         ShowForm = False
  50.         Call ShowMsg(strMsg:=conUnInitMsg, strTitle:="classForm.ShowForm")
  51.         Exit Function
  52.     End If
  53.     Call DoCmd.Restore
  54.     'Handle error on OpenForm() only.
  55.     On Error GoTo ErrorSF
  56.     Call DoCmd.OpenForm(FormName:=strTo, _
  57.                         WhereCondition:=strFilter, _
  58.                         OpenArgs:=varOpenArgs)
  59.     On Error GoTo 0
  60.     Set frmTo = Forms(strTo)
  61.     frmFrom.Visible = False
  62.     Exit Function
  63.  
  64. ErrorSF:
  65.     ShowForm = False
  66.     ' If open is cancelled (either by user or code) then simply exit
  67.     If Err.Number <> 2501 Then _
  68.         Call ErrorHandler(strName:=strTo, _
  69.                           strFrom:=frmFrom.Name & ".ShowForm", _
  70.                           lngErrNo:=Err.Number, _
  71.                           strDesc:=Err.Description)
  72. End Function
  73.  
  74. '************************* Contained Object Method(s) *************************
  75. 'For these subroutines to be activated the contained object must have the
  76. ''On Close' property set to a valid subroutine within the contained object.
  77. Private Sub frmCalled_Close()
  78.     frmFrom.Visible = True
  79.     Call DoCmd.Restore
  80.     Set frmTo = Nothing
  81. End Sub
  82. '******************************************************************************

Calling and Using Code

Expand|Select|Wrap|Line Numbers
  1. Option Compare Database
  2. Option Explicit
  3.  
  4. Private clsTo As New classForm
  5.  
  6. Private Sub Form_Open(Cancel As Integer)
  7.     Set clsTo.frmFrom = Me
  8. End Sub
  9.  
  10. Private Sub cmdWhatever_Click()
  11.     Call clsTo.ShowForm(strTo:="frmWhatever")
  12. End Sub
  13.  
  14. Private Sub cmdExit_Click()
  15.     Call DoCmd.Close
  16. End Sub
  17.  
  18. Private Sub Form_Close()
  19.     'Method must exist in order for container to handle event.
  20. End Sub
Line #4 indicates the declaration for the classForm object.
Line #7 indicates the basic setting up of the object. This tells the class which form is the caller for returning to after any called form terminates.
Line #11 indicates calling another form. At this point in the code the class takes over and hides the calling form as well as showing the called form.
Lines #18 through #20 indicate a stub of an event handler that must exist if the class is to be able to capture the called form terminating. This is necessary for the class to re-show the caller form.
Sep 26 '11 #1
7 6694
jimatqsi
1,271 Expert 1GB
That looks like a very useful class. Thanks for the post. :)
Sep 27 '11 #2
Shouldn't a couple of the properties in the class module be Public rather than Private?
Expand|Select|Wrap|Line Numbers
  1. Private Property Get frmFrom() As Form
will stop you being able to use
Expand|Select|Wrap|Line Numbers
  1. Set clsTo.frmFrom = Me
May 1 '18 #3
NeoPa
32,556 Expert Mod 16PB
Are you sure?

I haven't got a copy to hand ATM but it works so I'm not sure what you say makes sense.

If you can show it doesn't work then I'll happily spend the time looking into it, but if you're just confused and want me to do the checking for you then that doesn't work for me.
May 3 '18 #4
Sorry, I should have worded it differently - no, not confused as such just not checking how the code works properly.

My confusion resulted from Private Property Get frmFrom() As Form being declared as Private which caused the intellisense not to suggest frmFrom when I added the Form_Open event.

frmTo is only used within the class module though, so can be Private. This then raises the question of whether it is the better practice to use frmFrom(Property)or frmParent(Member Variable?) within the class - I've no idea, and may be beyond the scope of this question?

Either way - the code works as intended.

Hopefully that made sense.
May 3 '18 #5
NeoPa
32,556 Expert Mod 16PB
Darren Bartrup:
This then raises the question of whether it is the better practice to use frmFrom(Property)or frmParent(Member Variable?) within the class - I've no idea, and may be beyond the scope of this question?
Not beyond the scope. I'm very happy to answer that.

With OOP (Object Oriented Programming) it's very much about boundaries. Manipulating {Instance}.{Property} is generally frowned upon, as this allows the using process uncontrolled access to the class instance. Generally speaking, in OOP, where a class designer wants a using process to have access to elements of the class instance they will (should) provide Property Gets and Property Sets to support that controlled access.

Obviously, it's not always strictly necessary, but it's generally considered good practice, or at least so I understand. Particularly when there is any desire to restrict how the values can be set. I really can't claim to be the best expert at OOP mind you.
May 3 '18 #6
That makes perfect sense, thanks for the pointers.
May 4 '18 #7
NeoPa
32,556 Expert Mod 16PB
Darren Bartrup:
Thanks for the pointers.
No. They're Class Instances! (J/k).

Glad I was able to help :-)
May 4 '18 #8

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

Similar topics

2
by: Enigman O'Maly | last post by:
I'm still somewhat new to object style programming (as will become evident), using VBA in Excel 2000 to automate some previously manual functions. I've defined a class module so that I can...
42
by: WindAndWaves | last post by:
Dear All Can you tell me why you use a class module??? Thank you Nicolaas ---
2
by: windandwaves | last post by:
Hi Gurus I have a module with a bunch of functions that tell me everything about a table (e.g. the number of children, whether it exists, the table description, etc..., data-entry quality,...
15
by: MLH | last post by:
In this forum, under a different subject title, I have explored the following: I want to examine each procedure in my class modules and standard modules (A97) Since the other subject title was...
4
by: debbie | last post by:
Well I'm finally trying out class modules...I have a great book I'm using but its ADO and I use DAO so it's a challenge for me...I've looked most of today, in my book and here but can not find an...
1
by: Alasdair | last post by:
Friends, I'm an old C programmer who upgraded to C++ but was never comfortable with it. I've recently moved to C# and love it but I obviously am missing some of the subtleties. I thought the...
5
by: Shawn Hogan | last post by:
Hi, I have a 3rd party control(infragistics) that seems to alter the VS.NET IDE properties grid so that there are three areas instead of two areas in the VS.NET IDE properties grid. There is a...
1
by: Lauren Wilson | last post by:
Well Wayne, I have made very good use of your excellent FTP class module. There is only one remaining problem: Despite the fact that you defined FTP error codes in FTPClient, I cannot seem to...
6
by: JonathanOrlev | last post by:
Hello everyone, I have a newbe question: In Access (2003) VBA, what is the difference between a Module and a Class Module in the VBA development environment? If I remember correctly, new...
1
by: c2015 | last post by:
I need help with some VB code. I will keep it generic and clear as possible. I have two forms lets call Form1 and Form2 I have a class module (CM) and a sub class module (SCM) instantiated in...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

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.