473,386 Members | 1,779 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

How to detect a Sub-Form event from the Main Form?

119 100+
I have an Access form (MainForm) that has a SubForm. I would like to know if a MainForm event exists that detects a SubForm record change.

I can use the "On Current" event to detect when the MainForm record changes, but does an event such as "On SubForm On Current" exist?

Many thanks,
Nov 7 '08 #1
13 25824
Stewart Ross
2,545 Expert Mod 2GB
Hi. It is the subform's On Current event that fires for each record in the subform. The main form cannot receive or handle the subform's events. If you wish to use this event you have to place the code in the subform itself.

Whilst it may technically be possible to set up custom event handlers for your subform to which the main form could listen this is not a trivial task. I have not tried this with a main form / sub form combination so I cannot say for sure that it is even possible to use this approach. Custom event handlers can work well for independent forms.

If you wish to call subroutines or functions outside of the scope of your form's code modules (which are local in scope to the form concerned and not visible to any other form, even in mainform/subform combinations) you will need to place the code concerned in a public code module (i.e. one that is shown in the Modules tab of the database window). You can then call the code as necessary from the relevant On Current event handler.

-Stewart
Nov 7 '08 #2
billelev
119 100+
Thanks for your help...In trying to implement a solution, I encountered a related problem, which will involve some more explanation...

MainForm has two sub-forms, SubForm1 and SubForm2.

When the record in SubForm1 changes, I want to display different records in SubForm2.

I can almost achieve this by using the following code in the Form_Current event of SubForm1

Expand|Select|Wrap|Line Numbers
  1. ' === Code in SubForm1 ===
  2.  
  3. Private Sub Form_Current()
  4.  
  5.     If CurrentProject.AllForms("MainForm").IsLoaded Then
  6.         If CurrentProject.AllForms("SubForm2").IsLoaded Then
  7.             'If MainForm is loaded when SubForm1 record gets changed, change
  8.             ' the filter in SubForm2
  9.             Forms("MainForm").SubForm2.Form.Filter = "ChartId=" & Me.ChartID
  10.         End If
  11.     End If
  12.  
  13. End Sub

The problem here is that whilst the code recognizes that MainForm is open, the "IsLoaded" property does not get set to TRUE for sub-forms. Do you know of a way of determining whether or not a form is open as a sub-form?
Nov 7 '08 #3
Stewart Ross
2,545 Expert Mod 2GB
Hmm, unless you have some form of automated selection of which subform is loaded as part of the main form, wouldn't it always be the case that the subform must be present if the main form is?

Anyway, there is no built-in function that checks for the subform being loaded, but the following simple custom function returns true if the named subform control is present on the main form and false otherwise. I really do think this is a redundant check, however.

Expand|Select|Wrap|Line Numbers
  1. Public Function fSubformLoaded (mainformname As String, subformname As String)
  2.   Dim Result As Boolean
  3.   On Error Resume Next
  4.   Result = Not IsNull(Forms(mainformname).Controls(subformname).Form.Name)
  5.   fSubformLoaded = Result
  6. End Function
If the subform control does not exist on the main form an error will result, which is dealt with safely by the On Error Resume Next, resulting in return of the default value False for variable Result. If the control does exist then the subform's name property is non-null and the function will return True instead.

-Stewart
Nov 7 '08 #4
billelev
119 100+
Hmm, unless you have some form of automated selection of which subform is loaded as part of the main form, wouldn't it always be the case that the subform must be present if the main form is?

Anyway, there is no built-in function that checks for the subform being loaded, but the following simple custom function returns true if the named subform control is present on the main form and false otherwise. I really do think this is a redundant check, however.

Expand|Select|Wrap|Line Numbers
  1. Public Function fSubformLoaded (mainformname As String, subformname As String)
  2.   Dim Result As Boolean
  3.   On Error Resume Next
  4.   Result = Not IsNull(Forms(mainformname).Controls(subformname).Form.Name)
  5.   fSubformLoaded = Result
  6. End Function
