1

所以我正在编写一个引用bloomberg单元格公式的代码......因此循环通常比数据加载速度更快。我认为如果我能以某种方式延迟循环的迭代,这可以相对容易地解决......这会给细胞时间来填充。这是我到目前为止所写的,我不确定如何写最后一行。

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 
4

1 回答 1

3

Application.OnTime基本上安排一个事件在特定时间/之后运行。即使在代码执行并清除堆栈后,它也允许您安排事件运行。这就是为什么它是一种Application水平方法。

OnTime方法不会暂停或延迟任何事情,它只是一个调度程序。因此,您的其余代码将继续执行,并且无论代码在多大程度上依赖于等待 的任务的结果OnTime,您都会遇到错误。

从理论上讲,我认为您可能会出于您的目的使这种方法以一种迂回的方式工作,但我认为使用 WinAPISleep函数可能会更好。这也为您提供了更大的粒度(您可以指定到毫秒)。

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

您可以通过调用从任何子例程或函数调用它:

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

更新

我注意到您的代码实际上并不包含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
于 2013-09-23T01:29:11.207 回答