基于Excel VBA,创建ADODB对象或使用DOCMD.RUNSQL是否更好?哪个是pro&contra?

m.f*_*lli 2 vba ado adodb excel-vba access-vba

根据标题,创建ADODB对象或访问对象是否更好然后使用DOCMD.runsql?我通常使用Excel工作表和访问表.哪种方法更快,更灵活可靠?有一些细节是赞成还是反对?

Nig*_*nan 5

简短的回答是:

  1. ADODB更快,更可靠,它可能具备您所需的功能;
  2. 如果您真的需要,Access Application对象具有更丰富的功能;
  3. Access Application对象可能(或可能不会)允许您运行SQL和查询具有嵌入式VBA的对象.

更详细......

如果您正在使用DoCmd,那么您已经将MSAccess.exe的副本实例化为您的Access应用程序对象的一部分 - 这是相当多的内存,并且它需要几秒钟才能启动:不是您想要做的事情一项微不足道的任务.

但是,您现在可以使用所有Access应用程序对象的方法和属性 - 不仅仅是DoCmd,您还拥有所有CurrentDB对象,包括querydefs集合.因此,如果这是一项复杂的任务,而不仅仅是"运行这个简单的查询",那么Access Application对象就具有优势.

一个很大的缺点是您无法将此工作表分发给在其工作站上没有MSAccess.exe的用户:他们的VBA无法创建MS-Access应用程序的实例及其DoCmd方法.

创建ADODB对象要快得多,并且每个拥有MS-Office的人都拥有用于MS-Access的OLEDB数据库驱动程序,即使他们的计算机上没有Office或MS-Access的"专业"版本.

对象实例化是这里的一个重要性能问题:ADODB对象和MS-Access的OLEDB数据库驱动程序也会比MS-Access.exe运行查询稍快,但这并不是你会注意到的性能优势.

请注意,ADODB连接对象将为您提供详细的错误和状态信息,您可以设置超时(在连接上,以及命令对象或记录集对象),以防止慢速查询或MS-Access进程失败.

如果您是一位经验丰富的开发人员,能够很好地掌握事件驱动编程以及Access的最新OLEDB驱动程序的详细属性,那么您可以让SQL以异步方式运行 - 启动命令,将控制权交还给Excel并让用户继续工作,直到ADO对象引发"已完成"事件.因此,如果您不需要数据,则可以将SQL作为即发即弃操作运行,并且可以在流程完成时使用事件过程在代码中启动响应 - 或向用户报告错误.

但是,如果这是关于将数据返回到Excel表或图表对象,则内置查询工具现在(Office 2013)比您在VBA中可以执行的操作更快,无论是DoCmd还是ADODB:即使使用异步ADO,第一个数据块始终是同步的,并且您的Excel会话被"异步"VBA命令锁定,直到它到达为止.

您的ADODB对象肯定无法使用嵌入式VBA命令运行SQL - 既不是本机VBA也不是MS-Access数据库中编写的自定义代码 - 这可能会让您大吃一惊:该__CODE__函数在Access中编写的Jet SQL中非常常见,如果在MS-Access环境之外调用SQL,它将无法运行.其他VBA包含不太明显,字符串处理是一个特殊的混淆源:这个Stack Overflow答案给出了详细的解释.但是,我不确定您是否可以从MS-Access应用程序对象运行带有嵌入式VBA的Jet_SQL查询,如果它在另一个启用VBA的应用程序中实例化:我从未尝试过,我很可能就是你只能使用MS-Access的实际用户会话运行受VBA限制的Jet-SQL.你需要测试一下!

一个快速的性能提示:您的SQL实际上是MS-Access数据库中保存的查询(A DAO Querydef对象)的名称吗?如果是这样,请将其作为ADODB.Command对象运行,而不是将其作为SQL文本执行; 或使用'adCmdStoredProc'选项打开记录集(并运行'execute'方法):

__CODE__

此外,如果初学者到中级开发人员正在阅读此内容以搜索相关问题的答案,请检查您的SQL是否未在MS-Access数据库中查询外部定义的链接表或"传递"查询:直接连接到实际托管数据的ADODB对象将运行得更快,更快.

这就是我现在所能想到的,我希望其他Stackers继续添加这个答案,以便我们得到一个全面的列表.