-1

我有通过以下公式从 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 服务器,但失败得很惨。C# 中的 RTD 用于傻瓜有 什么建议吗?

4

2 回答 2

3

挑战在于暂停 VBA 代码并确保在我们保存之前,单元格中的值已更新。

您之前实现的问题是,通过在循环中执行此操作,由于 VBA 不支持多线程,应用程序“忙”并且无法从 RTD 服务器接收新数据。

这主要基于我从 Microsoft 的文档/知识库中收集的内容,重点补充说:

RTD 函数从 RTD 服务器检索数据以在工作簿中使用。只要有新数据从服务器可用并且工作簿可以接受,函数结果就会更新。服务器 等到 Excel 空闲后再更新。这使开发人员不必确定 Excel 是否可以接受更新。RTD 函数在这方面不同于其他函数,因为只有在重新计算工作表时才会更新其他函数。

并进一步表明切换应用程序.CalculationState等对 RTD 服务器没有影响:

因为 RTD 在 Excel 空闲时更新数据,所以如果 Excel 处于手动计算模式,它会继续接收信息。在这种情况下,新数据将被缓存,并在执行手动计算时使用当前值。

因此,数据将在服务器可用时更新(可能不是问题),但您的实现中的问题是工作簿无法接受它,因为它正在运行 VBA 线程并且 RTD 公式不是“正常”外部链接。

尽管 RTD 函数提供了指向服务器上数据的链接,但它与引用其他工作表或工作簿中的单元格的链接类型不同。例如,如果您在工作簿中使用 RTD 功能,则在打开工作簿时不会收到 Links 启动消息,也无法通过 Edit Links 对话框管理 RTD 功能的状态。

我怀疑另一个不同之处是该RefreshAll方法对此功能没有影响,您不能强制它获取外部数据,因为当工作簿可以接受它时它已经这样做了。

潜在的解决方案

通过使用Application.OnTime事件来安排保存间隔,我想应该可以避免工作簿无法接收数据的问题。

如果您想定期保存数据,此函数将递归调用自身,受Appliction.OnTime方法限制:

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 函数调用。因此,请对此持保留态度,并了解我可以为您提供多少进一步的帮助非常有限。

于 2015-02-09T01:04:37.530 回答
2

我有一个类似的问题。我在我的 VBA 中添加了以下命令来触发 RTD 数据刷新。在我使用 VBA 宏中的数据之前,我执行了此命令。希望这可以帮助。

Excel.Application.RTD.RefreshData

于 2018-07-26T15:07:36.747 回答