Access will sometimes fail to exit cleanly and leave an MSACCESS.EXE process running with no visible user interface (the application is no longer shown in the Applications tab of Task Manager).
What is the minimal code necessary to reproduce this error?
UPDATE: I've posted an answer that reliably reproduces the problem. I would be very interested in other scenarios that may also reproduce the issue. I will upvote any future answer that successfully reproduces the problem. I would like to make this question a repository of verified scenarios that cause the issue so that those who run into this problem in the future have a better explanation then the usual vague suggestions to "close all open objects, etc."
I've searched high and low for a reproducible example of this phenomenon and finally stumbled upon this answer posted by Chris from Brisbane, Australia: Something a little more subtle... I'm reposting his answer here with very slight modification:
Create a new form and add a single command button named cmdShutdown with the following code:
Dim PersistentRS As DAO.Recordset
Private Sub Form_Open(Cancel As Integer)
Set PersistentRS = CurrentDb.OpenRecordset("SELECT * FROM msysobjects")
End Sub
Private Sub cmdShutdown_Click()
Application.Quit ' < This is the culprit.
End Sub
Private Sub Form_Close()
On Error GoTo ErrorHandler
ExitProcedure:
PersistentRS.Close ' < This is all it requires.
Exit Sub
ErrorHandler:
Resume ExitProcedure
End Sub
This problem is not about the PersistentRecordset being left open, quite the contrary.
The fact is that the garbage collector has done its job and has already closed PersistentRecordset.
The garbage collector was called by Application.Quit before the Form_Close event was called.
Any Application.Quit command will call the garbage collector and it doesn’t matter if that command is on another Form.
Once the Application.Quit command has called the garbage collector all variables have been reset.
The Application.Quit command then starts a shutdown sequence.
If any Form is open then an attempt is made to close it.
If the Form has a Form_Close or Form_Unload event those events will fire.
When invoked by the Application.Quit command those events are running with PersistentRecordset which has already been closed.
So, if you are going to look for recordsets which have not been closed then save yourself some time. Look for recordsets where an attempt is made to close them and remove that attempt.
We paid good money for the garbage collector so we should use it; it works.
Trying to do the garbage collection ourselves can lead to failure.
But any such circular error, not just recordset errors, will cause Access to be too busy to close.
Chris.
I confirmed this reproduces the error in Access 2002 running in Windows 7 64-bit.
Related
I have struggled and struggled with this issue. I've read a many similar questions concerning this topic, but I'm new at this and I'm reading "Greek to me". Perhaps someone will be willing to help me on an elementary level with this. I created an SSIS package with several steps. The first step is a script task that uses a VB8 script to pull the data from the SFTP server. The script reads like this:
Imports System
Imports System.Data
Imports System.Math
Imports Microsoft.SqlServer.Dts.Runtime
<System.AddIn.AddIn("ScriptMain", Version:="1.0", Publisher:="", Description:="")> _
<System.CLSCompliantAttribute(False)> _
Partial Public Class ScriptMain
Inherits Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
Enum ScriptResults
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
End Enum
Public Sub HealthSmart()
Dim Path As String, Path2 As String ', fileName As String, fo As Object, x As Object, y As Object, z As Object, rs As Object
Path = "\\RENYSQL1\share\Health_Smart\Received_Files\Test"
Path2 = "\\RENYMstr1\shared\CLIENT FOLDERS\HEALTHSMART\Original_PDF_Files\Test"
Shell("""C:\Program Files (x86)\Ipswitch\WS_FTP 12\wsftppro.exe"" -s ""Health_Smart:/Test/AMC_Test/*.pdf"" -d ""local:" & Path & "\"" -quiet", vbMaximizedFocus)
Shell("""C:\Program Files (x86)\Ipswitch\WS_FTP 12\wsftppro.exe"" -s ""Health_Smart:/Test/AMC_Test/*.pdf"" -d ""local:" & Path2 & "\"" -quiet", vbMaximizedFocus)
Dts.TaskResult = ScriptResults.Success
End Sub
End Class
It runs perfectly fine when the step is executed in the SSIS package. It also runs without error when I import the SSIS package into MSDB and select run package. But when I scedule it as a step in a job, it acts as if it ran perfectly. But the first step pulled not data.
I have tried setting the permissions of the SSIS package to a user that has full permissions to everything. I also tried setting the package protection level to DontSaveSensitive with no password.
On the SQL job side, I have tried using Windows authentication in the job as well as the login I mentioned earlier to run the package. Neither worked. Furthermore, I changed it to run on 32 bit - but to no avail.
I understand that the SQL job is run by the SQL agent. Does the agent have a specific login? People in my department say no.
The strange thing is that when I schedule the job to run, it runs and says it is successful. But the first step of getting the SFTP files with the above script runs, but does not pull any data. The Job Activity Monitor says it was Successful.
I have no idea what to do next. Be easy on me. I'm new at this.
While you certainly could have permissions issues if you are not receiving and error it would suggest the code is not executing. Looking at where you placed your code in your script I am thinking it is entirely possible that you did not put a call to your SUB in the Main () Sub. When creating a new script you should see something like:
Public Sub Main()
'
' Add your code here
'
Dts.TaskResult = ScriptResults.Success
End Sub
And basically where it says add your code here is where Microsoft was leading you to add your script. It is completely okay to do it in its own sub as you have, but if you do you need to call your sub within the Main() SUB like so:
Public Sub Main()
'
' Add your code here
'
HealthSmart()
Dts.TaskResult = ScriptResults.Success
End Sub
If you actually do have the Main SUB and calling your code. There could perhaps be an error within wsftppro.exe. Have you run the code outside of the script?
If permissions are causing the issue within the exe and not error you could try running via your dev environment as a user that has access to the locations and if it succeeds for you then you could need permissions for your SQL Agent and/or Service Account.
I'm new to access and am working with a database someone else wrote.
I'm trying to understand the code by tracing it, but surprisingly I'm having trouble here.
There's a form, let's call it form 1, such that if you click it's "go" button it will execute a procedure. The first command in that procedure is:
DoCmd.OpenForm "Frm2", acNormal
When this line executes it goes to some module, "module X", where two functions are executed. These
functions are in a stand-alone module and I don't see how they are related to Frm2.
After these two functions are executed, control goes to Frm2, specifically this line in Frm2's code:
Form.Load
So, my question, as I alluded to earlier, is why are the two functions in module X called before
control is handed to Frm2?
When the first of the two mystery functions are being executed, I do a stack trace and I see this:
function1()
<non-basic code>
Frm1_Btn_click()
This doesn't tell me what's calling function1, and its throwing me off.
If I comment out function1, I get a run-time error 3085 "Undefined Function
function 1 in Expression". This begs the question, what "expression" is the error referring to?
I believe this is the missing link, but I can't find it.
Thanks for your help
I solved it. The issue was a dependency that was caused by the form having a record source linked to a query. The was due to this.
I'm glad I was able to solve this!
After recently adding some new VBA code that referred to a control, my code wouldn't run. On investigation, I found the problem was a typo in the code referring to the control: I'd typed it as Me.CheckYearEmd (with an m) rather than Me.CheckYearEnd.
This is now resolved and the code's working fine, but the weird thing is the error didn't trigger my error handling; it just didn't run. My error handling works on a very simple basis:
On Error GoTo ErrHandler
... 'Rest of sub
Exit Sub
ErrHandler:
DoCmd.SetWarnings True
MsgBox "The database has generated an error. Please contact the database administrator, quoting the following error message: '" & Err.Description & "'", vbCritical, "Database Error"
Is there something specific about referring to a control that doesn't exist (as I effectivley did above) that causes it to bypass error handling, and is there a way of catching these errors?
I can't recreate the situation you described. When I misspell a control name in the form's code, running Debug->Compile from the VB Editor's main menu triggers a compile error: "Method or data member not found".
However, if I don't run Debug->Compile and just try to run the form's procedure with the misspelled name, I still get that compile error.
Although I can't duplicate your situation, I'll offer a guess why the procedure's error handler doesn't catch it. The directive, On Error GoTo ErrHandler, traps run-time errors. But the misspelled control name triggers a compile error.
I have an ActiveX control for opening and manipulating a proprietary image type. I am able to embed the control in an Access form, and by using the Object Browser am able to ascertain all the class members. The only problem I am having is handling some of the events raised by the control.
For example, from the Object Browser I can see the following event definition:
Event RightClicked()
And when I add the following code to the form:
Private Sub CtrlInstanceName_RightClicked()
'Anything here
End Sub
Everything works as expected. However, if the event declaration has parameters passed to it, such as:
Event MeasurementUpdated(id as Long)
Adding:
Private Sub CtrlInstanceName_MeasurementUpdated(id as Long)
'Anything here
End Sub
Produces the following error:
The expression ... you entered as the event property setting produced
the following error: Procedure declaration does not match description
of event or procedure having the same name.
Even more strange after adding this second handler, all event handlers on the form produce this error, including events raised by the form and other controls on the form.
I have tested the ActiveX control in a C# .NET application and am able to handle the events there (although they don't quite work as expected). In Visual Studio, the function prototypes end up being a little odd with auto-defined event handler class types.
Any ideas on how I need to change the event procedure declaration to avoid this error?
Well like most Friday questions, I later found the answer to this one was rather quite simple.
First, due to my unfamiliarity with the VBA code editor, I did not know that it was possible to create stubs for embedded controls by using the Object combobox above the code. After selecting my control name I selected the MeasurementUpdate event from the procedure combobox.
The correct declaration is simply:
Private Sub CtrlInstanceName_MeasurementUpdated(ByVal id as Long)
'Anything here
End Sub
The key difference being the ByVal modifier.
I have been working on something that checks an MySQL Database to check something - however the program stops responding because it is constantly checking the database. Is it possible to have it wait a few seconds to recheck the database? I have tried sleep() but it is giving a strange error:
A call to PInvoke function
'Game!WindowsApplication1.Form1::Sleep' has unbalanced the
stack. This is likely because the managed PInvoke signature
does not match the
unmanaged target signature. Check that the calling convention
and parameters of the
PInvoke signature match the target unmanaged signature.
I have been looking into this for quite a while and i am in a predicament. I do need the MySQL databases to be checked very often. I tried making a web browser refresh before checking it again - but it started to lag the application.
Code:
function updateit()
' SQL Code goes here, it succeeds.
updateit() ' Update it again.
return true
end
updateit()
Your code example shows a recursive function with no base case. The result of that is always a stack overflow (an uncatchable exception in .Net).
Don't call your updateit() function from within the function itself. Instead, just write a loop to call it over and over.
Try doing your checks from a separate thread. Try dragging a BackgroundWorker onto your form and putting your check in that to make your program more responsive. I've never seen that error before though. Is it System.Threading.Thread.Sleep() or something specific to VB?
Looking at your code it looks like you've got infinite recursion. That will cause a stackoverflow... try
while(true)
'SQL code
end