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
更好 – 我发现它在数据库引擎之间有所不同。
[/更新]