智能表9.1.1
Smartsheet 是一個動態工作平台,可讓您管理專案、建立工作流程以及與團隊合作。
隨著您的 Excel 宏變得越來越強大和復雜,您可能會發現它們會失去性能。在討論宏時,性能一詞通常與速度同義。速度是您的 VBA 程序執行其預期任務的速度。以下是幫助您的 Excel 宏以最佳性能級別運行的十種方法。
您是否知道每次更改或操作影響電子表格中任何公式的單元格時,Excel 都會重新計算整個工作表?在具有大量公式的工作表中,此行為會大大降低宏的運行速度。
您可以使用 Application.Calculation 屬性告訴 Excel 切換到手動計算模式。當工作簿處於手動計算模式時,除非您通過按 F9 鍵明確觸發計算,否則工作簿不會重新計算。
將 Excel 置於手動計算模式,運行您的代碼,然後切換回自動計算模式。
子宏1() Application.Calculation = xlCalculationManual '把你的宏代碼放在這裡 Application.Calculation = xlCalculationAutomatic 結束子
將計算模式設置回 xlCalculationAutomatic 將自動觸發工作表的重新計算,因此在您的宏運行後無需按 F9 鍵。
您可能會注意到,當您的宏運行時,您的屏幕會出現大量閃爍。這種閃爍是 Excel 試圖重繪屏幕以顯示工作表的當前狀態。不幸的是,Excel 每次重新繪製屏幕時,都會佔用內存資源。
您可以使用 Application.ScreenUpdating 屬性禁用屏幕更新,直到您的宏完成。禁用屏幕更新可以節省時間和資源,讓您的宏運行得更快一點。宏代碼運行完畢後,您可以重新打開屏幕更新。
子宏1() Application.Calculation = xlCalculationManual Application.ScreenUpdating = False '把你的宏代碼放在這裡 Application.Calculation = xlCalculationAutomatic Application.ScreenUpdating = True 結束子
將 ScreenUpdating 屬性設置回 True 後,Excel 將自動觸發屏幕重繪。
Excel 狀態欄出現在 Excel 窗口的底部,通常顯示 Excel 中某些操作的進度。如果您的宏正在處理大量數據,狀態欄將佔用一些資源。
需要注意的是,關閉屏幕更新與關閉狀態欄顯示是分開的。即使您禁用屏幕更新,狀態欄也會繼續更新。您可以使用 Application.DisplayStatusBar 屬性暫時禁用任何狀態欄更新,進一步提高宏的性能:
子宏1() Application.Calculation = xlCalculationManual Application.ScreenUpdating = False Application.DisplayStatusBar = False '把你的宏代碼放在這裡 Application.Calculation = xlCalculationAutomatic Application.ScreenUpdating = True Application.DisplayStatusBar = True 結束子
您可以將宏實現為事件過程,告訴 Excel 在工作表或工作簿更改時運行某些代碼。
有時,標準宏會進行更改以觸發事件過程。例如,如果您有一個標準宏來操作 Sheet1 上的多個單元格,則每次更改該工作表上的一個單元格時,您的宏必須在 Worksheet_Change 事件運行時暫停。
通過使用 EnableEvents 屬性告訴 Excel 在宏運行時忽略事件,可以添加另一個級別的性能提升。
在運行宏之前將 EnableEvents 屬性設置為 False。宏代碼運行完畢後,您可以將 EnableEvents 屬性設置回 True。
子宏1() Application.Calculation = xlCalculationManual Application.ScreenUpdating = False Application.DisplayStatusBar = False Application.EnableEvents = False '把你的宏代碼放在這裡 Application.Calculation = xlCalculationAutomatic Application.ScreenUpdating = True Application.DisplayStatusBar = True Application.EnableEvents = True 結束子
每次宏修改行數、列數或更改工作表的頁面設置時,Excel 都被迫花時間重新計算工作表上顯示的分頁符。
您可以通過在啟動宏之前簡單地隱藏分頁符來避免這種行為。
將 DisplayPageBreaks 工作表屬性設置為 False 以隱藏分頁符。如果要在宏運行後繼續顯示分頁符,請將 DisplayPageBreaks 工作表屬性設置回 True。
子宏1() Application.Calculation = xlCalculationManual Application.ScreenUpdating = False Application.DisplayStatusBar = False Application.EnableEvents = False Activesheet.DisplayPageBreaks = False '把你的宏代碼放在這裡 Application.Calculation = xlCalculationAutomatic Application.ScreenUpdating = True Application.DisplayStatusBar = True Application.EnableEvents = True Activesheet.DisplayPageBreaks = True 結束子
如果您的宏操作包含大型數據源的數據透視表,則在執行諸如動態添加或移動數據透視字段之類的操作時可能會遇到性能不佳的情況。
您可以通過暫停數據透視表的重新計算直到完成所有數據透視字段更改來提高宏的性能。只需將 PivotTable.ManualUpdate 屬性設置為 True 以推遲重新計算,運行您的宏代碼,然後將 PivotTable.ManualUpdate 屬性設置回 False 以觸發重新計算。
子宏1() ActiveSheet.PivotTables("PivotTable1").ManualUpdate=True '把你的宏代碼放在這裡 ActiveSheet.PivotTables("PivotTable1").ManualUpdate=False 結束子
重要的是要記住,雖然宏記錄器通過為您編寫 VBA 代碼來節省時間,但它並不總是編寫最有效的代碼。一個主要的例子是 Macro Recorder 如何捕獲您在錄製時執行的任何復制和粘貼操作。
您可以通過刪除中間人並執行從一個單元格到目標單元格的直接複製來稍微提升宏。此替代代碼使用 Destination 參數繞過剪貼板並將單元格 A1 的內容直接複製到單元格 B1。
範圍(“A1”)。複製目的地:=範圍(“B1”)
如果您只需要復制值(而不是格式或公式),則可以通過同時避免 Copy 方法來進一步提高性能。只需將目標單元格的值設置為在源單元格中找到的相同值。此方法比使用 Copy 方法快約 25 倍:
Range("B1").Value = Range("A1").Value
如果您只需要將公式從一個單元格複製到另一個單元格(而不是值或格式),您可以將目標單元格的公式設置為源單元格中包含的相同公式:
Range("B1").Formula = Range("A1").Formula
錄製宏時,您經常會多次操作同一個對象。您可以通過使用 With 語句在一次拍攝中對給定對象執行多個操作來節省時間並提高性能。
以下示例中使用的 With 語句告訴 Excel 一次應用所有格式更改:
帶範圍(“A1”)。字體 .Bold = 真 .斜體=真 .Underline = xlUnderlineStyleSingle 結束於
養成將動作分塊到 With 語句中的習慣,不僅可以讓您的宏運行得更快,而且還可以更輕鬆地閱讀您的宏代碼。
Macro Recorder 喜歡使用 Select 方法在對對象執行操作之前明確選擇對象。在使用對象之前,通常不需要選擇對象。事實上,您可以通過不使用 Select 方法來顯著提高宏性能。
錄製宏後,養成修改生成代碼以刪除 Select 方法的習慣。在這種情況下,優化後的代碼如下所示:
Sheets("Sheet1").Range("A1").FormulaR1C1 = "1000" Sheets("Sheet2").Range("A1").FormulaR1C1 = "1000" Sheets("Sheet3").Range("A1").FormulaR1C1 = "1000"
請注意,沒有選擇任何內容。該代碼僅使用對象層次結構來應用所需的操作。
另一種加速宏的方法是限制在代碼中引用工作表數據的次數。從工作表中獲取數據總是比從內存中獲取數據的效率低。也就是說,如果您的宏不必反復與工作表交互,它們的運行速度會快得多。
例如,以下簡單代碼強制 VBA 不斷返回 Sheets(“Sheet1”).Range(“A1”) 以獲取在 If 語句中執行的比較所需的數字:
對於報表月 = 1 到 12 If Range("A1").Value = ReportMonth Then MsgBox 1000000 / 報表月 萬一 下一個報告月
一種更有效的方法是將 Sheets(“Sheet1”).Range(“A1”) 中的值保存到名為 MyMonth 的變量中。這樣,代碼引用 MyMonth 變量而不是工作表:
Dim MyMonth 作為整數 MyMonth = Range("A1").Value 對於報表月 = 1 到 12 如果 MyMonth = ReportMonth 那麼 MsgBox 1000000 / 報表月 萬一 下一個報告月
考慮利用變量來處理內存中的數據,而不是直接引用工作表。
呼叫物件的方法或屬性時,需要經過OLE元件的IDispatch介面。對這些OLE元件的呼叫需要時間,因此減少對OLE元件的參考次數可以提高巨集程式碼的速度。
對於物件屬性或方法的調用, 一般採用Object.Method的表示方法 ,即“.”。符號用於呼叫屬性和方法。
因此,可以根據符號「.」的個數來判斷方法或屬性的呼叫次數。越少的“.” 符號,程式碼運行速度越快。
例如下面的語句包含3個符號“.”。
ThisWorkbook.Sheet1.Range("A1").Value = 100
下面的語句只有一個符號「.」。
Activewindow.Top = 100
這裡有一些減少符號“.”數量的技巧。跑得更快。
首先,當需要重複引用同一個物件時,可以將該物件設定為變數以減少呼叫次數。例如,以下程式碼每行需要兩次呼叫。
ThisWorkbook.Sheets("Sheet1").Cells(1, 1) = 100
ThisWorkbook.Sheets("Sheet1").Cells(2, 1) = 200
ThisWorkbook.Sheets("Sheet1").Cells(3, 1) = 300
因為 Sheets(“Sheet1”) 物件需要重複引用,所以可以先將其設為一個變數 sht ,這樣每個程式碼只需要呼叫一次。
Set sht = ThisWorkbook.Sheets("Sheet1")
sht.Cells(1, 1) = 100
sht.Cells(2, 1) = 200
sht.Cells(3, 1) = 300
其次,如果不想宣告臨時變數sht,也可以使用 前面提到的With語句。如下例所示:
With ThisWorkbook.Sheets("Sheet1")
.Cells(1, 1) = 100
.Cells(2, 1) = 200
.Cells(3, 1) = 300
End With
第三, 當循環較多時,盡量將屬性和方法保留在循環之外。 在循環中重複使用同一物件的屬性值時,可以先將屬性值賦給循環外的指定變量,然後再在循環中使用該變量,這樣可以達到更快的速度。如下例所示:
For i = 1 To 1000
ThisWorkbook.Sheets("Sheet1").Cells(1, 1) = Cells(1, 2).Value
ThisWorkbook.Sheets("Sheet1").Cells(2, 1) = Cells(1, 2).Value
ThisWorkbook.Sheets("Sheet1").Cells(3, 1) = Cells(1, 2).Value
Next i
此範例中的每個迴圈都會取得單元格 Cells(1,2) 的 Value 屬性。如果在迴圈開始之前將 Cells(1.2) 的 Value 屬性指派給變量,則運行速度會更快。如下例所示:
tmp = Cells(1, 2).Value
For i = 1 To 1000
ThisWorkbook.Sheets("Sheet1").Cells(1, 1) = tmp
ThisWorkbook.Sheets("Sheet1").Cells(2, 1) = tmp
ThisWorkbook.Sheets("Sheet1").Cells(3, 1) = tmp
Next i
上面的程式碼 每次迴圈時都會呼叫ThisWorkbook.Sheets("Sheet1") 。您可以使用 With語句將對ThisWorkbook.Sheets("Sheet1") 的 呼叫移至 循環之外,從而更快地完成此操作。如下例所示:
tmp = Cells(1, 2).Value
With ThisWorkbook.Sheets("Sheet1")
For i = 1 To 1000
.Cells(1, 1) = tmp
.Cells(2, 1) = tmp
.Cells(3, 1) = tmp
Next i
End With
初學者通常更喜歡使用 Variant 類型變量,它的優點是不太複雜,因為對於 Integer 或 Long 資料類型來說,任何類型的資料都可以使用,不會出現記憶體溢出的問題。但是,Variant 類型資料比其他指定類型需要更多的額外記憶體空間(Integer 資料為2 個位元組,Long 資料為4 個位元組,Variant 資料為16 個位元組),VBA 處理Variant 類型資料比其他指定類型需要更多時間資料的。如下例所示。
Sub VariantTest()
Dim i As Long
Dim ix As Integer, iy As Integer, iz As Integer
Dim vx As Variant, vy As Variant, vz As Variant
Dim tm As Date
vx = 100: vy = 50
tm = Timer
For i = 1 To 1000000
vz = vx * vy
vz = vx + vy
vz = vx - vy
vz = vx / vy
Next i
Debug.Print "Variant types take " & Format((Timer - tm), "0.00000") & " seconds"
ix = 100: iy = 50
tm = Timer
For i = 1 To 1000000
iz = ix * iy
iz = ix + iy
iz = ix - iy
iz = ix / iy
Next i
Debug.Print "Integer types take " & Format((Timer - tm), "0.00000") & " seconds"
End Sub
上面的程式碼中,第8到13行對Variant變數做了100萬次加減乘除運算,第17到22行對Integer變數做了100萬次加減乘除運算。在我的電腦上,Variant變數的操作大約花費了 0.09375 秒,而Integer變數的操作大約花費了 0.03125 秒。結果可能因計算機而異,但 Variant 變數明顯慢於 Integer 變數。
因此, 建議在可以明確使用指定資料類型時避免使用 Variant 變數。
Smartsheet 是一個動態工作平台,可讓您管理專案、建立工作流程以及與團隊合作。
SharePoint 是一個基於 Web 的協作系統,它使用各種工作流程應用程式、「清單」資料庫和其他 Web 元件以及安全功能來控制業務群組的協同工作。
萬年日曆是一款手機上的日曆檢視應用程式,可協助您在手機上快速查看陰陽日期,從而安排您的重要工作。
Microsoft Outlook 是由 Microsoft Corporation 開發的商業和生產力應用程式。
ClickUp 是所有企業評價最高的生產力平台之一。Google、Booking.com、San Diego Padres 和 Uber 等大型企業都使用 ClickUp 來提高工作效率。
PDF 已成為閱讀、建立和傳送文字文件的常用格式。反過來,用於此類文件的程式數量也有所增加。PDF-XChange Viewer 是數量不斷增長的 PDF 檢視器之一。
Apache OpenOffice 提供了一整套可與 Microsoft 365 競爭的 Office 應用程序,尤其是 Excel、PowerPoint 和 Word。它允許您更有效地管理您的項目,並支援多種文件格式。
iTaxViewer軟體是當今最受歡迎的XML檔案讀取軟體。該軟體是用於讀取稅務總局 XML 格式電子報稅單的應用程式。
Nitro PDF Reader 是一款方便的 PDF 編輯器,涵蓋了大多數人每天使用 PDF 文件執行的所有基本任務。
Foxit Reader主要是一個PDF閱讀器,還允許您建立PDF文件、對其進行簽名、編輯以及添加註釋。它適用於作業系統,有 Microsoft Office 軟體包中各種程式的插件。