在Excel中暂停RTD服务器并保存工作表

时间:2015-02-08 18:01:25

标签: excel vba rtd

我有工作表,它通过以下公式从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 有什么建议吗?

2 个答案:

答案 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