Solved Ugly new Access bug

Pat Hartman

Super Moderator
Staff member
Local time
Today, 04:16
Joined
Feb 19, 2002
Messages
47,457
New bug forces you to use task manager to close Access when you have a form bug.

I opened a form directly because I was testing and hadn't yet added it to the login form but that form wasn't open and hidden as it normally would be. When I closed the form I was testing, it tried to return control to the logon form which wasn't opened and so Access raises an error as expected.
1751818024058.png

Older versions of Access closed the form when you press End. Now access simply returns to the open form. So I tried again to close it. This time I chose debug which opens the code window to the failing instruction. I stopped the code from running and tried again to close the form. No joy. the form stays open. So I tried the "x" to close Access. It shows the same error message as above and returns me to the form that will not close. So my options are the three fingered salute or task manager. Both are really poor ways to close Access.
 
Which version of Access, Pat? Is it an Office 365 version? Also, is this running as a .ACCDB, .ACCDE, .ACCDR, or something else? Finally, when you say the miscreant form would have returned to the login form, it clearly would do so by name - because otherwise the error message would not have known the name. Which leads to the suggestion that you could protect yourself for testing simply by including a test as to whether the login form is open before trying to engage with it. (I know I don't have to tell you how IsOpen works.)

Refusal to close is normally a symptom of the process being stuck in an I/O rundown OR of having an unload event's CANCEL flag being set (or some internal event analogous to the CANCEL flag method).

To distinguish between those two, if it happens again, after you use Task Manager, stay there. Count to 10 seconds and then alphabetize the process list by clicking in the process name column of the processes list. (Makes it easier to do the next step.) Now see if you still have a copy of MSACCESS.EXE in the process list.

It is a symptom of an I/O rundown that you would still have a dangling copy of Access running "disembodied" i.e. a task that has lost touch with its control channels. Tasks in that rundown state can only be cleared by reboot. The Windows Task Manager cannot address the failed rundown. Even if you got the process ID number from WTM and opened the CMD prompt in admin mode, you would be unable to kill the process. If the task really DOES go away, then it is more similar to a CANCEL of an event than an I/O rundown wait.

Granted, EITHER way is a bug - but knowing which kind of bug is something that the Access team would need to know.
 
> Older versions of Access closed the form when you press End.
Not necessarily. That may depend on which event the error occurred in (the cancellable Form_Open perhaps?), if there is an error handler in place (your code apparently did not have one), and possibly other factors like if the form was opened modally.
Anyway, it can be resolved by hitting Debug, and reviewing the code and either opening the login form manually, or setting the instruction pointer and possibly some variables like the Cancel argument to appropriate values, and then continuing to run.
 
Which leads to the suggestion that you could protect yourself for testing simply by including a test as to whether the login form is open before trying to engage with it. (I know I don't have to tell you how IsOpen works.)
I don't care that it errors during testing. What I discovered is that THERE IS NOW NO WAY TO CLOSE THE FORM PERIOD!!!!! I don't need a solution. I am reporting an ISSUE. But thank you.

This is the entirety of the code in the form's class module.
Code:
Option Compare Database
Option Explicit



Private Sub cmdGenerate_Click()

    If Me.txtStartDT & "" = "" Then
        Me.txtStartDT.SetFocus
        MsgBox "Please enter the start date.", vbOKOnly
        Exit Sub
    End If
    If Me.txtNumWeeks & "" = "" Then
        Me.txtNumWeeks.SetFocus
        MsgBox "Please enter the Number of weeks to generate.", vbOKOnly
        Exit Sub
    End If
    Call AddDates(Me.txtStartDT, Me.txtNumWeeks)
    MsgBox "Generate complete", vbOKOnly
End Sub

Private Sub Form_Unload(Cancel As Integer)
        If IsNull(Me.OpenArgs) Then
            DoCmd.OpenForm "frmLogin", , , , , acWindowNormal
        Else
            DoCmd.OpenForm Me.OpenArgs, , , , , acWindowNormal
            'SS_OpenForm Me.OpenArgs
        End If
End Sub

Private Sub txtStartDT_AfterUpdate()
    Me.txtNumWeeks = 52
End Sub

There is nothing in the code that is preventing the close.

Here is task manager

1751825183245.png
 
Tabbed docs ftw.
💅

Edit: tabs not relevant
 
Last edited:
Anyway, it can be resolved by hitting Debug, and reviewing the code and either opening the login form manually, or setting the instruction pointer and possibly some variables like the Cancel argument to appropriate values, and then continuing to run.
Not any more. The form just stays open. Can't close it. Also tried right clicking the form header and choosing close all. The form will not close. The error stops it.

You'd think the children would test when they make a change like this.
 
Last edited:
Bleeding edge?
The screenshot in post #4 doesn’t show the update channel, version and build info. Please provide another screenshot of the info to the right of the About Access button

Sorry but I can’t quite follow your explanation in post #1. To save time, please can you provide a simple repro database that demonstrates the issue.
 
Simple test:
Code:
Private Sub Form_Unload(Cancel As Integer)
     Dim X as Long
     X = 1 / 0
End Sub
The form can only be closed if you click on Debug and manually ensure that 1/0 is not run through (e.g. move “yellow arrow” to End Sub).

The question is: What do you expect when you click on End instead of Debug?
End cancels the code execution. So the form remains open. However, this also prevents you from entering the design view because Unload also starts when you switch from the form view.

/edit:
Note: enable desing view in the VBA editor works.

Tested with Access version 2506 (18925.20138), 64 bit
 
Last edited:
OK - forget the request for a repro database.
I now understand what you meant in post #1 but its NOT due to a recent change in form behaviour.

I added the Form_Unload code in a test db with no frmLogin

Agree that you can't close the form except by using Task Manager in Access 365 ((tested in Beta Channel version 2508 build 19029.20000)
However it behaves in EXACTLY the same way in Access 2010 and I suspect would do so in older versions than that.
If very old versions behaved differently on clicking End then I would suggest that behaviour was incorrect.

Clearly neither clause of your code is valid in this scenario - the unload code is therefore flawed.

As @Josef P. points out, both End & Debug do precisely what they should.
I don't see how you can blame Access for the situation you got yourself into by making a mistake

Adding the line On Error Resume Next would allow your form to close without any issues (in both A2010 & A365)
 
Last edited:
I love the tone of this thread, supportive, helpful, non-critical - makes me wallow in a comfortable glow, knowing I am a member of this illustrious forum----
 
Forgot to say earlier:
If you move the same faulty code to the Form_Close event, the same error occurs but the form closes successfully on clicking End.
Hopefully its obvious why.
 
Colin and Pat, forgive me for stepping in, but I am thinking about other folks who read this thread and DON'T find it obvious.

The situation arises because when Pat manually launches the form for testing, it has no OpenArgs argument. When the form reaches the point to do an UNLOAD, the appropriate Event Code provides a name for the calling form. For some reason, a form wasn't available matching the spelling of the form requested to be opened. The code-provided default name ("frmLogin") appears in the error message. This failure to find the right form is the actual error, and all else is the result of this error.

It is significant to note specifically where that error originated. The FORM_UNLOAD event code has no declared error handler. (In fact, I'm going to infer that Pat didn't have error handling in that form.) That means that failing to open a form error-traps in the UNLOAD event code.

Because there is no local handler in the UNLOAD Event Code, the error subsystem removes the FORM_UNLOAD event context from the call frame and re-signals the same error to the next higher thing on the call stack, whatever it is. Eventually this cycle of "remove frame/re-signal" reaches Access itself, which has a "Last Chance" handler that generated the error message in the format shown in post #1.

Note that "Continue" is not an option here because the error handling process destroyed all stack layers until it reached the Access GUI. The nature of the FORM_UNLOAD code is that it runs BEFORE the actual unload operation performed by Access. We know this because we have the option to CANCEL that UNLOAD before Access gets to it.

In this error situation, because the call frames have been destroyed, you have no code context from which Access would close the form and no code context to allow a CONTINUE option. That is, after the error, you can't trigger an unload for the form because the form's class module context was destroyed by the time the Last Chance handler activated.

In my original post (#2), I wasn't sure why the form couldn't close, but with the extra information, I now know it was one of the two reasons I stated earlier. It had to do with the UNLOAD event code that was interrupted by the error before it could finish.
 
@Pat Hartman
Just aircode, but maybe the code should be

If ismissing (me.openargs) , rather than if isnull() etc. see if that fixes it.
 
Last edited:
@Pat Hartman
Just aircode, but maybe the code should be

If ismissing (me.openargs) , rather than if isnull() etc. see if that fixes it.
A quick test would have shown that it doesn't fix it.
As the unload event cannot complete, the form doesn't close.

The point is that its neither new, nor is it a bug.
Its just code error and easily fixed by adding error handling or moving the code to the close event or of course including the referenced form!
 
Sorry, It was inviting me to join the insider channel which I was on at some time in the past but it got too annoying.
1751898533185.png

The question is: What do you expect when you click on End instead of Debug?
I expect it to close the form as it used to. There is a continue button which is greyed out.

You all keep offering suggestions on where to move the code and how to fix the error. I KNOW how to fix the error. The problem is why Access now doesn't allow me to close the form in spite of the error.

Doc may have hit on why this is happening.

I attached a database with the form and a table. Open the form. No need to run any code. Just close the form or try to;)

Please pass the sample along to anyone at MS who might be interested. I changed the code in the sample so it is referring to the correct form. I had copied the form from a different database and it was referring to the wrong form. So the form now closes correctly in my app. But I didn't include the Switchboard form in the attached sample because I needed the error to occur.

Thanks.
 

Attachments

I had a look at your example app but it demonstrated exactly what I had already tested in both 365 & 2010.
My opinion remains unchanged - it is not a bug for the reasons I stated in post #10

In older versions of Access, certain code was allowed to run that no longer does so.
Over the years, Access has tightened up on poorly defined code. Perhaps this is one such case as you say it worked in the past

It may not be new but it is a bug since End does not close the form.

The code was flawed due to the missing form. It would obviously have worked if it had been present.
As the code was in the Unload event with no error handler, it could not complete . . . therefore the form could not then close.

To reiterate, clicking the End button in the error dialog stops code execution immediately.
As a result, clicking End does not then allow the form to close - nor should it ever have done so in a very early version of Access (prior to 2010).

If you still disagree with the feedback from others in this thread, then you have a channel whereby you can report the issue you describe to the Access team yourself.
 
The problem is why Access now doesn't allow me to close the form in spite of the error.

Doc may have hit on why this is happening.

I understand the mechanism that gets you into what appears to be a near intractable form deadlock. However, you ask the question that really makes the difference. If this used to work such that using [END] allowed you to close things, and now it does not, then that IS a significant change. So what DID change?

As far as I can tell when looking at the FORM_UNLOAD code you posted, that should work identically the same in all versions of Access I've ever seen (starting with Access 2.0, my first version). In all of those versions, you would take the fatal break-point BEFORE the behind-the-scenes UNLOAD operation occurred. If the form is not unloaded but its form-class context is no longer valid, you can't close it unless you take the WTM method to whack the whole process.

The change has to be something inside of Access itself, having to do with the form's UNLOAD-CLOSE sequence. One other way would allow that form closure after the error - if you had your own error handling code in that routine and allowed use of the CONTINUE option on the MSGBOX you used to report the error. The reason that would work is because the first error handler stops that cascade deletion/collapse of stack frames. In that case, there IS a chance of using [CONTINUE], because the form-class module's context is still intact.

However, you said this is the same code that has worked for a really long time. To be perfectly honest, I'm not sure why prior versions of Access WERE able to close that form, because if the error occurs, it HAS to block the UNLOAD and that would mean the recordset and its associated file were still open. We know it is still open because if you DO cancel an UNLOAD, you CAN still use bound forms.

It is a Windows rule that you can't close a process that still has an open file. That restriction is due to the need to assure a buffer flush for each file to prevent partially updated files. (See also "Access corrupted databases" and "Database in inconsistent state.") Using a WTM "END TASK" operation triggers an internal PROCESS RUNDOWN operation that includes a loop through the list of file handles to close all open files for that process. That forced close would assure a buffer flush for any pending buffer writeback operations, after which there will be no reason to stop the process from exiting.

I see I've started to ramble so I'll just stop and say that without Access being OpenSource, this is as far as I can take it, even though I know what events need to be examined.
 

Users who are viewing this thread

Back
Top Bottom