If the subform control does not exist on the main form an error will result, which is dealt with safely by the On Error Resume Next, resulting in return of the default value False for variable Result. If the control does exist then the subform's name property is non-null and the function will return True instead.

-Stewart
You are correct in that the sub-forms are always present when the MainForm is loaded, with one key exception...When MainForm is originally loading. This is causing the problem. That's why I wanted the code in SubForm1 to check to see if SubForm2 had loaded.

Once MainForm is loaded (and therefore the sub-forms) I don't need any checks, i.e. I can simply use:

Expand|Select|Wrap|Line Numbers
  1. Private Sub Form_Current()
  2.             Forms("frmChartSeries").frmSeries.Form.Filter = "ChartId=" & Me.ChartID
  3. End Sub
I did find a work around, which isn't particularly elegant, but it seems to do the trick...The Visible property is only visible after the form (and sub-forms) has fully loaded...I just won't apply the filter when the form loads (which doesn't matter, anyway).

Expand|Select|Wrap|Line Numbers
  1. Private Sub Form_Current()
  2.     If CurrentProject.AllForms("MainForm").IsLoaded And Forms("MainForm").Visible Then
  3.             Forms("MainForm").SubForm2.Form.Filter = "ChartId=" & Me.ChartID
  4.     End If
  5. End Sub

Your suggestions also works, so many thanks for you help!
Nov 8 '08 #5
ADezii
8,834 Expert 8TB
Thanks for your help...In trying to implement a solution, I encountered a related problem, which will involve some more explanation...

MainForm has two sub-forms, SubForm1 and SubForm2.

When the record in SubForm1 changes, I want to display different records in SubForm2.

I can almost achieve this by using the following code in the Form_Current event of SubForm1

Expand|Select|Wrap|Line Numbers
  1. ' === Code in SubForm1 ===
  2.  
  3. Private Sub Form_Current()
  4.  
  5.     If CurrentProject.AllForms("MainForm").IsLoaded Then
  6.         If CurrentProject.AllForms("SubForm2").IsLoaded Then
  7.             'If MainForm is loaded when SubForm1 record gets changed, change
  8.             ' the filter in SubForm2
  9.             Forms("MainForm").SubForm2.Form.Filter = "ChartId=" & Me.ChartID
  10.         End If
  11.     End If
  12.  
  13. End Sub

The problem here is that whilst the code recognizes that MainForm is open, the "IsLoaded" property does not get set to TRUE for sub-forms. Do you know of a way of determining whether or not a form is open as a sub-form?
The method to check and see if a Form is Loaded as a Sub-Form is to check its Parent Property, as in:
Expand|Select|Wrap|Line Numbers
  1. Public Function fIsSubFormLoaded(frm As Form) As Boolean
  2. 'Is the form referenced in the Parameter currently loaded as a subform?
  3. 'We can check its Parent property to find out.
  4. Dim strName As String
  5.  
  6. On Error Resume Next
  7.  
  8. strName = frm.Parent.Name
  9. fIsSubFormLoaded = (Err.Number = 0)
  10. Err.Clear
  11. End Function
Expand|Select|Wrap|Line Numbers
  1. If fIsSubFormLoaded(Me) Then
  2.   MsgBox "It is Loaded as a Sub-Form"
  3. Else
  4.   MsgBox "It is Loaded as a Stand Alone Form"
  5. End If
Nov 8 '08 #6
ADezii
8,834 Expert 8TB
I'm a little rusty on this Topic but you should be able to detect Events in a Sub-Form from a Main Form by 'Hooking' to it:
  1. In the Main Form's Declarations Section, Declare a WithEvents Reference to the Sub-Form:
    Expand|Select|Wrap|Line Numbers
    1. Private WithEvents frmSubForm As Form
  2. In the Load() Event of the Main Form, 'Hook' it to the Sub-Form:
    Expand|Select|Wrap|Line Numbers
    1. Private Sub Form_Load()
    2. Set frmSubForm = Forms![frmSubFormDemo]![subfSubForm].Form
    3.  
    4. frmSubForm.OnCurrent = "[Event Procedure]"
    5. End Sub
  3. Haven't had time to play with it, but you should somehow be able to react to the Current() Event of the Sub-Form from the Main Form.
Nov 8 '08 #7
missinglinq
3,532 Expert 2GB
I'm confused by this statement!
You are correct in that the sub-forms are always present when the MainForm is loaded, with one key exception...When MainForm is originally loading
The fact is by the time the MainForm is originally loading, the subforms are already loaded! Subforms always load before the main form loads, unless, of course, a tear has occurred in the time continuum of space.

Linq ;0)>
Nov 8 '08 #8
FishVal
2,653 Expert 2GB
I'm confused by this statement!

