By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
425,548 Members | 1,091 Online
Bytes IT Community
Submit an Article
Got Smarts?
Share your bits of IT knowledge by writing an article on Bytes.

Cascading Forms.

Expert Mod 15k+
P: 31,399
The following code is a class module with an example of its usage to follow.

Class Module Name=classForm
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. '13/3/2007  Added optional parameter varOpenArgs to be passed 'as is' into _
  12.             the new form.
  14. Private Const conUnInitMsg As String = _
  15.                   "Object uninitialised - unable to show form."
  17. Private frmParent As Form
  18. Private WithEvents frmCalled As Form
  20. Public Property Set frmFrom(frmValue As Form)
  21.     Set frmParent = frmValue
  22. End Property
  24. Private Property Get frmFrom() As Form
  25.     Set frmFrom = frmParent
  26. End Property
  28. Private Property Set frmTo(frmValue As Form)
  29.     Set frmCalled = frmValue
  30. End Property
  32. Public Property Get frmTo() As Form
  33.     Set frmTo = frmCalled
  34. End Property
  36. 'Uninitialised returns True if frmFrom not yet initialised.
  37. Public Function Uninitialised() As Boolean
  38.     Uninitialised = (frmFrom Is Nothing)
  39. End Function
  41. 'ShowForm opens form strTo and hides the calling form.  Returns True on success.
  42. Public Function ShowForm(strTo As String, _
  43.                          Optional varOpenArgs As Variant) As Boolean
  44.     ShowForm = True
  45.     'Don't even try if caller hasn't initialised Form object yet
  46.     If Uninitialised() Then
  47.         ShowForm = False
  48.         Call MsgBox(conUnInitMsg, , "classForm.ShowForm")
  49.         Exit Function
  50.     End If
  51.     Call DoCmd.Restore
  52.     'Handle error on OpenForm() only.
  53.     On Error GoTo ErrorSF
  54.     Call DoCmd.OpenForm(FormName:=strTo, OpenArgs:=varOpenArgs)
  55.     On Error GoTo 0
  56.     Set frmTo = Forms(strTo)
  57.     frmFrom.Visible = False
  58.     Exit Function
  60. ErrorSF:
  61.     ShowForm = False
  62.     Call MsgBox("Error found in [" & frmFrom.Name & _
  63.                 ".ShowForm] calling [" & strTo & "]." & VbCrLf & _
  64.                 "Error#=" & Err.Number & " - " & Err.Description & ".")
  65. End Function
  67. '************************* Contained Object Method(s) *************************
  68. 'For these subroutines to be activated the contained object must have the
  69. ''On Close' property set to a valid subroutine within the contained object.
  70. Private Sub frmCalled_Close()
  71.     frmFrom.Visible = True
  72.     Call DoCmd.Restore
  73.     Set frmTo = Nothing
  74. End Sub
  75. '***************************************************************************
This code is an example menu form. It is calls another form (A, B & C) and is called by another menu (D & E) so incorporates all the code required to make it work.
It is a standard in my databases that reports are always maximised and that forms are always restored, so there is code in her to do that, but this can be stripped without losing the main functionality.
  1. To use the classForm class it is necessary to Dim a variable to reference it. This need only be declared as Private as it is referenced exclusively internally.
  2. The variable needs to be set up with the calling form [frmFrom] before it is used in anger.
  3. Invokes a new form. This causes the current form to be hidden until the invoked form is closed.
  4. I would typically have a CommandButton on every form to exit.
  5. In case the x at top-right (or any of a bunch of other methods) is used, the actual tidying up work is (and always should be) done in the Form_Close event procedure. A completely empty procedure is simply dropped at compile time, so a comment line must be included here at least. The class can only pick up (and pass on) the fact that the called form has been closed if this procedure exists in the called form.
Expand|Select|Wrap|Line Numbers
  1. Option Compare Database
  2. Option Explicit
  4. Private clsTo As New classForm                        '<-- A
  6. Private Sub Form_Open(Cancel As Integer)
  7.     Call DoCmd.Restore
  8.     Set clsTo.frmFrom = Me                            '<-- B
  9. End Sub
  11. Private Sub cmdGroupCust_Click()
  12.     Call clsTo.ShowForm(strTo:="frmGroupCust")        '<-- C
  13. End Sub
  15. Private Sub cmdExit_Click()                           '<-- D
  16.     Call DoCmd.Close(ObjectType:=acForm, ObjectName:=Me.Name)
  17. End Sub
  19. Private Sub Form_Close()                              '<-- E
  20.     'Method must exist in order for container to handle event.
  21. End Sub
Mar 12 '07 #1
Share this Article
Share on Google+

Expert 100+
P: 1,356
Nice... BookMarked! Question, how many buttons do you usually run on these forms? I am doing quite well with button management, I have many buttons yet it is neat and tidy but I was curious.
Mar 23 '07 #2

Expert Mod 15k+
P: 31,399
Thank you.
There's not really any limit except the size of the form.
I normally run 1280x1024 resolution but try to design for 1024x768. I run up to seven rows of buttons (Plus my cmdExit button on all forms) and up to two columns. Each button is .8 high and wide and I leave a gap of .2 between each (vertically).

I know I could fit more on, but aesthetically, I want it to be comfortable and easy for the operator to use.
Mar 23 '07 #3