Вероятно, ошибка каждые два клика связана с открытием только что удаленной таблицы, где бы она ни находилась. Рассмотрите возможность перебора коллекции MS Access TableDefs , чтобы условно удалить объект, если он существует. Затем измените порядок выполнения запроса действий перед вызовом OpenRecordset .
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
В сторону - никогда не используйте On Error Resume Next
в VBA. Всегда заранее предвидеть и обрабатывать исключения.
В качестве альтернативы, вместо использования команды make-table SELECT * INTO
и необходимости программного удаления таблицы, просто создайте таблицу один раз , а затем используйте DELETE
и INSERT
, которые могут бегать каждый раз. Конечно, это предполагает, что структура таблицы (поля / типы) остается прежней.
DELETE FROM myTable;
INSERT INTO myTable (Col1, Col2, Col3)
SELECT Col1, Col2, Col3 FROM myOtherTable;
SELECT * FROM myTable;
Наконец, нет никаких оснований даже использовать библиотеку объектов MS Access для открытия / закрытия .GUI только для выполнения запросов. Поскольку Access - это база данных, подключитесь к ней, как к любому другому бэкэнду (например, SQLite, Postgres, Oracle), и выполняйте ваши запросы оттуда. Ниже приведен пример подключения ODBC, драйвер которого можно легко заменить на драйверы других RBDMS.
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
Фактически, вышеупомянутый подход даже не требует установленного MS Access GUI .exe! Кроме того, обязательно сохраняйте запрос SELECT
(даже один внутри INSERT
) внутри Access и не запускайте его как строку SQL VBA, поскольку механизм доступа сохранит лучший план выполнения для сохраненных запросов.