Way to prevent subform from being opened directly?

mdlueck

Sr. Application Developer
Local time
Yesterday, 21:00
Joined
Jun 23, 2011
Messages
2,633
I am making use of a global variable in order to prevent individual forms from being non-programitaically opened.

Prior to opening any form I set:

Code:
  'Open the projects window and exit
  flgInitArchitecture = True
  DoCmd.OpenForm strDocName
  DoCmd.Close acForm, Me.Name
And in the Open event of the Forms, I code:

Code:
  'Test if this form is being opened programatically vs manually
  If architecturecheck_CheckHowStarted() = 0 Then
    'Caught someone being sneeky... we outtahere!
    Cancel = True
  End If
In the Form's Open event.

I have need of creating a more complicated subform which I would like to prevent from being opened non-programitaically.

Any suggestions how I could implement such within a subform context? TIA!
 
Michael, can you describe how the subform is opened non-programmatically?

Chris.
 
Via the Navigation Pane. This is what I would like to prevent.
 
For what it's worth, just to assist with context
Working with subforms

When you open a form that contains a subform, the subform and its records are loaded before the main form. Thus, the events for the subform and its controls (such as Open, Current, Enter, and GotFocus) occur before the events for the form. However, the Activate event does not occur for subforms. Therefore, opening a main form triggers an Activate event only for the main form.

Similarly, when you close a form that contains a subform, the subform and its records are unloaded after the form. The Deactivate event does not occur for subforms. Therefore, closing a main form triggers a Deactivate event only for the main form. The events for the controls, form, and subform occur in the following order:

Events for the subform's controls (such as Exit and LostFocus)
Events for the form's controls (including the subform control)
Events for the form (such as Deactivate and Close)
Events for the subform

Note Because the events for a subform occur after the main form is closed, certain events, such as canceling the closing of the main form from an event in the subform, will not occur. You may need to move these types of validation tests to an event on the main form.
 
Have you tried to hide it? ( right click -> properties) Google for how to unhide hidden objects before you attempt it :-)
 
Have you tried to hide it?

Yes I am familiar with hiding objects, and most power users here as well. ;) I think that weak compared to what I have in place for real forms.

As example, one person prefers to edit records directly through table views rather than using forms. They get records scrambled such that queries do not work properly. In the new application, I am going to specifically DELETE all linked table objects which are to the SQL Server! :p Take that! MUST use forms!
 
I think that hiding objects is fine. If someone takes to circumventing that, and screws the data up, then that is negligent to say the least. Not on your part but on the part of the delinquent.

Putting all that effort to safeguard you app against busybodies seems to me not to be a good use of your skills.
 
When you open a form that contains a subform, the subform and its records are loaded before the main form.

So I suppose on the subform, instead of calling my architecturecheck_CheckHowStarted() function which turns off the flag, I could manually check the flgInitArchitecture variable.

Then from the real form perform the regular function call and handle the canceling of Form Open there.

Since the usual behavior is for the form to be opened programatically, I need not be concerned about what happens when I cancel the open event of a subform as that will not happen normally. "That should never happen."

Sounds like worth testing shortly.
 
Putting all that effort to safeguard you app against busybodies seems to me not to be a good use of your skills.

Data integrity.

This application, for example, captures userid / timestamp of each write to the database via each Stored Procedure. Direct access to the SQL tables would be a bypass around that standard.

Also, I leave all DB class objects floating around in global variable space. So the ability to open subforms and change data might actually work in some cases where DB objects just happened to have left over data in them which is enough to "prime the pump" of the subform. In the case of this subform, only four DB objects need to be populated, and those DB objects are populated with active data 99% of the time. Thus, I would like to be able to remain consistent and not allow subforms to be opened interactively.
 
I am not arguing about what it takes to screw up the data.

What I don't understand is that you are spending effort on measures to keep ppl at bay, who apparently consider it a challenge to circumvent safeguards. It's like the virus war, with measures and counter measures. What is the point, in a working environment, to safeguard apps against other employees? You are putting a lot of effort into a fight that should not exist, and can thus easily escalate into a no-purpose "I'm smarter than you"-war.
 
"I'm smarter than you"-war.

I suppose that is what it is, after all! :cool:

It I was coding this app for my own use, I would not need userid security. I might still keep track of when records were last written, out of an interest factor. There would be no multi-user update situation to handle. etc...

I am a consultant developing an application for a client, who potentially needs to get years worth of use out of the finished application. My name goes on this application... right in the Help \ About button. I best not spell quality with a K! :D
 
Technically speaking, a subform can not be opened.

A Form used as a subform is never opened but rather an instance of the Form is opened.
A Form can only become a subform if it is the Source Object of a Subform Control on a Parent Form.
If the Parent Form is opened then the Form, as the Source Object of the Subform Control, is instantiated.
It is that instance of the Form, not the Form itself, which is opened.

If a Form, which is intended to be used only as a subform, is opened directly then it can not have a Parent Form.
If a Form does not have a Parent Form then it is not a subform.

Therefore, we can check if the Form, or instance of the Form, has a Parent.

Behind any Form intended to be instantiated only as a subform:-
Code:
Private Sub Form_Open(ByRef intCancel As Integer)

    intCancel = NoParent(Me)

End Sub

In a standard module:-
Code:
Public Function NoParent(ByRef frm As Access.Form) As Integer

    On Error Resume Next
    
    frm.Parent.Section(acDetail).BackColor = frm.Parent.Section(acDetail).BackColor
    
    If Err.Number <> 0 Then
        NoParent = True
        DoCmd.Close acForm, frm.Name
    End If

End Function

Chris.
 
In a standard module:-
Code:
Public Function NoParent(ByRef frm As Access.Form) As Integer

Thank you very much, ChrisO! That bit seems ripe to harvest and become:

Code:
Public Function architecturecheck_CheckHowStartedSubform(ByRef frm As Access.Form) As Integer
 
I have it successfully implemented as follows:

First in shared code I have:

Code:
Public Function architecturecheck_CheckHowStartedSubform(ByRef MePointer As Access.Form) As Boolean
On Error Resume Next

  'Test if this form is being used as a subform vs manually
  MePointer.Parent.Section(acDetail).BackColor = MePointer.Parent.Section(acDetail).BackColor
    
  If Err.Number = 0 Then
    architecturecheck_CheckHowStartedSubform = True
  Else
    'Caught someone being sneeky... we outtahere!
    MsgBox "Fandango application MUST be started with 'main' form only!", vbOKOnly + vbExclamation, "Fandango Launch Error!"
    architecturecheck_CheckHowStartedSubform = False
  End If

End Function
And on the Open event of a Form which is only ever used as a subform:

Code:
Private Sub Form_Open(Cancel As Integer)
  On Error GoTo Err_Form_Open

  'Test if this form is being opened programatically vs manually
  If architecturecheck_CheckHowStartedSubform(Me) = False Then
    'Caught someone being sneeky... we outtahere!
    Cancel = True
  End If

Exit_Form_Open:
  Exit Sub

Err_Form_Open:
  Call errorhandler_MsgBox("Form: Form_subform_lastsaved, Subroutine: Form_Open()")
  Resume Exit_Form_Open

End Sub
So, code all set for that bigger project requiring me to morph another entire form into/within a new form.
 

Users who are viewing this thread

Back
Top Bottom