我有一个Excel加载项(带有Userform),它连接到Access数据库(使用DAO)来执行各种功能。十多年来,我一直在使用这个组合。 Excel中的代码和数据库最近都没有更改过。就在上周,一位用户报告说他们的一个功能比平常花了更长的时间,所以我调查了一下。它最终表明函数本身运行得很好,但是当代码清理并运行db.Close时它就挂了。它不会产生错误,它最终仍会成功,但关闭数据库并继续前进大约需要一分钟。
我会经历所有的症状和尝试的解决方案,看看是否有其他人有任何想法,因为我不知所措。
只有在运行db.Execute时才会发生这种情况。我可以打开数据库并立即关闭它,它关闭就好了。如果我打开它,运行一个SELECT查询来填充一个记录集,然后关闭它,它也关闭就好了。但是,如果我打开它并运行单个UPDATE / SELECT INTO / INSERT / ALTER / DROP语句,则Close方法将花费一分钟时间运行。
我的第一个想法是压缩数据库。我清除了几张未使用的旧桌子并进行了紧凑/修复,但这没有做任何事情。同样的问题。
我的下一次尝试是重新创建数据库。我创建了一个全新的TEST db,从旧的表导入了所有表,在新数据库中指向我的Excel加载项并进行了相同的测试。相同的结果。
我的下一次尝试是尝试将其移至本地驱动器(它位于网络共享上)。这个稍微减少了关闭时的挂起,但它仍然存在。这并不重要,因为这个数据库必须托管在网络共享上。
我的下一次尝试是从我的TEST数据库中删除一堆表。我清除了大约一半的人,并且关闭时的挂机减少了很多。清理更多甚至更多。删除除一个表之外的所有表都将其删除。所以现在我知道我的问题与数据库的大小有关,但为什么呢?紧凑型后,它的最大尺寸为500MB。它运行良好多年。为什么突然之间表格的大小/数量会如此巨大?我显然无法删除生产数据库中的所有表,只是为了解决关闭连接的问题。
正如我所提到的,这段代码已经存在很长时间了,prod db实际上是Access 2000格式(mdb),所以我的下一次尝试是改变格式。我尝试将它全部导入Access 2003格式(mdb)和最新的Access 2016格式(accdb)。结果是一样的。
在云端,我想我会尝试从外接程序之外的其他位置点击数据库(因为问题出在我的Excel文件中)。我将我的测试代码复制并粘贴到Word 2016模块中......它运行得很好。
那很奇怪。
然后我尝试了一个全新的Excel文件。也跑得很好。
所以我回到我的加载项并尝试粘贴到模块中的代码。
再次,运行良好。
...
所以我打开Userform并再次运行我的测试代码。挂断了。
??????
我创建一个全新的Excel文件,制作一个空的Userform,将我的测试代码粘贴到表格的初始化事件....挂起。
之后我立即在模块中运行相同的代码......仍然挂起。即使一分钟前它在一个不同文件的模块中运行得很好。
但是如果我关闭文件,打开一个新文件,粘贴代码而不打开Userform,然后运行它,它运行正常。创建/打开用户窗体将导致所有后续尝试运行代码挂起。
所以这里是Cliff的Notes版本:
Excel 2016 DAO连接到大型数据库访问数据库在db.Close上挂起,但在以下情况下:
1)数据库很大(删除大多数表有帮助,但显然不是解决方案)。
2)您在Excel会话期间随时打开任何Userform。无论代码在何处运行,在表单打开后的OR期间的所有尝试都将挂起。在打开Userform之前运行代码不会挂起。
这些结果在多台Windows 7计算机上都是重复的,所有这些都显示为Office的最新更新。
编辑:我能够在运行Excel 2013的远程计算机上尝试这一点并且没有挂起(使用最初显示问题的原始插件/数据库)。但是,该机器位于我们的数据中心,与网络共享所在的位置相同,因此至少有两个可能的原因:1)不同版本的Excel和2)不同/更快网络连接。如果您想知道为什么我使用DAO而不是ADO,那就是因为这些函数的作用(很多东西通过Tabledef循环来修改索引甚至创建/修改表说明,无法通过ADO访问。如果不是这样,我只需切换到ADO并完成它。我可能会成为能够为其目前正在做的所有事情提供ADO备选方案/解决方案,但如果我能帮助它,我宁愿不重写整个插件。
我完全失去了这个,所以如果有人有任何想法,我会全力以赴。