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

Pause RTD server in Excel and save worksheet

我有通过以下公式从 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 完成更新,而这永远不会。我还看到了显式暂停与数据库的连接的示例,但我不知道如何调整 RTD 服务器案例。我尝试从 C# 运行 RTD 服务器,但失败得很惨。 有什么建议吗?

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

您之前的实现的问题 是在循环内执行,因为 VBA 不支持多线程,应用程序是 "busy" 并且无法从 RTD 服务器接收新数据。

这主要基于我从 Microsoft documentation/knowledge-base 收集到的内容,重点补充:

The RTD function retrieves data from an RTD server for use in the workbook. The function result is updated whenever new data becomes available from the server and the workbook can accept it. The server waits until Excel is idle before updating. This relieves the developer of having to determine whether Excel is available to accept updates. The RTD function differs from other functions in this regard because other functions are updated only when the worksheet is recalculated.

并进一步建议切换应用程序的 .CalculationState 等将对 RTD 服务器没有影响:

Because RTD updates data when Excel is idle, it continues to receive information if Excel is in manual calculation mode. In that event, the new data is cached and the current values are used when a manual calculation is performed.

因此,当数据从服务器可用时,数据将被更新(大概不是问题),但您的实现中的问题是工作簿无法接受它,因为它是 运行 VBA 线程和 RTD 公式不是 "normal" 外部 link.

Although the RTD function provides a link to data on a server, it is not the same type of link as references to cells in other worksheets or workbooks. For example, if you use the RTD function in a workbook, you do not receive the Links startup message when you open the workbook, nor can you manage the status of an RTD function through the Edit Links dialog box.

我怀疑另一个不同点是 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 函数调用的。因此,请对此持保留态度,并了解我能为您提供的进一步帮助非常有限。

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

Excel.Application.RTD.RefreshData