I have a large MS Access 2013 application, and while adding some new logic I've come come upon an obstacle that no amount Googling has allowed me to overcome.
When I run the following code I get a
runtime error 3021: No current record.
error message when executing the last statement:
Docmd.Close acForm,"Picking"
DoCmd.DeleteObject acForm, "Picking"
DoCmd.CopyObject, "Picking", acForm, "Picking On Tablet"
The two forms listed in the code both exist and are proper. The first form (Picking) is being deleted properly in the 2nd statement. (The name has been removed from the list of form objects showing in the nav pane.)
My guess is that I need to somehow refresh the objects list before I run the 3rd statement but can't figure out how to do that. As a lark, I did try DoCmd.RefreshRecord since runtime error 3021 says "no current record" but of course this didn't work.
Am I on the right track? Any other ideas? I'm completely stumped.
You don't mention where your code is located (it can't be in form 'Picking'), but I got the following to work in a Module. You can delete whatever 'RefreshDatabaseWindow' commands you want until you find the culprit...
Option Compare Database
Option Explicit
Sub Do_Something_With_Forms()
RefreshDatabaseWindow
DoCmd.Close acForm, "Picking"
RefreshDatabaseWindow
DoCmd.DeleteObject acForm, "Picking"
RefreshDatabaseWindow
DoCmd.CopyObject , "Picking", acForm, "Picking On Tablet"
RefreshDatabaseWindow
End Sub
Thanks to all for your help. The answers all provided perspective. Based on your feedback I decided to check my work elsewhere. Sure enough, code elsewhere was the source of the issue.
It's times like this when I wish Access would provide stack visibility. What I discovered by hitting F8 some 50-75 times was that I was erroneously executing code to re-establish ODBC links for all my tables, while at the same time essentially, the code in question was manipulating the picking form.
The picking form links to two of the tables and this most likely caused my issue.
After correcting my logic error now the code works fine (yes, it does run in a separate module).
Related
I've been using Application.forms.Count to measure the number of forms that are open, and most of the time, this function works correctly. However, every once in a while, the count is wrong.
When I view the amount in a MsgBox, Access thinks that there are 2 forms open when it is obvious that only 1 is open. I have this running on my Form_Unload method, as the form should only close if it is the last form still open. I have made sure that there are no other instances of Access running when this is performed and no pop-ups or modals are open.
Dim Form As Double
Form = Application.forms.Count
MsgBox Form
If Form = 1 Then
'Nothing, form closes
DoCmd.ShowToolbar "Ribbon", acToolbarYes
Else
MsgBox "You cannot close this form right now."
cancel = True
End If
End Sub
As mentioned, this code does work most of the time, but it is a major hindrance when the wrong count occurs, and I'd like to find out what is causing it.
Using (Debug.Print Forms(0).Name and Debug.Print Forms(1).Name), I was able to figure out that the form I had open had somehow duplicated itself (though only one version of the form is open on the screen). While I have no idea how this happened, a simple restart of MS Access will get rid of the duplication. I'll add this supplemental if statement to prevent this in the future:
If formCount = 1 Then
...
Else
If Forms(0).Name = Forms(1).Name Then
'The duplication error is happening again
DoCmd.Close "FormNameHere"
End If
End If
After all this time, I believe I've found the root of this error. I did not previously know that forms could be opened in the background without actually appearing, and this happens when you read or write a project-level variable. I had checked on a variable and then tried to check the number of forms up, and there was two open despite only one being visible. I think a simple DoCmd.Close "formNameHere" after checking on the variable would be the best way to go about this problem.
I just started receiving a weird error when submitting a record to my database. It's a data entry form that calls a bunch of code, and then calls
docmd.runcommand acSaveRecord
Application.quit
at the end. I changed the line docmd.save to docmd.runcommand acSaveRecord because records were not being saved sometimes. I do not have the application set to compact and repair on close. Why am I getting this message?
The full error is You cannot compact the open database through vba or a macro
Here's what I found
acSaveRecord is a member of Access.Constants and is equal to 4.
acCmdSaveRecord is a member of Access.AcCommands and is equal to 50.
Essentially, the command I was using is "DoCmd.RunCommand 4".
The value in Access.AcCommandsthat is equal to 4 is acCmdCompactDatabase
Therefore, one should use docmd.runcommand accmdSaveRecord (or use form.dirty)
This blog post briefly explains why one should use form.dirty.
Weird -- source on the weird behavior is the last post here
An MS Access form that has been working for over a year now, does a simple:
"Dim MyQuoteID as INTEGER
MyQuoteID = Me.QuoteID"
(It then proceeds to execute an SQL Statement inserting "MyQuoteID" that it just captured from the form)
...Only now it errors and says "Method or data member not found" on "Me.QuoteID".
Of course, the "QuoteID" box is right there, plainly visible, and has been for over a year.
Obviously some kind of corruption because I didn't change anything - but it doesn't solve with a compact and repair!
WTH??????
Two things to try:
Decompile via the command line (msaccess.exe "path\to\your.mdb" /decompile)
Use the undocumented SaveAsText and LoadFromText methods to "export" and "import" your form
SaveAsText acForm, "YourFormName", "YourFormName.txt"
LoadFromText acForm, "YourFormName", "YourFormName.txt"
I think you meant to write TextBox rather than INT. Assuming that this code is in the VBA module for a form, you do not need to define any of the controls in this way, nor is it good practice to do so. Just delete these two lines, and it might fix your problem.
Is there any method to avoid the annoying write conflict messages by automating and hiding the process so that it doesn't appear as if the program is defective? There doesn't seem to be any point to these messages anyway as there is only one real choice which is to drop the changes.
The only way I know to avoid that message is to requery your screen after running a process or changing data on the backend database (or sql server)
You should be able to handle these errors in a combination of two places. The first, and most important is on the Form_Error event. Your code will look something like this:
Private Sub Form_Error(DataErr As Integer, Response As Integer)
If DataErr = 7787 Then
MsgBox "Oops, this record was edited by someone else or " & _
"in another screen while you were making edits." & _
"Your edits cannot be saved."
Response = acDataErrContinue
End If
End Sub
You will also need to handle error 3021 anywhere you run a Save command in VBA, like this:
Private Sub cmdSave_Click()
On Error GoTo ErrHandler
DoCmd.RunCommand acCmdSaveRecord
Exit Sub
ErrHandler:
If Err.Number = 3021 Then
'Do Nothing
Resume Next
Else
'Handle other errors here
Resume Next
End If
End Sub
Now, I readily agree with one of the comments that it's more important that you try to resolve whatever is causing these errors rather than coding around them. In my case I am using the above solution to handle write conflicts that occur when a user opens two instances of the same form to the same record and makes edits in both instances. It would be better if I would prevent the user from opening the same record twice or prevent edits by only allowing the user to make edits in one of the open form instances but neither of these are exactly easy to implement, especially when you are using your own forms collection so I guess you could say I'm waiting for a "rainy day".
can't believe I am losing so much time on this one.
I have an order form, and when I click on a button "reports", a dialog
pop ups with a list of different reports to chose from. Double-clicking selects
and starts the correspondent report.
On one of these reports, there is an unbound text box I need the user to enter data with.
The ControlSource of this field is set to its Name property.
When the report is started, an input box appears with an OK and a Cancel button. Whenever I enter some data, all is fine.
But when I click on Cancel, the app crashes and I get an errormessage:
"Runtime Error 2501: The Action OpenReport has been canceled" (translated from German).
The Report is called through this code:
DoCmd.OpenReport vBerichtName, nAnsicht
End If
On Error Resume Next
DoCmd.Close acForm, "F_BerichtDrucken"
On Error GoTo 0
1) Why does the error handling not kick in?
2) I googled and found lots of weird solutions for this, like the official Microsoft one saying you need to install/update a printer driver (come on...). None helped.
I am doing this for a friend and I normally work on linux/php,java, etc. I apologize if the solution is somewhat obvious or something like that.
Ditto to Phillipe's answer. you didn't give us the whole procedures but you need to do something like this...
Sub MyButton_Click
On Error Goto myError
DoCmd.OpenReport vBerichtName, nAnsicht
MyExit:
Exit Sub
MyError:
If Err.number = 2501 then goto myExit
msgbox err.description
goto myExit
End Sub
This is a common error but you can catch it like any other error and ignore it if is 2501.
Seth
The error probably comes from the DoCmd.OpenReport line. This is why the error handler does not work.
I guess the value you requested is somehow mandatory in the report. Did you try to put your error management line before the docmd.openReport?
Check your default printer. I was getting the same error & all my code was working properly. Someone using the computer set the default printer to a label printer. Somehow Access was checking the printer & knew it didn't have the correct size settings to print so it stopped the displaying of the report.
I changed the default printer to another full size sheet printer and it worked fine.
I hope this helps someone because I was at a loss when it first occurred.
OK, it works now.
After your suggestions, I put the code like this:
On Error GoTo CancelError
If Not IsNull(vFilter) Then
DoCmd.OpenReport vBerichtName, nAnsicht, , vFilter
Else
DoCmd.OpenReport vBerichtName, nAnsicht
End If
CancelError:
DoCmd.Close acReport, vBerichtName
DoCmd.Close acForm, "F_BerichtDrucken"
Echo True ' this did the trick
Exit Function
As soon as I put Echo True into the error handling, it works
now smoothly, going back to the previous form and allowing
to continue to work - looks like "Echo" is kind of a refresher for the screen...?