2015-02-08 102 views
-1

我有工作表,其通過以下公式從RTD服務器獲取數據:暫停RTD服務器在Excel和保存工作表

=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

我對RTD不熟悉,但是您是否嘗試過使用WinAPI'Sleep'功能?這應該使Excel應用程序在指定的時間間隔內「睡眠」。每1分鐘節省似乎不必要的課稅,不是嗎?應用程序如此不穩定以致較長的時間間隔不適合? – 2015-02-08 18:31:24

+0

謝謝大衛。我想我已經嘗試了'睡眠'。問題在於Excel無法完全更新工作表,Excel會一直保存舊數據。我可以將保存間隔增加到5分鐘,但我的目標是收集實時數據,所以我希望在技術上儘可能縮小保存間隔。 – user1700890 2015-02-08 19:51:54

+0

我仍然很好奇爲什麼你覺得需要經常保存文檔...你是否在每個保存點都創建一個新的文件副本?如果是這樣,這是非常多餘的,不是嗎?如果不是,每次「保存」操作都會覆蓋之前的保存,那麼爲什麼不使用較小的間隔,或者爲什麼不打算自動保存呢?假設你的應用程序是穩定的,並且不會隨機「崩潰」,那麼就沒有真正的數據丟失風險...... – 2015-02-08 20:03:44

回答

1

面臨的挑戰是暫停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對象/等。這是從RTD函數調用的。所以,請盡情享受這一點,並瞭解我可以爲您提供的進一步援助非常有限。

+0

大衛,你是最棒的!你的方法奏效!萬分感謝! – user1700890 2015-02-09 02:39:57