Cancel = True (1 Viewer)

ChrisO

Registered User.
Local time
Today, 16:52
Joined
Apr 30, 2003
Messages
3,202
Cancel = True

There appears to be a misunderstanding on the www about what
Cancel = True
means specifically in the Open event of a Form or Report.

One example:-
http://allenbrowne.com/casu-20.html

That example implies that, if we wish to close the Form, we should use Cancel = True. That example then goes on to say that the Cancel will raise a VBA error in the Form which attempted to open the Form which was cancelled.

Specifically, the error raised is error “2501; The OpenForm action was canceled.”

That then leads people to write code like this… (Simplified)

In the Form which is cancelled:-
Code:
Private Sub Form_Open(Cancel As Integer)

    Cancel = True
    
End Sub

And in the Form which opened it:-
Code:
Private Sub cmdOpenForm_Click()

    On Error GoTo ErrorHandler
    
    DoCmd.OpenForm "frmMyForm"

ExitProcedure:
    Exit Sub

ErrorHandler:
    Select Case Err.Number
        Case 2501       [color=green]' Cancelled
            ' Do nothing.[/color]
        
        Case Else
            MsgBox "Error  " & Err.Number & "  " & Err.Description
    
    End Select
    
    Resume ExitProcedure

End Sub

Now while the above code works as expected it does not lead to an understanding.

In the Form which closes itself
Cancel = True
does two things. It both closes the Form and it raises the error in the Form which attempted to open it. But the Form which attempted to open it ignores the error in the Select Case structure in its error handler.

So the question then becomes; why raise an error if that error will be ignored?

The alternative to the above code then becomes…

In the Form which is cancelled:-
Code:
Private Sub Form_Open(Cancel As Integer)

    DoCmd.Close acForm, Me.Name
    
End Sub

And in the Form which opened it:-
Code:
Private Sub cmdOpenForm_Click()

    On Error GoTo ErrorHandler
    
    DoCmd.OpenForm "frmMyForm"

ExitProcedure:
    Exit Sub

ErrorHandler:
    MsgBox "Error  " & Err.Number & "  " & Err.Description
    
    Resume ExitProcedure

End Sub

I understand that people will jump to the defence of what and who they read on the www and what they have done themselves in the past.

But did they know that
Cancel = True
is specifically designed to raise an error which gets passed back but also gets ignored?

Can anybody post code which actually uses the error which
Cancel = True
produces?

Not just words please but actual copy/paste code from a past application.

What I’m trying to find out is if
Cancel = True
is any better, because it raises an error, than
DoCmd.Close acForm, Me.Name
which does not raise the error.

Chris.
 

MarkK

bit cruncher
Local time
Yesterday, 23:52
Joined
Mar 17, 2004
Messages
8,186
A few thoughts . . .

Cancel might be inherited. It makes sense that certain events should be able to return a value to the (non-VBA) code that raised the event, and give that code a chance to alter its execution. Perhaps that calling code is implemented in a base class from which other objects, including forms, derive. I know I've implemented features before, not because they are particularly necessary, but because I can, and this feature may follow that pattern.

Cancel = True doesn't raise an error if you open the form directly from the "database window." It seems possible to me that in it's early design, Access was not conceived to be as 'automatable' as it is now. The DoCmd object, for instance, seems like a sort of patchwork add-in to provide VBA with the capacity to open objects from code. DoCmd must be that, a VBA mechanism to automate previously created objects, like a DAO.QueryDef must have existed before DoCmd. I find DoCmd a sort of gluey lump that lacks elegance. A Form should have a Show method that takes the parameters you now have to use with DoCmd, and DoCmd.OpenForm doesn't even return an object reference?!?!?

If you open a non-default instance of a form and Cancel = True, you get error 2001 with the same description, you cancelled the previous operation. Not sure what that means, but it seems curious.
 

ChrisO

Registered User.
Local time
Today, 16:52
Joined
Apr 30, 2003
Messages
3,202
Mark, I think you have nailed the point…it’s curious.

I don’t mind that Cancel = True raises a VBA error if people are going to use that error. What I do mind is that people will use Cancel = True and then write more code to ignore the error which is raised.

It become curious that people close the Form by using Cancel = True rather than simply closing the Form using DoCmd.Close acForm, Me.Name.

Is it that people simply go to sites and follow the recommendations given there and then write more code which wasn’t necessary in the first place?

Chris.
 

Galaxiom

Super Moderator
Staff member
Local time
Today, 16:52
Joined
Jan 20, 2009
Messages
12,853
It seems possible to me that in it's early design, Access was not conceived to be as 'automatable' as it is now. The DoCmd object, for instance, seems like a sort of patchwork add-in to provide VBA with the capacity to open objects from code. DoCmd must be that, a VBA mechanism to automate previously created objects, like a DAO.QueryDef must have existed before DoCmd.

DoCmd was a step up from DoMenuItem which was about as far as a program design could possibly get from being object oriented.
 

gemma-the-husky

Super Moderator
Staff member
Local time
Today, 07:52
Joined
Sep 12, 2006
Messages
15,660
slight observation

I was surprised that cancel=true actually did the job, at first

I had assumed it ought to be cancel = vbcancel, and always used that (maybe I saw that usage somewhere). I think in fact that any non-zero value for cancel cancels the form, so it is just random that "true" happens to be a value that closes the form.

eg I just tried cancel=25, and that cancelled the open event.
 

Galaxiom

Super Moderator
Staff member
Local time
Today, 16:52
Joined
Jan 20, 2009
Messages
12,853
slight observation

I was surprised that cancel=true actually did the job, at first

I had assumed it ought to be cancel = vbcancel, and always used that (maybe I saw that usage somewhere). I think in fact that any non-zero value for cancel cancels the form, so it is just random that "true" happens to be a value that closes the form.

eg I just tried cancel=25, and that cancelled the open event.

vbCancel is the return value of a Cancel button click in a dialog box.

Cancel is a Boolean ByRef argument to the procedure and hence, as usual, any value other than zero will be interpreted as True by automatic type casting.
 

Users who are viewing this thread

Top Bottom