The fact is by the time the MainForm is originally loading, the subforms are already loaded! Subforms always load before the main form loads, unless, of course, a tear has occurred in the time continuum of space.

Linq ;0)>
Though it is certainly not the case, but I'd like to point out that is not true for main form being in datasheet view - subform will not be loadad until subdatasheet expanded.

@OP
A simple recursive procedure you could find here will help you to find a form opened in subform control.

@ADezii
Declaring form variable with events is certainly the best way to handle subform's events in main form module

Regards,
Fish.
Nov 8 '08 #9
ADezii
8,834 Expert 8TB
Though it is certainly not the case, but I'd like to point out that is not true for main form being in datasheet view - subform will not be loadad until subdatasheet expanded.

@OP
A simple recursive procedure you could find here will help you to find a form opened in subform control.

@ADezii
Declaring form variable with events is certainly the best way to handle subform's events in main form module

Regards,
Fish.
Hello FishVal. It appears as though you are very proficient in the OOP approach. If you have a few minutes, can you demo exactly how you would 'Hook' a Sub-Form's Current() Event and capture it within the context of a Main Form. I realize that I have the correct concept, but I am a little rusty with OOP, and I'm not sure about the implementation of this concept. I thank you for your time and consideration in this matter.
Nov 8 '08 #10
FishVal
2,653 Expert 2GB
Hello FishVal. It appears as though you are very proficient in the OOP approach. If you have a few minutes, can you demo exactly how you would 'Hook' a Sub-Form's Current() Event and capture it within the context of a Main Form. I realize that I have the correct concept, but I am a little rusty with OOP, and I'm not sure about the implementation of this concept. I thank you for your time and consideration in this matter.
Hello, ADezii.

Below is a code for subform Current event hooking.
It doesn't differ much from that you've already posted. ;)

Expand|Select|Wrap|Line Numbers
  1. Option Compare Database
  2. 'declare global object variable with events
  3. Private WithEvents frmSubform As Access.Form
  4.  
  5. Private Sub Form_Load()
  6.     'set reference to subform control form object
  7.     Set frmSubform = Me.sbf.Form
  8.     'set "OnCurrent" property so that a sub with special name -
  9.     '<object name>_<event name> will be called to handle event
  10.     frmSubform.OnCurrent = "[Event Procedure]"
  11. End Sub
  12.  
  13. 'event handling code - sets value of main form unbound control
  14. 'to a value obtained from subform control
  15. Private Sub frmSubform_Current()
  16.     Me.txbSubformEvent = Me.sbf.Form!txt
  17. End Sub
  18.  
  • Subform control form "HasModule" property has to be set to True
  • As soon as subform "Current" event occurs before mainform "Load" event it will be not handled when form has been opened, so the first "Current" event should be handled in mainform "Load" event handler.

