ThisWorkbook.Refresh从timer sub调用时不起作用

问题描述 投票:2回答:1

[编辑:]固定代码标签[/编辑]

我设置了一个计时器(代码从各种来源改编)。它调用一个sub,其中包含一行ThisWorkbook.RefreshAll如果我通过从其中点击F5来运行子RefreshData,它可以正常工作。如果我从Timer子中调用sub,我得到运行时错误50290

数据包括对SQL Server数据库的各种查询。

代码:

尝试过之后添加DoEvents,没有去。同样的错误。

Sub Timer()

Dim TimeOut As Long
'Set Timeout in minutes
TimeOut = 5

If blnTimer Then

    lngTimerID = KillTimer(0, lngTimerID)

    If lngTimerID = 0 Then

        MsgBox "Error: Timer Not Stopped"

        Exit Sub

    End If

    Debug.Print "blnTimer = False"
    blnTimer = False

Else

    lngTimerID = SetTimer(0, 0, TimeSerial(0, TimeOut, 0), AddressOf RefreshData)

    If lngTimerID = 0 Then

        MsgBox "Error: Timer Not Generated"

        Exit Sub

    End If
    Debug.Print "blnTimer = True"
    blnTimer = True

End If

Debug.Print "Timer Complete at " & Time

End Sub

Sub RefreshData()

'Refresh all data connections
ActiveWorkbook.RefreshAll

'Complete all refresh events before moving on
DoEvents

Debug.Print "Data Refreshed at " & Time

End Sub

预期的结果是每隔5分钟调用一次子RefreshData,它将运行命令ThisWorkbook.RefreshAll并更新所有外部数据连接。

[编辑:]更新 - 我刚尝试在RefreshAll上方执行Application.CalculateFullRebuild(根据here),并在CalculateFullRebuild行上显示相同的错误代码。情节加厚......

[编辑2]我将发布我的完整解决方案,因为我将其限制在我们的办公时间,这对于发现此帖子的人可能也很有用。感谢@EvR的Application.OnTime帮助!注意:下面的代码必须在ThisWorkbook中,并且您要运行的模块必须位于Module1中,或者您必须将Module1更改为您的代码所在的位置 - 当然还要将Sub的名称从RefreshData更改为您的sub,两者都在启动计时器和结束计时器潜艇......

[Edit3]:我忘了为MyTime包含公共变量声明 - 如果不将它用作公共变量(即在任何子程序之外),则取消例程(ThisWorkbook_BeforeClose)将不起作用,您将收到错误每次关闭工作簿时:它需要确切的MyTime值来取消计时器。

[Edit4]:如果timer> = officecloses应该是 - 否则当小时为17:00时它将设置Seconds = 0 ...并且在手动再次打开工作簿之前它不会再次运行!下面的代码更新。

[编辑5]:秒需要是Long类型,因为当我总和过夜时,在整数中没有足够的内存需要大量的秒数!代码更新如下。

[编辑6]:我刚刚发现你不能在当前时间增加23个小时(当你想到它时会有意义 - 日期回落到Excel的第一个日期)。我需要添加DateAdd(“d”,1,MyTime)并将MyTime的初始设置更改为使用Now而不是Time(现在包括时间和日期)。是的我每天早上都手动打开它,因为这样找到内存错误,然后确定,手动关闭和打开......直到今天。今天是一个全新的一天!! :D纠正了以下代码。

Public Dim MyTime As Date

Sub RefreshOnTime()

Dim Delay As Integer
Dim OfficeOpens As Integer
Dim OfficeCloses As Integer
Dim Overnight As Integer
Dim DayAdvance As Integer

'Delay in seconds
Delay = 240
'hour of opening
OfficeOpens = 7
'hour of closing (24hr clock)
OfficeCloses = 17

'If in working hours
If Hour(Time) >= OfficeOpens And Hour(Time) < OfficeCloses Then
    Overnight = 0
    DayAdvance = 0
'If in the morning (e.g. auto open after scheduled reboot at 3am)
ElseIf Hour(Time) < OfficeOpens Then
    Overnight = (OfficeOpens - Hour(Time))
    DayAdvance = 0
'If after 5pm add 1 to day
'Add morning hours
ElseIf Hour(Time) >= OfficeCloses Then
    Overnight = (OfficeOpens - Hour(Time))
    DayAdvance = 1
End If

Debug.Print "Hours = " & Overnight

'Add Seconds to current time
MyTime = DateAdd("s", Delay, Now)
Debug.Print "MyTime after adding Seconds = " & MyTime

'Add DayAdvance to MyTime
MyTime = DateAdd("d", DayAdvance, MyTime)
Debug.Print "MyTime after adding DayAdvance = " & MyTime

'Add Overnight to MyTime
MyTime = DateAdd("h", Overnight, MyTime)

Debug.Print "RefreshData will run at " & MyTime

'REPLACE MODULE1 with the right module
'REPLACE RefreshData with the name of your sub
Application.OnTime MyTime, "Module1.RefreshData"

End Sub


Private Sub Workbook_BeforeClose(Cancel As Boolean)

'REPLACE MODULE1 with the right module
'REPLACE RefreshData with the name of your sub
Application.OnTime MyTime, "Thisworkbook.RefreshData", , False

End Sub


Private Sub Workbook_Open()

'Just in case you need to debug
'Uncomment these 3 lines and click "No" on workbook open
'Dim Ans As Variant
'Ans = MsgBox("Do you want to run RefreshOnTime?", vbYesNo, "Yes/No")
'If Ans = vbYes Then RefreshOnTime

RefreshOnTime

End Sub
excel vba runtime-error refresh
1个回答
1
投票

用ThisWorkbook-section中的代码替换你的timer-sub:

Dim MyTime As Date

Sub RefreshOnTime()
RefreshData
MyTime = DateAdd("s", 500, Time)
Application.OnTime MyTime, "Thisworkbook.RefreshOnTime"
End Sub

Private Sub Workbook_BeforeClose(Cancel As Boolean)
Application.OnTime MyTime, "Thisworkbook.RefreshOnTime", , False
End Sub

Private Sub Workbook_Open()
RefreshOnTime
End Sub
© www.soinside.com 2019 - 2024. All rights reserved.