[英]How to improve slow macro?
I need to use Word Macro for automatically proofreading the documents.我需要使用 Word 宏来自动校对文档。 I have an excel file, filled in with all the wrong spelling words, and after I installed the macro to Microsoft Word, it took several minutes to finish the spelling checking for just 1 page of the Word Document.
我有一个 excel 文件,填写了所有错误的拼写单词,在我将宏安装到 Microsoft Word 后,只需要几分钟就完成了 Word 文档的 1 页的拼写检查。
Can I use.txt to replace the excel in order to make it faster?我可以使用 .txt 替换 excel 以使其更快吗? Or what should I improve?
或者我应该改进什么? Below please find the code for the Macro:
请在下面找到宏的代码:
Attribute VB_Name = "PR"属性 VB_Name = "PR"
Option Explicit
Sub PR()
Dim Path As String
Dim objExcel As Object
Dim iCount As Integer
Dim VChar As String
Dim OChar As String
Options.AutoFormatAsYouTypeReplaceQuotes = True
Path = "D:\Macro\rplPR.xlsx"
'Highlight variant characters
With ActiveDocument
.TrackRevisions = False
.ShowRevisions = False
End With
Set objExcel = CreateObject("Excel.Application")
objExcel.Workbooks.Open Path
For iCount = 2 To 2500
Selection.HomeKey Unit:=wdStory
VChar = objExcel.ActiveWorkbook.Sheets(1).Cells(iCount, 1)
If Len(VChar) = 0 Then Exit For
Selection.HomeKey Unit:=wdStory, Extend:=wdMove
With Selection.Find
.ClearFormatting
.Replacement.ClearFormatting
.Replacement.Highlight = True
.Text = VChar
.Replacement.Text = "^&"
.Execute Replace:=wdReplaceAll
End With
Next
objExcel.ActiveWorkbook.Close
objExcel.Quit
End Sub
Move these lines up to above the For
statement.将这些行向上移动到
For
语句的上方。 You are setting them 2,499 times and you only need to do it once.您正在设置它们 2,499 次,而您只需要设置一次。
.ClearFormatting
.Replacement.ClearFormatting
.Replacement.Highlight = True
.Text = VChar
.Replacement.Text = "^&"
So each dot is a function call.所以每个点都是一个 function 调用。 There are 5 needless ones done 2498 times which is 12,490 function calls.
有 5 次不必要的调用 2498 次,即 12,490 次 function 调用。
Function calls, while essential, are slow compared to other operations as there is a lot of setup. Function 调用虽然必不可少,但与其他操作相比速度很慢,因为有很多设置。
If you didn't use with
that would be an extra 12,490 function calls as well for a total of 24,980 sloww needless function calls.如果您不
with
,那么额外的 12,490 个 function 调用以及总共 24,980 个慢速不必要的 function 调用。
Try the following.试试下面的。 Do note that there is necessarily some overhead involved in starting Excel (if not already running), as well as processing the workbook.
请注意,启动 Excel(如果尚未运行)以及处理工作簿必然会产生一些开销。 Hence, even a single-page document will encounter the same overhead there as a 100-page document.
因此,即使是单页文档也会遇到与 100 页文档相同的开销。
Sub BulkFindReplace()
Application.ScreenUpdating = False
Dim xlApp As Object, xlWkBk As Object, StrWkBkNm As String, StrWkSht As String
Dim iDataRow As Long, xlFList As String, xlRList As String, i As Long
StrWkBkNm = "D:\Macro\rplPR.xlsx": StrWkSht = "Sheet1"
'Start Excel
Set xlApp = CreateObject("Excel.Application")
If xlApp Is Nothing Then
MsgBox "Can't start Excel.", vbExclamation
Exit Sub
End If
On Error GoTo 0
With xlApp
'Hide our Excel session
.Visible = False
' The file is available, so open it.
Set xlWkBk = .Workbooks.Open(StrWkBkNm, False, True)
If xlWkBk Is Nothing Then
MsgBox "Cannot open:" & vbCr & StrWkBkNm, vbExclamation
.Quit: Set xlApp = Nothing: Exit Sub
End If
' Process the workbook.
With xlWkBk
With .Worksheets(StrWkSht)
' Find the last-used row in column A.
iDataRow = .Cells(.Rows.Count, 1).End(-4162).Row ' -4162 = xlUp
' Capture the F/R data.
For i = 1 To iDataRow
' Skip over empty fields to preserve the underlying cell contents.
If Trim(.Range("A" & i)) <> vbNullString Then
xlFList = xlFList & "|" & Trim(.Range("A" & i))
xlRList = xlRList & "|" & Trim(.Range("B" & i))
End If
Next
End With
.Close False
End With
.Quit
End With
' Release Excel object memory
Set xlWkBk = Nothing: Set xlApp = Nothing
'Exit if there are no data
If xlFList = "" Then Exit Sub
'Process each word from the F/R List
With ActiveDocument.Range.Find
.ClearFormatting
.Replacement.ClearFormatting
.MatchWholeWord = True
.MatchCase = False
.Wrap = wdFindContinue
For i = 1 To UBound(Split(xlFList, "|"))
.Text = Split(xlFList, "|")(i)
.Replacement.Text = Split(xlRList, "|")(i)
.Execute Replace:=wdReplaceAll
Next
End With
Application.ScreenUpdating = True
End Sub
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.