2013-09-22 93 views
1

因此,我正在編寫一個引用bloomberg單元格公式的代碼......因此循環經常跳過的速度比數據可以加載的快。我認爲如果我能以某種方式延遲循環的迭代,就可以相對容易地解決這個問題......這將給單元格填充時間。這是我迄今寫的,我不確定如何真正寫出最後一行。如何使用Application.OnTime來延遲循環

x = 1 


If x < TixCollection.count Then 

    ' runs report if ADR Close is active 
    If Sheets("Input").Range("L2").value = "x" Then 
     Call build_singleEquity(x) 
      'Set pat = New pattern 

      Application.OnTime Now + TimeValue("00:00:10"), "pattern_recogADR" 

      If Sheets("Input").Range("L5").value = "x" Then 
       Dim sht_name As String 
       sht_name = TixCollection(x).ADR & "_ADRclose" 
       Call Sheet_SaveAs(path_ADRclose, sht_name, "SingleEquityHistoryHedge") 
      End If 
    End If 


    'runs report if ORD Close is active 
    If Sheets("Input").Range("L9").value = "x" Then 
     Call build_ordCloseTrade(x) 



      If Sheets("Input").Range("L13").value = "x" Then 

       Dim sht_name1 As String 
       sht_name1 = TixCollection(x).ADR & "_ORDclose" 
       Call Sheet_SaveAs(path_ORDclose, sht_name1, "OrdCloseTrade") 
      End If 
    End If 


Application.OnTime Now + TimeValue("00:00:15"), x = x + 1 'want to write something like this but syntax is wrong 
+0

值得注意的是:您提供的這段代碼實際上並不包含任何'Loop'結構。除此之外,我認爲你需要使用'睡眠'功能。請參閱下面的答案。嘗試一下,並根據需要修改你的代碼 - 如果你有麻煩,我會檢查並嘗試提供幫助。 –

回答

3

Application.OnTime基本上調度以在/特定時間後運行一個事件。它允許你安排一個事件,即使你的代碼已經執行並清除堆棧之後,甚至可以運行。這就是爲什麼它是Application級別的方法。

OnTime方法不會暫停或延遲任何事情,它只是一個調度程序。因此,其餘代碼將繼續執行,並且無論代碼依賴於等待OnTime的任務結果,您都會遇到錯誤。

從理論上講,我認爲你可能會爲了你的目的而以一種迂迴的方式工作,但我認爲你可能會更好地使用WinAPI Sleep函數。這也給你更大的粒度(你可以指定爲毫秒)。

Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) 

您可以通過調用任何子程序或函數,調用這個:

Sleep 5000 'pause for 5000ms, (5 seconds) 

UPDATE

我注意到你的代碼實際上並不包含Loop結構。我想我明白你想要做什麼。下面是它刺傷:

Do While x < TixCollection.count Then `or consider: Do While x <= TixCollection.Count 

    ' runs report if ADR Close is active 
    If Sheets("Input").Range("L2").value = "x" Then 
     Call build_singleEquity(x) 
      'Set pat = New pattern 

      Sleep 10000 
      Call pattern_recogADR 

      If Sheets("Input").Range("L5").value = "x" Then 
       Dim sht_name As String 
       sht_name = TixCollection(x).ADR & "_ADRclose" 
       Call Sheet_SaveAs(path_ADRclose, sht_name, "SingleEquityHistoryHedge") 
      End If 
    End If 


    'runs report if ORD Close is active 
    If Sheets("Input").Range("L9").value = "x" Then 
     Call build_ordCloseTrade(x) 
      If Sheets("Input").Range("L13").value = "x" Then 

       Dim sht_name1 As String 
       sht_name1 = TixCollection(x).ADR & "_ORDclose" 
       Call Sheet_SaveAs(path_ORDclose, sht_name1, "OrdCloseTrade") 
      End If 
    End If 

x = x+1 
Sleep 15000 'Wait for 15 seconds 
Loop 

這是很難說,如果這兩個Sleep(你以前OnTime調用)的真正需要,因爲我不知道哪一個(或者兩個)被引入的錯誤條件。

您需要確保將Sleep函數的代碼放入vba項目中。

更新

假設休眠功能,或Application.Wait方法不爲你工作,你可以嘗試另一件事是一個簡單的Do/While循環。雖然我無法複製你的狀況,但這似乎是最可靠的。

Dim newTime As Date 
newTime = Now + TimeValue("00:00:10") 
Do While Not Now >= newTime 
    DoEvents 
Loop 

最後的選擇是禁用並手動強制計算,如下所示。我的理解是應用程序很忙,並且在計算事件發生時不會執行代碼。但是,考慮到這一點,我不確定這些方法是否適用於您,因爲儘管您指出它正在等待Excel工作表計算,但我認爲這不可行,工作表事件優先於運行代碼,所以我認爲客戶端仍然會發生一些情況,除非他們通過API提供某種方法(例如返回布爾值的.Busy等),否則您可能無法可靠地進行捕獲。

Dim appCalc as Long: appCalc = Application.Calculation 
Application.Calculation = appCalc '# disable automatic calculation 
Call build_singleEquity(x) 
Application.Calculate 'Force calculation 
Application.Calculation = xlCalculationAutomatic '# return to normal/previous property 
Call pattern_recogAD 
+0

hm好吧我會給你一個鏡頭 – googlekid

+0

嗨大衛的代碼不工作,因爲睡眠功能停止了一切......包括具有bloomberg功能的單元格正在加載數據 – googlekid

+0

好的。我對bloomberg API不熟悉,但他們是否提供任何方法來確定它是否仍在加載數據?此外,此代碼中的哪一行是開始加載數據的調用? –