在 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
我有通过以下公式从 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