我有工作表,它通过以下公式从RTD服务器获取数据:
=RTD("tos.rtd", , "ASK", ".SPX150220C750")
我想每1分钟左右用上面的公式保存工作表。挑战是暂停VBA代码并确保在保存之前,更新单元格中的值。我试过以下代码。
Sub Archiving()
For i = 0 To 4
Worksheets("Test").Activate
Application.Sheets("Test").Copy
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs Filename:="D:\Save " & i & ".csv", FileFormat:=xlCSV
ActiveWorkbook.Save
ActiveWindow.Close
Windows("Real time data.xlsm").Activate
Application.DisplayAlerts = True
Application.Wait (Now + TimeValue("0:00:05"))
ActiveWorkbook.RefreshAll
DoEvents
Next i
End Sub
代码不起作用,因为DoEvents等待RTD完成更新,这是永远不会的。我也看到了明确暂停与DB的连接的示例,但我不知道如何调整它的RTD服务器案例。我试图从C#运行RTD服务器,但失败了。 RTD in C# for dummies 有什么建议吗?
答案 0 :(得分:3)
面临的挑战是暂停VBA代码,并确保在保存之前,更新单元格中的值。
您之前实现的问题是通过在循环内完成,因为VBA不支持多线程,应用程序“忙”并且无法从RTD服务器接收新数据。
这主要基于我从微软的documentation/knowledge-base收集的内容,重点补充:
RTD函数从RTD服务器检索数据以供在 工作簿。每当新数据变为时,功能结果都会更新 可从服务器获得,工作簿可以接受。服务器 在更新前等待Excel处于空闲状态。这减轻了开发人员的负担 必须确定Excel是否可用于接受更新。 RTD功能在这方面与其他功能不同,因为 只有在重新计算工作表时才会更新其他功能。
进一步表明,切换应用程序的.CalculationState
等对RTD服务器没有任何影响:
由于RTD在Excel空闲时更新数据,会继续接收 如果Excel处于手动计算模式,则显示信息。在该事件中, 缓存新数据,并在手动时使用当前值 进行计算。
因此数据在服务器上可用时会更新(可能不是问题),但实现中的问题是工作簿无法接受它,因为它正在运行VBA线程并且RTD公式是不是“正常”的外部链接。
虽然RTD功能提供了指向服务器上数据的链接,但确实如此 与其他工作表中的单元格引用不同的链接类型 或工作簿。例如,如果在工作簿中使用RTD函数, 打开时,您没有收到链接启动消息 工作簿,也无法通过管理来管理RTD功能的状态 “编辑链接”对话框。
我怀疑另一个不同之处是RefreshAll
方法对此函数没有影响,你不能强制它获取外部数据,因为它已经这样做了当工作簿可以接受它时强>
潜在解决方案
通过使用Application.OnTime
事件来安排保存间隔,我认为您应该能够避免工作簿无法接收数据的问题。
如果你想定期保存数据,这个函数会递归调用自己,受Appliction.OnTime
method的限制:
Private Sub CreateArchive()
'Saves a copy of sheet "Test" and sets OnTime to save again in 60 seconds
Dim saveTime as String
saveTime = Format(Now(), "YYYY-MM-DD-hh-nn")
Worksheets("Test").Copy
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs Filename:="D:\Save " & saveTime & ".csv", FileFormat:=xlCSV
ActiveWorkbook.Close
Windows("Real time data.xlsm").Activate
Application.DisplayAlerts = True
'Call on this function again in 60 seconds:
Application.OnTime Now + TimeValue("00:00:60"), CreateArchive
End Sub
注意:我无法复制,因为我没有你的COM对象/ etc。从RTD函数调用。所以,请大家注意这一点,并了解我能为你提供多少帮助,我非常有限。
答案 1 :(得分:1)
我有一个类似的问题。我在VBA中添加了以下命令,以触发RTD数据刷新。在使用VBA宏中的数据之前,我已经执行了此命令。希望这会有所帮助。
Excel.Application.RTD.RefreshData