在Access中从Excel中运行macros,但Access在运行后不会closures

我从Excel VBA打开Microsoft Access并运行一个macros,然后在Excel中运行更多的代码。 一切都很好,但是现在我遇到了两个问题。 运行macros后,First Access不会closures,因此Excel超时(它会popup一个消息框,提示Microsoft Excel正在等待另一个应用程序完成OLE操作)。 这实际上是另一个问题,因为当它超时,我必须再次与Excel交互,使Excel中的macros继续运行。 我试图在Excel中首次启动macros之前不必碰任何东西,直到完成。 我认为这也可能是超时,因为我在Access中添加了更多的步骤到我的macros,所以它需要更长的时间…

首先,这里是调用Access的Excel代码:

Sub Opendatabase() Dim accessApp Set accessApp = CreateObject("Access.Application") accessApp.Visible = True accessApp.OpenCurrentDataBase ("I:\MyPath\MyFile.accdb") accessApp.Run "ImportDataRunQueriesExportData" 'Run the next part of Excel macro Application.Run "PullinTheExportedAccessData" End Sub 

然后在Access中,它会这样做(对不起它太长了)。 它的目的是拉取数据,运行查询(我通过打开和closures它们,我不确定是否有更快的方式)然后导出数据。 我也希望它最后也能结束,现在这个部分不起作用。

 Sub ImportDataRunQueriesExportData() DoCmd.RunSavedImportExport "Import-ERT Aggregate Macro" 'Open master book January to refresh DoCmd.SetWarnings False DoCmd.OpenQuery ("Remove HP not Area8") DoCmd.OpenQuery ("Remove Non Area 8 HP") DoCmd.SetWarnings True DoCmd.OpenTable ("Remove HPnonArea8") DoCmd.Close acTable, "Remove HPnonArea8" DoCmd.OpenQuery ("Summary For January") 'Open Duplicate search queries across all c DoCmd.OpenQuery ("S+D") DoCmd.OpenQuery ("S+D+L") DoCmd.OpenQuery ("S+D+L+F") DoCmd.OpenQuery ("S+D+L+F+M") 'Open Duplicate search queries within c DoCmd.OpenQuery ("C+S+D") DoCmd.OpenQuery ("C+S+D+L") DoCmd.OpenQuery ("C+S+D+L+F") DoCmd.OpenQuery ("C+S+D+L+F+M") 'Save and close queries, made with create Macro function DoCmd.Close acQuery, "Summary For January" DoCmd.Close acQuery, "S+D" DoCmd.Close acQuery, "S+D+L" DoCmd.Close acQuery, "S+D+L+F" DoCmd.Close acQuery, "S+D+L+F+M" DoCmd.Close acQuery, "C+S+D" DoCmd.Close acQuery, "C+S+D+L" DoCmd.Close acQuery, "C+S+D+L+F" DoCmd.Close acQuery, "C+S+D+L+F+M" 'Open Summary Queries DoCmd.OpenQuery ("New January") DoCmd.OpenQuery ("Renew January") DoCmd.OpenQuery ("Count October") DoCmd.OpenQuery ("Count November") DoCmd.OpenQuery ("Count December") DoCmd.OpenQuery ("5B") DoCmd.OpenQuery ("5CW") DoCmd.OpenQuery ("5ML") DoCmd.OpenQuery ("5M") DoCmd.OpenQuery ("5S") DoCmd.OpenQuery ("RA") 'Save and close queries and table DoCmd.Close acQuery, "New January" DoCmd.Close acQuery, "Renew January" DoCmd.Close acQuery, "Count October" DoCmd.Close acQuery, "Count November" DoCmd.Close acQuery, "Count December" DoCmd.Close acQuery, "5B" DoCmd.Close acQuery, "5CW" DoCmd.Close acQuery, "5ML" DoCmd.Close acQuery, "5M" DoCmd.Close acQuery, "5S" DoCmd.Close acQuery, "RA" 'Make Table, delete w/in c dups, Open Data Table SD Between C, close table DoCmd.SetWarnings False DoCmd.OpenQuery ("Table S+D") DoCmd.OpenQuery ("Delete C+S+D") DoCmd.SetWarnings True DoCmd.OpenTable ("SD Between C") DoCmd.Close acTable, "SDBC" 'Run saved exports of the queries to folder DoCmd.RunSavedImportExport "Export-S+D" DoCmd.RunSavedImportExport "Export-S+D+L" DoCmd.RunSavedImportExport "Export-S+D+L+F" DoCmd.RunSavedImportExport "Export-S+D+L+F+M" DoCmd.RunSavedImportExport "Export-C+S+D" DoCmd.RunSavedImportExport "Export-C+S+D+L" DoCmd.RunSavedImportExport "Export-C+S+D+L+F" DoCmd.RunSavedImportExport "Export-C+S+D+L+F+M" DoCmd.RunSavedImportExport "Export-New January" DoCmd.RunSavedImportExport "Export-Renew January" DoCmd.RunSavedImportExport "Export-Count October" DoCmd.RunSavedImportExport "Export-Count November" DoCmd.RunSavedImportExport "Export-Count December" DoCmd.RunSavedImportExport "Export-5B" DoCmd.RunSavedImportExport "Export-5CW" DoCmd.RunSavedImportExport "Export-5ML" DoCmd.RunSavedImportExport "Export-5M" DoCmd.RunSavedImportExport "Export-5S" DoCmd.RunSavedImportExport "Export-S D Between C" DoCmd.RunSavedImportExport "Export-RA" Dim n As Integer Dim db As DAO.Database Set db = CurrentDb For n = db.TableDefs.Count - 1 To 0 Step -1 ' loop through all tables If InStr(1, db.TableDefs(n).Name, "ImportError") > 0 Then ' if table is import errors table DoCmd.DeleteObject acTable, db.TableDefs(n).Name ' delete table End If Next n Application.SetOption "Auto compact", True End Sub 

