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函数。 也许这就是堵塞操作系统的原因。