我有一个Excel电子表格,其中包含用于计算固定范围内给定数据的加载项功能。按下F9或Shift-F9键,所有工作表都能正常工作。
我正在用VBA写一个for循环。它将范围从包含所有数据的一个工作表复制到另一个工作表。然后一次手动计算一个工作表,暂停,甚至计算两次,以确保每个工作表的执行。如果我在调试模式中通过整个for循环逐行手动逐步执行VBA代码,一切正常。但是,如果我按F5并以全速运行整个VBA循环。代码为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所说,我使用'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
答案 0 :(得分:0)
考虑使用Application.CalculateFullRebuild
代替对每张工作表的Calculate
多次调用。它将强制重新计算所有内容并重建依赖关系(顾名思义)。
根据公式在工作表之间的相关性,您可能无法触发正确的计算顺序,一次处理每个工作表。完全重建方法是刷新电子表格的“核选项”。具体来说,调用sht.Cells.Dirty
然后调用sht.Calculate
可能只会强制刷新当前工作表而不考虑其他工作表上的更改。