excel 如何计算整个工作簿,而不是所有打开的工作簿?

cunj1qz1  于 2023-11-20  发布在  其他
关注(0)|答案(8)|浏览(120)

是否有一种方法可以在VBA中计算整个工作簿而不是所有打开的工作簿?
我知道

worksheet.Calculate

字符串
但它只能做一张纸。我还知道

Application.CalculateFull


但我认为这会同时重新计算所有打开的工作簿。
是否可以只做一个工作簿?

**编辑:**我了解方法:

For Each wks In ActiveWorkbook.Worksheets
    wks.Calculate
Next


但如果工作表之间有链接,这是非常危险的,那么计算的顺序就很重要。我知道我可以找到确切的顺序并应用它,问题是在非常大的工作簿上,这可能会变得有些棘手

yh2wf1be

yh2wf1be1#

经过一定的调查和测试,首先选择所有的床单和计算后的工程:

Application.Calculation = xlManual
ThisWorkbook.Sheets.Select
ActiveSheet.Calculate

字符串
这将同时计算所有选定的图纸,从而创建正确的计算顺序。

ykejflvf

ykejflvf2#

史蒂芬·G的答案实际上并不起作用,只是看起来像。
它仍然以1个方向的顺序计算工作表。我通过创建5个工作表并将它们全部+ 1到另一个单元格来测试这一点,在每个工作表上以不同的方向。使用选择工作表然后计算方法将给予错误的结果。
因为它要求工作表是可见的,所以我构建了一个函数来替换使用该方法的calculate函数。(需要字典参考库)。但不要使用。

EXAMPLE, METHOD DOES NOT WORK
Function Calculate_Workbook(Optional Wb As Workbook)

'Application.calculate will calculate all open books, which can be very slow.
'Looping through all sheets in workbook to calculate can be risky due to formula referencing a cell thats not yet calculated, calculation order may be important.
Dim DicShtVisible As New Dictionary
DicShtVisible.CompareMode = TextCompare
Dim Asht As Worksheet, AWkbk As Workbook    'Previously selected books
Dim Sht As Worksheet

Set Asht = ActiveSheet
Set AWkbk = ActiveWorkbook

If Wb Is Nothing Then Set Wb = ThisWorkbook

Wb.Activate
'Unhide all sheets as can't select very hidden stuff
For Each Sht In Wb.Sheets
    DicShtVisible.Add Sht.Name, Sht.Visible
    Sht.Visible = xlSheetVisible
Next Sht

'Select all sheets and calculate the lot
Wb.Sheets.Select
ActiveSheet.Calculate

'Reapply visibility settings
Dim Key As Variant
For Each Key In DicShtVisible.Keys
    Wb.Sheets(Key).Visible = DicShtVisible.Item(Key)
Next Key

'Reset selections
AWkbk.Activate
Asht.Select

End Function

字符串
据我所知,没有解决方案,唯一的答案是要么知道你的工作簿的计算顺序,并手动计算工作表的顺序,或接受使用计算,它将计算所有打开的工作簿。
然而,我很想被证明是错的。这是一个如此恼人和愚蠢的问题。

2izufjch

2izufjch3#

据我所知没有。
你实际上是在浪费时间做Application.Worksheets(1).Calculate
我运行了一个计时测试:在同一个Excel示例中打开了3个工作簿。
一个有8200个volatile函数,一个工作表中有8000个在4个不连续的范围内,其他工作表中有200个。
另外两个工作簿,总共有100个函数。结果:

  • Application.Calculate - 4.41 ms
  • ThisWorkbook.Worksheets(1).Calculate-每个工作表52.05 ms
  • ThisWorkbook.Worksheets(1).Range("R1").Calculate(重复4次)- 84.64 ms

这是违反直觉的,但事实如此。
声明Dim wks as Worksheet也会浪费时间。除非您执行For.
另外,要小心引用ActiveWorkbook-当你的代码运行你的主工作簿可能不是活动的一个。ThisWorkbook(一个代码)更安全。

r1zhe5dt

r1zhe5dt4#

ThisWorkbook将只使用代码所在的工作簿

For Each wks In ThisWorkbook.Worksheets
    wks.Calculate
Next wks

字符串

ltqd579y

ltqd579y5#

我们可以用

Application.CalculateBeforeSave = True

字符串
然后保存工作簿?可以更巧妙地捕获当前值,如果不为真则设置,如果不为真则保存,重置。

5jdjgkvh

5jdjgkvh6#

另一种选择是创建一个新的Excel示例,打开该示例的工作簿,然后计算该示例。这将使原始示例中的任何工作簿都不计算,如果另一个工作簿的计算速度非常慢(例如100k+公式),则可能节省您的时间。

Dim xlApp As Excel.Application
Dim wbTest As Workbook

Set xlApp = New Excel.Application
Set wbTest = xlApp.Workbooks.Open("c:\temp\test.xlsx")

' do a bunch of stuff in wbTest

xlApp.Calculate

字符串
这是否更好取决于您的情况。打开第二个Excel示例涉及一点额外的时间和可能更多的内存(尽管我没有测试过这一点,它可能不是一个显着的量)。
您可能需要更改更多代码,以考虑到此工作簿位于不同示例中的事实,并且某些函数可能存在问题(例如,如果您通过后台处理Excel原始示例中的所有工作簿来检查工作簿是否已打开)。

r3i60tvu

r3i60tvu7#

试试这个:

Sub CalcBook()
    Dim wks As Worksheet
    Application.Calculation = xlManual
    For Each wks In ActiveWorkbook.Worksheets
        wks.Calculate
    Next
    Set wks = Nothing
End Sub

字符串

qvk1mo1f

qvk1mo1f8#

使用Calculate
例如:

Sub Cal_()
    Calculate
End Sub

字符串

相关问题