excel vba:暂停参数化的SQL查询来完成?

我有一个工作簿,其中几个数据提要根据某些下拉菜单/用户操作将parameter passing回SQL查询。 这样可以保持工作簿的修剪,改进计算等 – 将所有项目级别的细节保存在工作簿中是不现实的。

我的VBA的一些元素依赖于来自这些参数化查询的数据的评估。 这就产生了这个问题 – 在评估macros中的所有内容之前,VBA不会等待parameter passing回查询。

我很好奇,如果任何人有任何想法或build议的最佳做法,以编程方式暂停VBA执行,直到饲料刷新。 我现在的工作就是把我的VBA分成两部分,把依赖于改变的数据的东西放到一个单独的函数中,然后使用application.ontime来暂停X秒。

Application.OnTime Now + TimeSerial(0, 0, 10), "Restart" 

这是一个90%的解决scheme,但不够理想。 时间的长短是任意的 – 在一个非常缓慢的连接上,它不够长,在一个很快的连接上,这是不必要的缓慢。

理想情况下,有一些方法可以等待Excel准备就绪,然后继续。 与使用MS Internet Controls库时的使用方式类似

 Do Until .document.ReadyState = "complete" 

暂停执行,直到IE返回就绪状态。 任何更优雅的解决scheme的策略?

编辑:下面每个jon,添加代码并解释SQL查询如何工作:

 select sts1.studentid, sts1.alphascore as testcycle, sts2.numscore as lexile, sts3.alphascore as gleq, sts4.numscore as nce from ps.studenttestscore sts1 join ps.students stu on (sts1.studentid = stu.id) join ps.studenttestscore sts2 on (sts1.studenttestid = sts2.studenttestid) join ps.studenttestscore sts3 on (sts1.studenttestid = sts3.studenttestid) join ps.studenttestscore sts4 on (sts1.studenttestid = sts4.studenttestid) where (stu.id = ? ) and (sts1.testscoreid = 578) and (sts2.testscoreid = 575) and (sts3.testscoreid = 577) and (sts4.testscoreid = 576) 

这个? 是传递相关学生ID的参数 – MS查询使用该参数的单元格值。 它看起来只是根据学生的select进行查找的单元格:

 =IFERROR(INDEX(Stu!$B:$F,MATCH(Student!B2,Stu!$F:$F,0),1),999999) 

(iferror只是通过一个任意的数字,以防止不愉快的对话框popup,如果不正确的值被选中)。

你的错误是使用MS-Query。 使用ADODB编码数据库调用,并等待ADODB.Command对象的Execute方法。

…如果这就是你实际做的。 这里有一定数量的猜测,但是看起来好像查询的状态 – 不是它embedded的表格 – 是你需要的信息。

这段代码asynchronous地调用一个SQL查询 – 它在概念上类似于一个命令对象,这是(我认为)你实际上在做什么 – 粗略的“睡眠”循环可以被一个进度条或轮询标志代码在别处计算。

仅供参考,ADO对象的状态和状态属性可能会令人困惑。 通常,0表示closures,1表示closures(对于返回打开的连接或数据集的对象),高于1的值对应于等待或执行。

当然,您可以同步调用查询。

我可以给你“DataConnection”的代码,但是你最好去ConnectionStrings.com。


公共职能FetchRecordSet(SQL作为string,可选CursorType作为CursorTypeEnum = adOpenForwardOnly)作为ADODB.Recordset
在错误恢复下一步

设置FetchRecordSet =新的ADODB.Recordset

用FetchRecordSet

     .CacheSize = 8
    设置.ActiveConnection = DataConnection
     。打开SQL,CursorType,adLockReadOnly,adCmdText + adAsyncFetch

    做的时候。状态> 1
         Application.StatusBar =“正在检索数据...” 
        睡250
    循环

结束

 Application.StatusBar = False

结束function

[更新]

自从我发布这个答案后,我学到了一些东西:

如果您知道命令,行集返回函数或MS-Access数据库中的命名查询的名称,请不要打扰如此调用它:


     SQL =“SELECT * FROM MyQuery”
     。打开SQL,CursorType,adLockReadOnly,adCmdText + adAsyncFetch

按名称调用该命令,并使用adCmdStoredProc常量告诉数据库引擎它是一个命名命令:


     SQL =“MyQuery”
     。打开SQL,CursorType,adLockReadOnly,adCmdStoredProc + adAsyncFetch

它运行速度快得多。

在MSDN上查找CommandTypeEnum,并使用最适合您的任何工具:

https://msdn.microsoft.com/en-us/library/ms675946(v=vs.85).aspx

使用adCmdTable命名表,看看是否比'view'对象的adCmdStoredProc更好 – 我发现它在数据库引擎之间有所不同。

[/更新]