任何帮助将不胜感激。 谢谢。

从我能看到你的问题在于如下几行:

 DoCmd.OpenQuery ("5ML") 

将其更改为:

 accessApp.DoCmd.OpenQuery ("5ML") 

详细说明这一点:DoCmd方法来自Access VBA库。 所以你需要一个访问应用程序对象来运行它。 你创build了这个对象,所以你的代码工作。 但是,当调用作为访问应用程序一部分的方法而不引用应用程序对象时,您将创build对自动化应用程序(在本例中为Access)的全局引用。 这就是为什么应用程序不会closures,即使您在最后closures它。 这当然是你应该做的。 所以你必须首先把应用程序对象放在访问应用程序的每个方法之前,然后正确地closures应用程序。 作为一项规则:

 accessApp.AMethodOfTheAccessApplication ... accessApp.CloseCurrentDatabase accessApp.Quit Set accessApp = Nothing 

这里有一篇文章更加清晰,正确,详细地解释了这一点: 程序不会退出

编辑:要使您的TableDef-Deletion-Loop在Excel中运行,您可以使用以下代码(请注意,您必须同时引用Microsoft 16.0 Access数据库引擎对象库以及Microsoft Access 16.0对象库 16是不重要的,只是采取这些库可用的最新版本)):

 Dim AccessApp As New Access.Application Dim tdf As DAO.TableDef AccessApp.OpenCurrentDatabase ("SomeDrive:\SomePath\SomeDb.accdb") For Each tdf In AccessApp.CurrentDb.TableDefs ' loop through all tables If InStr(1, tdf.Name, "tblDelete") > 0 Then ' if table is import errors table AccessApp.DoCmd.DeleteObject acTable, tdf.Name ' delete table End If Next tdf Set tdf = Nothing AccessApp.CurrentDb.Close AccessApp.Quit Set AccessApp = Nothing 

正如你所看到的,我使用了后期绑定而不是早期绑定(用于testing目的)。 所以,如果你决定使用早期的绑定(就像你上面的代码(不用担心引用,我猜)),你只需要弄清楚如何声明tdf对象。 这个绑定的东西是什么意思?

编辑编辑 :这里是与后期绑定相同的循环:

 Dim AccessApp As Object Set AccessApp = CreateObject("Access.Application") Dim tdf As Object AccessApp.OpenCurrentDatabase ("SomeDrive:\SomePath\SomeDb.accdb") For Each tdf In AccessApp.CurrentDb.TableDefs ' loop through all tables If InStr(1, tdf.Name, "tblDelete") > 0 Then ' if table is import errors table AccessApp.DoCmd.DeleteObject 0, tdf.Name ' delete table End If Next tdf Set tdf = Nothing AccessApp.CurrentDb.Close AccessApp.Quit Set AccessApp = Nothing