使用application.ontime重复运行宏时Excel使用太多内存

时间:2017-10-05 00:15:54

标签: excel vba excel-vba

我对VBA知之甚少,但是我创建了一个每15分钟运行一次的宏,只是在工作表中添加了一行,其中包含第一行的值(即rtd函数)。我运行的时间越长,excel使用的内存就越多,24小时后就会使用1gb +的RAM。无论如何我可以改善这一点或阻止这种情况发生,所以我可以运行代码几天?感谢

Sub Store()
currow = Workbooks("Store data.xlsm").Worksheets("Sheet1").Range("A65536").End(xlUp).Row

Workbooks("Store data.xlsm").Worksheets("Sheet1").Cells(currow + 1, 1) = Format(Now, "dd/mm/yyyy HH:nn:ss")

Workbooks("Store data.xlsm").Worksheets("Sheet1"). _
   Range(Workbooks("Store data.xlsm").Worksheets("Sheet1").Cells(currow + 1, 2), _
    Workbooks("Store data.xlsm").Worksheets("Sheet1").Cells(currow + 1, 47)) = _
    Workbooks("Store data.xlsm").Worksheets("Sheet1"). _
    Range(Workbooks("Store data.xlsm").Worksheets("Sheet1").Cells(2, 2), _
    Workbooks("Store data.xlsm").Worksheets("Sheet1").Cells(2, 47)).Value

Application.OnTime Now + TimeValue("00:15:00"), "Store"
End Sub

2 个答案:

答案 0 :(得分:3)

从早期的实验中我还发现Application.OnTime不应该调用自身(它需要调用一个单独的过程),并且以不同的方式处理递归

试试这两个版本:

V1 - Application.OnTime

Option Explicit

Public Sub UpdateStore()
    Application.OnTime Now + TimeValue("00:15:00"), "Store"
End Sub

Public Sub Store()
    Dim curRow As Long, firstRow As Range, lastRow As Range

    With Workbooks("Store data.xlsm").Worksheets("Sheet1")
        curRow = .Cells(Rows.Count, "A").End(xlUp).Row + 1
        .Cells(curRow, 1) = Format(Now, "dd/mm/yyyy HH:nn:ss")

        Set firstRow = .Range(.Cells(2, 2), .Cells(2, 47))
        Set lastRow = .Range(.Cells(curRow, 2), .Cells(curRow, 47))
    End With
    lastRow = firstRow.Value
    UpdateStore    'recursive call
End Sub

V2 - 睡眠API(已编辑 - 非递归)

Option Explicit

#If Win64 Then      'Win64=true, Win32=true, Win16= false
    Private Declare PtrSafe Sub Sleep Lib "Kernel32" (ByVal dwMilliseconds As Long)
#ElseIf Win32 Then  'Win32=true, Win16=false
    Private Declare Sub Sleep Lib "Kernel32" Alias "Sleep" (ByVal dwMilliseconds As Long)
#End If

Public Sub StoreSleepAPI()
    Dim curRow As Long, firstRow As Range, lastRow As Range, counter As Long

    For counter = 1 To 400    '<-- adjust this to "how many hours" * "4" ( times / hour)

        With Workbooks("Store data.xlsm").Worksheets("Sheet1")
            curRow = .Cells(Rows.Count, "A").End(xlUp).Row + 1
            .Cells(curRow, 1) = Format(Now, "dd/mm/yyyy HH:nn:ss")

            Set firstRow = .Range(.Cells(2, 2), .Cells(2, 47))
            Set lastRow = .Range(.Cells(curRow, 2), .Cells(curRow, 47))
        End With

        lastRow = firstRow.Value
        Sleep 900000    '1000 = 1 second, 900000 = 15 minutes
        DoEvents
    Next
End Sub

睡眠也使用较少的CPU

答案 1 :(得分:1)

我假设,基于您明确识别所涉及的对象Sub Store()在一般模块中。如果没有,请确保将其声明为Public,然后在Sub b()下方适当地修改调用。

您需要将操作与召回分开。将两个潜艇放在一个通用模块中(EDITED - 我之前将它们混合在一起):

 Public Sub a()
    Application.OnTime Now + TimeValue("00:15:00"), "b" 
 End Sub

 Public Sub b()
    Call Store
 End Sub

Application.OnTime Now + TimeValue("00:15:00"), "Store"中的Sub Store()替换为Call a。那就是它。

OnTime在通用模块(不在对象模块,例如工作表模块)中时有效。此外,它应该调用常规模块中的子(插入 - &gt;模块)。我只知道这是有效的(很久以前我花了一些时间才弄明白这一点)。此外,这种安排允许&#34; Store&#34;例程完成运行和VBA引擎清除用于运行&#34; Store&#34;的内存。

不过,不要只相信我(或者你自己):永远测试!