I've recently moved a db built in Access 2010 to Access 2013. It was working fine for a while then it suddenly started crashing (i.e. not responding) whenever a certain table is updated using VBA. I can run the query on its own without any problem but can't call it in VBA. Below is an example of the code that would cause a crash. Any attempt to update this table causes it to crash:
Sub ShipOrder(OrderID As Long)
Dim strSQL As String
On Error GoTo ErrorHandler
strSQL = "UPDATE Orders SET StatusID = 20 WHERE ID = " & OrderID
CurrentDb.Execute strSQL, dbFailOnError
Exit Sub
ErrorHandler:
MsgBox Err.Description
End Sub
I've already moved all tables, forms, etc. to a new database just in case the old one was corrupted but the problem persisted.
Any suggestions on what is causing this error are greatly welcome!
Thanks.
Sound like your linked DB is the problem..
Did you try-
docmd.RunSQL ""
may be CurrentDb on CurrentDb.Execute is the problem...
good luck..
Related
strSQL = " select top 1 id from employees "
Set rs = CurrentDb.OpenRecordset(strSQL)
If Not rs.EOF Then
DoCmd.FindRecord rs(0), , True, , True
rs.Close
End If
the Error is a Write Conflict with the Save Record grayed out.
The DoCMD line is whats causing the error.
I am trying to automate when someone enters an ID and its already there to go to that record.
I have this working but when I try to edit the form I get an error stating that someone else
is trying to use the same form. I have isolated the code that is causing it but can't figure
out how to fix it.
Rebooted that didn't help so I moved the table from sql to Access and that sovled it.
I am using MS access where I click a button and it will upload a large number of files to my database. I want the user to be able to click the button and then minimise the application and when they come back all files are uploaded. However for a few of the files I get the error message "access was unable to append all the data to the table". This needs a user input and will not continue unless yes or no is selected.
For all these I always select yes, as I have a validation piece after this steps that will point out any issues.
Is there a way using VBA to build this yes selection into my code?
I already have the following in my code:
DoCmd.SetWarnings = False
DoCmd.RunSQL ...
DoCmd.SetWarnings = True
Thanks in advance,
Here is a function I use to execute sql, it returns the number of records effected by the SQL statement. It uses the 'On Error Resume Next' to handle any errors raised (not the best of coding practices). The function returns a 0 - it failed, if more then that's the number of recs effected by the SQL statement.
Function execSQL(vSQL) As Long
On Error Resume Next
Dim dbF As DAO.Database
Dim lngRecs As Long
DoCmd.SetWarnings False
Set dbF = CurrentDb
dbF.Execute vSQL
lngRecs = dbF.RecordsAffected
execSQL = lngRecs
DoCmd.SetWarnings True
dbF.Close
Set dbF = Nothing
End Function
Failing that, it may be better to use dao to execute the sql instead and then you can error trap properly on that and move on to the next record.
You could do something like this:
Sub MySub()
Dim strSql As String, fileName As String
On Error GoTo Err_MySub
'loop thru all files
strSql = "...'" & fileName & "' ...."
CurrentDb.Execute strSql
'end of loop
Exit Sub
Err_MySub:
Debug.Print fileName & " gives this error:" & Err.Description
End Sub
Press Ctrl-G to show the debug window. Maybe you should do something more clever in the error handler.
Action queries should be run using the Execute() method. No warnings of any kind are raised.
No parameters:
Currentdb().QueryDefs("QueryName").Execute dbFailOnError
With parameters:
With Currentdb().QueryDefs("QueryName")
.Parameters("ParameterName").Value = ParameterValue
.Execute dbFailOnError
End With
The dbFailOnError option will generate a run-time error if the query fails for whatever reason, so make sure your method handles errors. Lastly, if you need to see the records affected, check the RecordsAffected property of the query.
It's been a long time since I've had to do any development in Access, so hoping I can get some help. I have a split Front End/Back End solution that I've built. The Back End resides on a server, the front end gets copied down to user's desktops (and they use runtime Access 2013). I'm using Access with VBA and ADO connections/recordsets in order to do all record actions (Select, inserts, updates mostly).
Two intermittent issues have cropped up and I'm at a loss - this is one of them. From time to time, some users will get the error "Could not use "(back end Filename)"; file already in use." (where (back end filename) is my back end db name & location". When users get this message, they close out, re-open and try the same data entry and it works without a hitch. Here's the code:
Private Sub SetProblemCode()
On Error GoTo ErrorHandler
strSQL = "SELECT Problem_Code_ID, Problem_Code, Problem_Description FROM Problem_Code ORDER BY Problem_Description"
con.Open strConString
rstProblemCode.CursorLocation = adUseClient
rstProblemCode.Open strSQL, con, adOpenForwardOnly, adLockReadOnly
cboProblemCode.RowSourceType = "Table/Query"
Set cboProblemCode.Recordset = rstProblemCode
rstProblemCode.Close
con.Close
Exit Sub
ErrorHandler:
CriticalError Err.Description, Err.Number, Me.Name, "SetProblemCode"
End Sub
The rst and con objects are defined at the global level, a practice I've used in other solutions before but I'm questioning if that's some of the problem. I'm also questioning the cursor location, type and lock type I'm using, although it seems correct - I'm not altering data, just copying a recordset to the Access combo box.
I'm hesitant to make sweeping changes when it seems like the user closes out and tries again and it works just fine. Any thoughts?
I'm getting a 2498 error and really don't understand why. I'm building a string in VBA and am getting the error with the following line of code...
DoCmd.OpenQuery qdfNew, acNormal
It happened with a very long string created to create the query so I simplified the code as much as possible and am still getting the error.
Here's the code...
Option Compare Database
Option Explicit
Dim dbsFootball As Database
Dim strInsertSQL, strSelectSQL, strIntoSQL, strFromSQL, strOrderSQL, strSQL As String
Dim qdfNew As QueryDef
Sub CreateFormattedData()
Set dbsFootball = CurrentDb()
strSelectSQL = ""
strIntoSQL = ""
strFromSQL = ""
strOrderSQL = ""
strSQL = ""
strSelectSQL = "SELECT [tbl_Raw_League_Data].[Season]"
strIntoSQL = "INTO [tbl_Manip Data]"
strFromSQL = "FROM [tbl_Raw_League_Data]" _
+ "LEFT JOIN Referees ON [tbl_Raw_League_Data].[Referee] = Referees.[Referee from Source Data]"
strSQL = strSelectSQL + " " + strIntoSQL + " " + strFromSQL + " " + strOrderSQL
On Error Resume Next ' If query doesn't exist, error won't stop execution
DoCmd.DeleteObject acQuery, "pgmqry_Create Table tbl_Manip"
On Error GoTo 0 ' Reset error handler
Set qdfNew = dbsFootball.CreateQueryDef("pgmqry_Create Table tbl_Manip", strSQL)
DoCmd.OpenQuery qdfNew, acNormal
End Sub
The source field, [tbl_Raw_League_Data].[Season], is a "Short Text" data type (field size = 7).
If I terminate the VBA code and run the query that was created by the code, it works fine with no apparent errors. However, it will never run the query from within the VBA code.
I was originally getting the error 2498 when using "INSERT INTO" for an append query, but realized that the table could as easily be recreated at code execution time.
I'm lost and would sure appreciate some ideas!
Thanks in advance,
Jason
You are passing the querydef object to DoCmd.OpenQuery when it expects a string referencing name of a stored query object. Consider using the querydef's Name property:
DoCmd.OpenQuery qdfNew.Name, acNormal
Alternatively, use .Execute command from database object using the SQL string variable, bypassing any need for querydef:
dbsFootball.Execute strSQL, dbFailOnError
Or with querydef object, as #HansUp suggests, where you simply execute directly since it is an action query:
qdfNew.Execute dbFailOnError
Do note above two options bring up the regular MS Access discussion, of using stored vs VBA string query. While the former is precompiled and runs through query optimizer caching best plan, the latter can have sql dynamically created (structural components that is like SELECT, FROM and JOIN clauses as both can use passed in parameters). From your code snippet consider saving SQL query beforehand without needing to build it in VBA on the fly, and call it with DoCmd.OpenQuery.
So I have a system built in which it sets a few different flags and so on and so forth, but one of the things I want to do is take the contents of a staging table and send it over to another table used for tracking. I'm trying to do it using an insert into loop but I simply cannot figure out how to make it work as intended.
Private Sub Form_Load()
DoCmd.SetWarnings False
DoCmd.OpenQuery ("qryDeleteEmail")
Dim db As Object
Dim rst As Object
Dim test As Object
Set db = Application.CurrentDb
Set rst = db.OpenRecordset("qryDate")
Set test = db.OpenRecordset("tblEmailTemp")
If Me.RecordsetClone.RecordCount = 0 Then
MsgBox ("No delinquent accounts. No email will be generated.")
Me.Refresh
DoCmd.Close acForm, "qryDate", acSaveNo
DoCmd.CancelEvent
Else
rst.MoveFirst
Do Until rst.EOF
rst.Edit
rst!NeedsEmail = 1
rst.Update
rst.MoveNext
Loop
'DoCmd.Requery
'rst.Close
DoCmd.RunMacro ("StagingTable")
test.MoveFirst
Do Until test.EOF
CurrentDb.Execute "Insert Into EmailTracking (Account, ExpirationDate)" & _
"Values ('" & AccountName & "', '" & ExpirationDate & "')"
test.MoveNext
Loop
test.Close
rst.MoveFirst
Do Until rst.EOF
rst.Edit
rst!EmailSent = 1
rst.Update
rst.MoveNext
Loop
'DoCmd.Requery
rst.Close
DoCmd.RunMacro ("Close")
'DoCmd.OpenQuery ("qryDeleteEmail")
End If
Exit Sub
End Sub
What's happening right now is it's copying the first record of the staging table twice. For instance I have an account name A and an account name S, but instead of inserting the record for A and the record for S, it is simply inserting A twice.
Any help would be greatly appreciated!
Create and test a simpler procedure which is narrowly focused on the issue you're trying to solve. Unfortunately, I'm not sure what that issue is. I'll suggest this anyway ...
Public Sub TestLoopThruTable()
Dim db As DAO.database
Dim test As DAO.Recordset
Dim strInsert As String
DoCmd.SetWarnings True ' make sure SetWarnings is on
Set db = CurrentDb
Set test = db.OpenRecordset("tblEmailTemp")
Do While Not test.EOF
strInsert = "INSERT INTO EmailTracking (Account, ExpirationDate)" & vbCrLf & _
"VALUES ('" & AccountName & "', '" & ExpirationDate & "')"
Debug.Print strInsert
'db.Execute strInsert, dbFailOnError
test.MoveNext
Loop
test.Close
Set test = Nothing
Set db = Nothing
End Sub
Notice in your original version there was no space between ExpirationDate) and Values. I used a line break (vbCrLf) instead of a space, but either will keep the db engine happy.
I made sure SetWarnings is on. In your code, you turned it off at the start but never turned it back on again. Operating with SetWarnings off suppresses important information which you could otherwise use to understand problems with your code.
As that code loops through the recordset, it simply creates an INSERT statement and displays it for each row. You can view the output in the Immediate window (go there with the Ctrl+g keyboard shortcut). Copy one of those INSERT statements and test by pasting into SQL View of a new Access query. If it fails there, figure out what you need to change to satisfy the db engine. If the INSERT succeeds, try executing them from your code: enable the db.Execute line by removing the single quote from the start of that line.
The way you wrote the VALUES clause, it appears [ExpirationDate] is a text field. However if its data type is actually Date/Time, don't include quotes around the value you're inserting; use the # date delimiter instead of quotes.
Also make sure to include Option Explicit in the Declarations section of your code module like this:
Option Compare Database
Option Explicit
I mentioned that point because in an earlier version of this question you showed Option Compare but not Option Explicit. Trying to troubleshoot code without Option Explicit is a waste of time IMO.
I am not sure to understand what you are trying to do here; it is hard to understand what ErrorHandler is doing in the Else statement (even if commented).
As far as looping through a recordset goes, I advice you to read a little bit about the basis of VBA programmation in MS-Access. You can start by reading the articles below. It is a quick introduction about VBA recordsets and then the most common mistakes in VBA.
http://allenbrowne.com/ser-29.html
http://www.techrepublic.com/blog/10things/10-mistakes-to-avoid-when-using-vba-recordset-objects/373
It should help you improving your code.