472,952 Members | 2,169 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes and contribute your articles to a community of 472,952 developers and data experts.

Class Module to Handle Opening Forms Hierarchically

32,546 Expert Mod 16PB

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
  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.
  15. Private Const conUnInitMsg As String = _
  16.                   "Object uninitialised - unable to show form."
  18. Private frmParent As Form
  19. Private WithEvents frmCalled As Form
  21. Public Property Set frmFrom(frmValue As Form)
  22.     Set frmParent = frmValue
  23. End Property
  25. Private Property Get frmFrom() As Form
  26.     Set frmFrom = frmParent
  27. End Property
  29. Private Property Set frmTo(frmValue As Form)
  30.     Set frmCalled = frmValue
  31. End Property
  33. Public Property Get frmTo() As Form
  34.     Set frmTo = frmCalled
  35. End Property
  37. 'Uninitialised returns True if frmFrom not yet initialised.
  38. Public Function Uninitialised() As Boolean
  39.     Uninitialised = (frmParent Is Nothing)
  40. End Function
  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
  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
  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
  4. Private clsTo As New classForm
  6. Private Sub Form_Open(Cancel As Integer)
  7.     Set clsTo.frmFrom = Me
  8. End Sub
  10. Private Sub cmdWhatever_Click()
  11.     Call clsTo.ShowForm(strTo:="frmWhatever")
  12. End Sub
  14. Private Sub cmdExit_Click()
  15.     Call DoCmd.Close
  16. End Sub
  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 6649
1,266 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
32,546 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
32,546 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
32,546 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

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...
by: WindAndWaves | last post by:
Dear All Can you tell me why you use a class module??? Thank you Nicolaas ---
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,...
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...
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...
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...
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...
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...
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...
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...
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 4 Oct 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
by: Aliciasmith | last post by:
In an age dominated by smartphones, having a mobile app for your business is no longer an option; it's a necessity. Whether you're a startup or an established enterprise, finding the right mobile app...
by: tracyyun | last post by:
Hello everyone, I have a question and would like some advice on network connectivity. I have one computer connected to my router via WiFi, but I have two other computers that I want to be able to...
by: NeoPa | last post by:
Hello everyone. I find myself stuck trying to find the VBA way to get Access to create a PDF of the currently-selected (and open) object (Form or Report). I know it can be done by selecting :...
by: Teri B | last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course. 0ne-to-many. One course many roles. Then I created a report based on the Course form and...
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 1 Nov 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM) Please note that the UK and Europe revert to winter time on...
by: nia12 | last post by:
Hi there, I am very new to Access so apologies if any of this is obvious/not clear. I am creating a data collection tool for health care employees to complete. It consists of a number of...
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...

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.