2

I am trying to write a macro in excel vba that simply opens an access database and runs 2 queries in access. It seems to work and run the queries every 2 clicks of the macro button. What I mean is I click it, it works, the 2nd click I get a 'runtime error 462' on the second click, the third click it works, the fourth click I get the error again and so on. I can't seem to figure out why this is. Here is the code below.

Sub QueryAccess1()

Dim db As Access.Application
Set db = New Access.Application
'set variables

db.Visible = True

db.OpenCurrentDatabase ("DatabaseFileName")
'open database

'--------------------------------------------------------------
On Error Resume Next

db.DoCmd.DeleteObject acTable, "TableName"
'if the table does not exist it skips this line
'--------------------------------------------------------------

On Error GoTo 0
'sets the error back to normal

'--------------------------------------------------------------
CurrentDb.Openrecordset ("QUERY1")
CurrentDb.Execute ("QUERY2")
'Calls the queries
'--------------------------------------------------------------

'--------------------------------------------------------------
db.CloseCurrentDatabase
db.Quit
'Closes Access
'--------------------------------------------------------------

Set db = Nothing

End Sub

When I get the error I am getting it on the line

CurrentDb.Openrecordset ("QUERY1")
7
  • Instead of Openrecordset try OpenQuery. If that doesnt work, you can open the query in Edit mode, look at the SQL view and build/use the SQL instead on VBA Excel. Commented May 16, 2018 at 15:28
  • Does Query2 create the table "TableName"? Maybe that is the logic why odd's fail? Commented May 16, 2018 at 15:30
  • Yes Query2 does create "TableName" but I am not sure thats a problem because I am deleting the table first if it exists? Commented May 16, 2018 at 15:31
  • 1
    What line gives you the error? Commented May 16, 2018 at 15:33
  • I get the error on line 'CurrentDb.Openrecordset ("QUERY1")' Commented May 16, 2018 at 15:35

2 Answers 2

0

I managed to get it to work with Parfait's method. Here is what I have got.

Sub QueryAccess1()

Dim conn As Object, rst As Object
Dim path As String


Set conn = CreateObject("ADODB.Connection")
Set rst = CreateObject("ADODB.Recordset")

path = Sheets("SheetName").Range("A1")

'OPEN CONNECTION
conn.Open ConnectionString:="Provider = Microsoft.ACE.OLEDB.12.0; data source=" & path

'DELETES TABLE CONTENTS
conn.Execute "DELETE FROM [Table1]"

'RUN UNION QUERY AND INSERT INTO TABLE
rst.Open "SELECT * FROM [Query1]", conn
conn.Execute "INSERT INTO [Table1]  select * from [QUERY1] "

Set rst = Nothing: Set conn = Nothing

End Sub
Sign up to request clarification or add additional context in comments.

1 Comment

Usually, posted solutions will never be exactly as you need. OPs will often need to make adjustments. The only real difference here is using the OLEDB Provider instead of ODBC Driver. Finally, in this code you do not ever use rst, so remove its set and .Open lines and just run the action queries.
0

Likely the every two click error is due to opening the table that was just deleted where every other time it exists. Consider iterating through MS Access's TableDefs collection to conditionally delete the object if it exists. Then, re-order your action query to run before OpenRecordset call.

Public Sub RunQueries()
On Error Goto ErrHandle:
    ' DAO REQUIRES REFERENCE TO Microsoft Office X.X Access Database Engine Object Library
    Dim tbl As DAO.TableDef     
    Dim rs As DAO.Recordset
    Dim db As New Access.Application

    db.Visible = False                   ' KEEP DATABASE RUNNING IN BACKGROUND

    For Each tbl in db.CurrentDb.TableDefs
        If tbl.Name = "TableName" Then
            db.DoCmd.DeleteObject acTable, "TableName"
        End If
    Next tbl

    ' ASSUMED AN ACTION QUERY
    db.CurrentDb.Execute "QUERY2", dbFailOnError

    ' ASSUMED A SELECT QUERY BUT CALL BELOW IS REDUNDANT AS IT IS NEVER USED
    Set rs = db.CurrentDb.OpenRecordset("QUERY1")   

ExitHandle:
    ' FREE RESOURCES
    Set rst = Nothing: Set conn = Nothing
    db.CloseCurrentDatabase
    db.Quit
    Set db = Nothing
    Exit Sub

ErrHandle:
    MsgBox Err.Number & " - " & Err.Description, vbCritical, "RUNTIME ERROR"
    Resume ExitHandle
End Sub

Aside - Avoid ever using On Error Resume Next in VBA. Always proactively anticipate and handle exceptions.


Alternatively, instead of using the make-table command SELECT * INTO and then having to worry about deleting the table programmatically, simple create your table once and then use DELETE and INSERT which can be run each time. Of course this assumes the table's structure (fields/types) remain the same.

DELETE FROM myTable;

INSERT INTO myTable (Col1, Col2, Col3) 
SELECT Col1, Col2, Col3 FROM myOtherTable;

SELECT * FROM myTable;

Finally, there is no reason to even use the MS Access object library to open/close the .GUI just to run queries. Since Access is a database, connect to it like any other backend (i.e., SQLite, Postgres, Oracle) and run your queries from there. Below is an ODBC connection example which the driver can easily be swapped for drivers of other RBDMS's.

Dim conn As Object, rst As Object

Set conn = CreateObject("ADODB.Connection")
Set rst = CreateObject("ADODB.Recordset")

' OPEN CONNECTION
conn.Open "DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};" _
            & "DBQ=C:\Path\To\Access\DB.accdb;"

' RUN ACTION QUERIES
conn.Execute "DELETE FROM myTable"
conn.Execute "INSERT INTO myTable (Col1, Col2, Col3)" _
               & " SELECT Col1, Col2, Col3 FROM myOtherTable"

' OPEN RECORDSET
rst.Open "SELECT * FROM myQuery", conn

' OUTPUT TO WORKSHEET
Worksheets("DATA").Range("A1").CopyFromRecordset rst
rst.Close

In fact, the above approach does not even require MS Access GUI .exe installed! Also, be sure to save the SELECT query (even one inside INSERT) inside Access and not run as a VBA SQL string since the Access engine will save the best execution plan for stored queries.

4 Comments

Hi Parfait, I think I need to open the Access Gui and run the queries because the 2nd query creates a table in access so I then want to close access so the file is now saved with the new table in it or can I do this without opening Access? Also I tried removing the 'on error resume next' line and added in your loop for finding if the table exists. This does work but frustratingly I get the same problem where I run the code for a 2nd time and getting the same runtime error :(
I should mention the 2nd time I run the code it errors at db.Visible = True
CREATE TABLE...SELECT * INTO are SQL - DDL commands so you do not need the GUI .exe. MS Access is a unique software being both a backend and frontend. Only when working with frontend application items like forms/reports/macros/modules do you need the GUI.
See edit using proper error handling as advised, never use On Error Resume Next. Then, check the pop-up error message to properly see the issue to be handled.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.