我对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
答案 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;的内存。
不过,不要只相信我(或者你自己):永远测试!