【发布时间】:2012-03-01 16:41:05
【问题描述】:
经过一些实验后,我最终使用以下代码在 MSWord 中执行搜索和替换。此代码在页眉和页脚中也能完美运行,包括首页或奇数/偶数页的页眉和/或页脚不同的情况。
问题是我需要为我替换的每个字符串调用MSWordSearchAndReplaceInAllDocumentParts,并且我得到了一个不可接受的性能(4 页文档单词中大约 50 个字符串需要 2 分钟)。理想情况下,它当然应该是“即时的”。
在处理页眉和页脚之前,我只是在主文档中进行搜索和替换(使用 wdSeekMainDocument)。在那种情况下,性能是可以接受的(即使很慢)。我只是想知道为什么这么慢:切换视图需要时间吗?通常页眉或页脚包含很少的单词,所以我预计页眉和页脚中的所有搜索和替换不会使整体性能变得如此糟糕。但这不是我观察到的。
这是代码,在底部我放了探查器结果:
// global variable (just for convenience of posting to Stack Overflow)
var
aWordApp: OLEVariant; // global
// This is the function that is executed once per every string I replace
function MSWordSearchAndReplaceInAllDocumentParts;
begin
try
iseekValue := aWordApp.ActiveWindow.ActivePane.View.SeekView;
iViewType := aWordApp.ActiveWindow.ActivePane.View.Type;
if iViewType <> wdPrintView then
aWordApp.ActiveWindow.ActivePane.View.Type := wdPrintView;
if aWordApp.ActiveDocument.PageSetup.OddAndEvenPagesHeaderFooter then
begin
Try
aWordApp.ActiveWindow.ActivePane.View.SeekView := wdSeekEvenPagesFooter;
SearchAndReplaceInADocumentPart;
Except
// do nothing ..it was not able to set above view
end;
Try
aWordApp.ActiveWindow.ActivePane.View.SeekView := wdSeekEvenPagesHeader;
SearchAndReplaceInADocumentPart;
Except
// do nothing ..it was not able to set above view
end;
end;
if aWordApp.ActiveDocument.PageSetup.DifferentFirstPageHeaderFooter then
begin
Try
aWordApp.ActiveWindow.ActivePane.View.SeekView := wdSeekFirstPageFooter;
SearchAndReplaceInADocumentPart;
Except
// do nothing ..it was not able to set above view
end;
Try
aWordApp.ActiveWindow.ActivePane.View.SeekView := wdSeekFirstPageHeader;
SearchAndReplaceInADocumentPart;
Except
// do nothing ..it was not able to set above view
end;
end;
//Replace in Main Docpart
Try
aWordApp.ActiveWindow.ActivePane.View.SeekView := wdSeekMainDocument;
SearchAndReplaceInADocumentPart;
Except
// do nothing ..it was not able to set above view
end;
//Replace in Header
Try
aWordApp.ActiveWindow.ActivePane.View.SeekView := wdSeekCurrentPageHeader;
SearchAndReplaceInADocumentPart;
Except
// do nothing ..it was not able to set above view
end;
//Replace in Footer
Try
aWordApp.ActiveWindow.ActivePane.View.SeekView := wdSeekCurrentPageFooter;
SearchAndReplaceInADocumentPart;
Except
// do nothing ..it was not able to set above view
end;
//Replace in Header
Try
aWordApp.ActiveWindow.ActivePane.View.SeekView := wdSeekPrimaryHeader;
SearchAndReplaceInADocumentPart;
Except
// do nothing ..it was not able to set above view
end;
//Replace in Footer
Try
aWordApp.ActiveWindow.ActivePane.View.SeekView := wdSeekPrimaryFooter;
SearchAndReplaceInADocumentPart;
Except
// do nothing ..it was not able to set above view
end;
finally
aWordApp.ActiveWindow.ActivePane.View.SeekView := iseekValue;
if iViewType <> wdPrintView then
aWordApp.ActiveWindow.ActivePane.View.Type := iViewType;
end;
end;
// This is the function that performs Search And Replace in the selected View
// it is called once per view
function SearchAndReplaceInADocumentPart;
begin
aWordApp.Selection.Find.ClearFormatting;
aWordApp.Selection.Find.Text := aSearchString;
aWordApp.Selection.Find.Replacement.Text := aReplaceString;
aWordApp.Selection.Find.Forward := True;
aWordApp.Selection.Find.MatchAllWordForms := False;
aWordApp.Selection.Find.MatchCase := True;
aWordApp.Selection.Find.MatchWildcards := False;
aWordApp.Selection.Find.MatchSoundsLike := False;
aWordApp.Selection.Find.MatchWholeWord := False;
aWordApp.Selection.Find.MatchFuzzy := False;
aWordApp.Selection.Find.Wrap := wdFindContinue;
aWordApp.Selection.Find.Format := False;
{ Perform the search}
aWordApp.Selection.Find.Execute(Replace := wdReplaceAll);
end;
我在这里粘贴分析结果(我有 aqtime pro):
你能帮我找出问题吗?
【问题讨论】:
-
如果您真的需要性能,那么通过 OLE/ActiveX 使用 Word 基本上不会削减它...是否使用库(不依赖 Word)来处理 Word 文档?
-
如果你能提供一个合适的样本文档来进行基准测试会更好。
-
您能否详细说明分析结果:是以秒还是毫秒为单位的时间,是每次点击的时间还是所有点击的累积时间?
-
@The_Fox 以秒为单位,这是替换后发生的情况。在那种情况下,实际上我调用了该函数 153 次,所以我替换了 150 个不同的单词(在普通数据库中是 50,然后如果用户添加自定义字段,数字会增加)。
-
@Yahia 是的,我同意这个方法足够快,直到我添加了页眉和页脚的替换。我主要担心的是,添加页眉和页脚替换似乎会变得慢得多,就像在进行搜索和替换时解析完整文档并且活动视图仅是页眉一样。
标签: delphi activex word-automation