在Excell单元上,Excel不执行VBA for循环脚本

我有一个Excel电子表格,它具有附加function,可以根据固定范围内的数据进行计算。 按下F9或Shift-F9键,所有的工作表都能正常工作。

我正在为VBA编写一个for循环。 它从一个包含所有数据的工作表复制一个范围到另一个工作表。 然后一次手动计算一个工作表,暂停,甚至计算两次,以确保每个工作表的执行。 如果我通过整个for循环在debugging模式下逐行手动逐行执行VBA代码,则一切正常。 但是,如果我按F5并全速运行整个VBA for循环。 该代码为for循环的许多(不是全部)连续迭代产生相同的结果,而我知道结果应该都是不同的。 我的猜测是,工作环境变得陈旧,不会被新的数据取代。

以下是我的VBA代码。 我真的很感激,如果有人会看看它,并帮助解决这个问题。 有问题的代码的主要部分是“sht.Calculate”。

Option Base 1 #If VBA7 Then Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr) 'For 64 Bit Systems #Else Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) 'For 32 Bit Systems #End If Function runCalibrate() Dim xl As Workbook Set xl = ThisWorkbook nRowPerBlock = 15 yrs = Array("2005", "2006", "2007", "2008", "2009", "2010", "2011", "2012", "2013", "2014", "2015") Application.Calculation = xlCalculationManual strikeSentinel = Array(1, 13) maturitySentinel = Array(1, 10) nRow = maturitySentinel(2) - maturitySentinel(1) + 1 nCol = strikeSentinel(2) - strikeSentinel(1) + 1 For j = 1 To UBound(yrs) Set a = Worksheets(yrs(j)).Cells(3, 2) For i = 0 To 11 b = a.Offset(1 + nRowPerBlock * i, 1).Resize(nRow, nCol) xl.Sheets("SPX").Range("p4:ab13") = b 'refresh required worksheets Call RefreshSheetNX(xl.Sheets("TODAY")) Call RefreshSheetNX(xl.Sheets("USD")) Call RefreshSheetNX(xl.Sheets("SPX")) Call RefreshSheetNX(xl.Sheets("EQ Model")) Call RefreshSheetNX(xl.Sheets("EQ Calibration")) c = xl.Sheets("EQ Calibration").Range("c18:c32") xl.Sheets("calibration time series").Cells(38, 2 + 12 * (j - 1) + i).Resize(15, 1) = c Next i Next j End Function Function RefreshSheetNX(sht As Worksheet) On Error Resume Next sht.Cells.Dirty sht.Calculate Call Sleep(1000) sht.Calculate Call Sleep(1000) End Function 

正如Byron所build议的那样,我在下面的代码中使用了“Application.CalculateFullRebuild”。 但是当我通过“Application.CalculateFullRebuild”时,它根本就没有反应。

 Option Base 1 #If VBA7 Then Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr) 'For 64 Bit Systems #Else Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) 'For 32 Bit Systems #End If Function runCalibrate() Dim xl As Workbook Set xl = ThisWorkbook nRowPerBlock = 15 yrs = Array("2005", "2006", "2007", "2008", "2009", "2010", "2011", "2012", "2013", "2014", "2015") Application.Calculation = xlCalculationManual strikeSentinel = Array(1, 13) maturitySentinel = Array(1, 10) nRow = maturitySentinel(2) - maturitySentinel(1) + 1 nCol = strikeSentinel(2) - strikeSentinel(1) + 1 For j = 1 To UBound(yrs) Set a = Worksheets(yrs(j)).Cells(3, 2) For i = 0 To 11 b = a.Offset(1 + nRowPerBlock * i, 1).Resize(nRow, nCol) xl.Sheets("SPX").Range("p4:ab13") = b 'refresh required worksheets ' Call RefreshSheetNX(xl.Sheets("TODAY")) ' Call RefreshSheetNX(xl.Sheets("USD")) ' Call RefreshSheetNX(xl.Sheets("SPX")) ' Call RefreshSheetNX(xl.Sheets("EQ Model")) ' Call RefreshSheetNX(xl.Sheets("EQ Calibration")) Application.CalculateFullRebuild c = xl.Sheets("EQ Calibration").Range("c18:c32") xl.Sheets("calibration time series").Cells(38, 2 + 12 * (j - 1) + i).Resize(15, 1) = c Next i Next j End Function 

考虑使用Application.CalculateFullRebuild而不是多次调用来Calculate每个工作表。 它将强制重新计算一切并重build依赖关系(顾名思义)。

根据公式之间如何相互关联,您可能不会触发正确的计算顺序,每次处理一张纸张。 完整的重build方法是刷新电子表格的“核选项”。 具体来说,调用sht.Cells.Dirty然后sht.Calculate可能只强制刷新当前表单而不考虑其他表单上的更改。