Regards,
Fish
Nov 8 '08 #11
missinglinq
3,532 Expert 2GB
that is not true for main form being in datasheet view - subform will not be loadad until subdatasheet expanded.
Thanks, Fish! Never knew that! Actually, never contemplated doing that or saw anyone else do it, but as always, it's better to know than not to know!

;0)>
Nov 8 '08 #12
ADezii
8,834 Expert 8TB
Hello, ADezii.

Below is a code for subform Current event hooking.
It doesn't differ much from that you've already posted. ;)

Expand|Select|Wrap|Line Numbers
  1. Option Compare Database
  2. 'declare global object variable with events
  3. Private WithEvents frmSubform As Access.Form
  4.  
  5. Private Sub Form_Load()
  6.     'set reference to subform control form object
  7.     Set frmSubform = Me.sbf.Form
  8.     'set "OnCurrent" property so that a sub with special name -
  9.     '<object name>_<event name> will be called to handle event
  10.     frmSubform.OnCurrent = "[Event Procedure]"
  11. End Sub
  12.  
  13. 'event handling code - sets value of main form unbound control
  14. 'to a value obtained from subform control
  15. Private Sub frmSubform_Current()
  16.     Me.txbSubformEvent = Me.sbf.Form!txt
  17. End Sub
  18.  
  • Subform control form "HasModule" property has to be set to True
  • As soon as subform "Current" event occurs before mainform "Load" event it will be not handled when form has been opened, so the first "Current" event should be handled in mainform "Load" event handler.

Regards,
Fish
Thanks for taking the time and providing us with an explanation.
Nov 8 '08 #13
ramkam
1
Hi there,
Thanks for the explanation

However, this doesnt seem to work when the subform objectsource points to a table (allocated on the go by the main form)

ex: same as above, but the subformcontrol.sourceobject = "Table.foobar"

Would you know if there a trick or another way to detect oncurrent event, and even better, detect which field of the subform has focus ?

The idea is to display contextual information from many other tables, the model is fairly complex ... i'd need to show things when usefull.
May 27 '10 #14

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

Similar topics

6
by: dreamer | last post by:
I need to be able to detect different screen resolutions and then resize my applications forms, objects, fonts etc, to suit. Any ideas how to go about it? I use VB 5. Many thanks in advance.
5
by: Lars Moastuen | last post by:
Hi! I'm currently playing around with a project where I need to know if an object (any object) has been altered since last check. I need this to know when an object needs to be saved... My idea...
9
by: Bijoy Naick | last post by:
I've implemented forms authentication and authorization on my application. In my Web.Config, my authorization section looks like this.. <authorization> <allow roles="admin" /> <deny users="*"...
4
by: Joe | last post by:
Hi, I have a asp.net page that checks if any one of the two cookies exists. If none of the cookies exist then redirect the user to login page. Cookie “try” doesn’t exists. I can see that...
6
by: Nathan | last post by:
How can I detect when one of the arrow keys is pressed? Thanks, Nathan
2
by: David Batt | last post by:
Hi, I need to determine when data in a datagrid bound to a dataset has changed and thus make updates accordingly. I would of thought the code below would detect when a change has been made to...
6
by: jcrouse | last post by:
I have the following mouse events assigned to a label control. Is the a way I can tell which mouse button the users has clicked with? Private Sub lblP1JoyUp_Click(ByVal sender As System.Object,...
7
by: Wayne Wengert | last post by:
I am using VB with a Windows NET application. I have a datagrid in which the user can add rows using the "*" row. I want to detect whenever the user has added a row. I found the following code at...
2
by: James | last post by:
Hi. I'm probably attempting the impossible but what the hey. I'm modifying a multi-paneled form which has 8 different listviews, To allow sorting by columns I've had to add a diffrerent handler...
1
by: batista | last post by:
Hello to all, I'm using the HScrollBar Control in one of my apps. Now the problem is how to detect that when did the scrollbar reached its right end or left end.? Please Any...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
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,...
0
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...

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.