Excel VBA Cells.Find失败,除非我使用Application.Wait。 为什么?
我正在研究一个VBAmacros,我遇到了一些非常奇怪的行为。
它适用于Application.ScreenUpdating = True
,甚至在屏幕更新closures时也可以正常工作,并使用VBAdebugging器逐步执行macros。
只是在屏幕更新closures的情况下运行macros,不幸的是,导致Find
函数在下面的代码中失败:
Application.StatusBar = "Extracting data and updating tables..." Application.ScreenUpdating = False Application.DisplayAlerts = False Workbooks.Open FileName:=Save_folder & "new_data.xls" Workbooks("new_data.xls").Sheets("data").Range("B9:B39").Copy Dim tempdate As Date, startCell As Range tempdate = DateAdd("d", -1, Now) tempdate = DateSerial(Year(tempdate), Month(tempdate), 1) 'Start of the month Dim strdate As String strdate = Format(tempdate, "Short Date") Set startCell = ThisWorkbook.Sheets("Raw Data").Cells.Find(What:=CDate(strdate), After:=ThisWorkbook.Sheets("Raw Data").Range("A1"), LookIn:=xlFormulas _ , LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False) If startCell Is Nothing Then MsgBox "Couldn't find a date equal to the start of yesterday's month." Exit Sub Else startCell.Offset(0, 1).PasteSpecial xlPasteValues, Transpose:=False End If
将这个简短的代码片段添加到Cells.Find
的调用中解决了这个问题:
'Wait one second, to appease the Excel object creation gods Application.StatusBar = "Wait one second..." Application.Wait Now + TimeValue("00:00:01") Application.StatusBar = "Pasting values..."
抛出一个MsgBox
或提示符等也可以使Find
成功。
我的问题是,为什么我必须等待?
我无法产生这种行为。 看截图
Sub Sample() Dim tempdate As Date, startCell As Range Dim strdate As String Application.ScreenUpdating = False Application.DisplayAlerts = False tempdate = DateAdd("d", -1, Now) tempdate = DateSerial(Year(tempdate), Month(tempdate), 1) 'Start of the month strdate = Format(tempdate, "Short Date") Set startCell = ThisWorkbook.Sheets("Raw Data").Cells.Find(What:=CDate(strdate), LookIn:=xlFormulas _ , LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False) If startCell Is Nothing Then MsgBox "Couldn't find a date equal to the start of yesterday's month." Else MsgBox "Found" End If Application.ScreenUpdating = True Application.DisplayAlerts = True End Sub
快照
更新 :
如果代码中发生了很多事情,则使用DoEvents
以便代码将控制传递给操作系统,以便操作系统可以处理其他事件。
在尝试解决相同的问题时,我遇到了这个线程,而且在运行任何.Find函数之前,只需激活工作表即可解决DoEvents技巧。
你的代码和我的代码之间唯一的区别是它们都使用.Find函数。 也许这就是堵塞操作系统的原因。