使用Word宏替换Header、Footer等中的文本

简介:
When the Find or Replace utility on the Edit menu is used, it will find or replace text no matter where it appears in the document.  If you record that action however, it will only act on the text in the body of the document and it will have no effect on text that is in the headers or footers of the document, for example, or in a textbox, footnotes, or any other area that is outside the main body of the document.
This is well worth contacting  http://support.microsoft.com/contactus/ about.
To use a macro to find or replace text no matter where it is located in the document, it is necessary to loop through each of the StoryRanges in the document.
There are 11 different types of stories that can be part of a document, corresponding to the following WdStoryType constants: 
wdCommentsStory, wdEndnotesStory, wdEvenPagesFooterStory, wdEvenPagesHeaderStory, wdFirstPageFooterStory, wdFirstPageHeaderStory, wdFootnotesStory, wdMainTextStory, wdPrimaryFooterStory, wdPrimaryHeaderStory, and wdTextFrameStory.
The following code will loop through the first story for each story type in the document, replacing all instances of the text that is to be replaced in the  first story of each type:
Sub FindAndReplaceFirstStoryOfEachType ()

Dim
 myStoryRange  As Range

For Each myStoryRange In ActiveDocument.StoryRanges
     With myStoryRange.Find
        .Text = "findme"
        .Replacement.Text = ""
        .Wrap = wdFindContinue
        .Execute Replace:=wdReplaceAll
     End With
Next myStoryRange

End Sub
(Note for those already familiar with VBA: whereas if you use Selection.Find, you have to specify all of the Find and Replace parameters, such as .Forward = True, because the settings are otherwise taken from the Find and Replace dialog's current settings, which are  sticky , this is not necessary if using [Range].Find – where the parameters use their default values if you don't specify their values in your code).
As mentioned previously, the above code will only act upon the  first story for each story type in the document. (The first Header, the first Text Box, and so on). If your document contains sections with un-linked headers and footers in them, or, for example, contains more than one Text Box, the code will not act upon the second and subsequent occurrences of each type of story. So to make sure that the code does act on each occurrence of the text, no matter where it appears, you have to make use of the NextStoryRange method as in the following code:
Sub FindAndReplaceAllStoriesHopefully ()

Dim 
myStoryRange  As Range

For Each myStoryRange In ActiveDocument.StoryRanges
     With myStoryRange.Find
        .Text = "findme"
        .Replacement.Text = ""
        .Wrap = wdFindContinue
        .Execute Replace:=wdReplaceAll
     End With
     Do While Not (myStoryRange.NextStoryRange Is Nothing)
         Set myStoryRange = myStoryRange.NextStoryRange
         With myStoryRange.Find
            .Text = "findme"
            .Replacement.Text = ""
            .Wrap = wdFindContinue
            .Execute Replace:=wdReplaceAll
         End With
     Loop
Next myStoryRange

Problems with cycling through StoryRanges, and some workarounds

Some Headers can get missed out
Unfortunately, even this method doesn't work reliably if you have any blank Headers or Footers in your document. If, for example, you have a document in which the first section has a blank primary Header in the first section (such as might be the case for a report cover sheet), then  none of the primary Headers in the subsequent sections will be checked! Another thing that is well worth contacting  http://support.microsoft.com/contactus/ about.
One workaround for this is to design all your templates such that none of the Headers are blank – insert a space in any blank Headers. If doing so alters the layout of that section, apply a different style in that Header, so that it doesn't. There is really no other satisfactory workaround, for reasons that will be discussed in a separate article shortly.
Speed of the macro
Another problem with the above code is that it can be very slow if the document is large, or if it contains a large number of story ranges. This is especially a problem in Word 97. In Word 97, using Selection.Find is much faster than using [Range].Find. So you can speed up the above code up very significantly, in Word 97, by using the following instead:
Sub FasterFindAndReplaceAllStoriesHopefully ()

Dim 
myStoryRange  As Range

'First search the main document using the Selection
  With Selection.Find
    .Text = "findme"
    .Replacement.Text = ""
    .Forward = True
    .Wrap = wdFindContinue
    .Format =  False
    .MatchCase =  False
    .MatchWholeWord =  False
    .MatchWildcards =  False
    .MatchSoundsLike =  False
    .MatchAllWordForms =  False
    .Execute Replace:=wdReplaceAll
 End With

'Now search all other stories using Ranges
For Each myStoryRange In ActiveDocument.StoryRanges
    If myStoryRange.StoryType <> wdMainTextStory  Then
         With myStoryRange.Find
            .Text = "findme"
            .Replacement.Text = ""
            .Wrap = wdFindContinue
            .Execute Replace:=wdReplaceAll
         End With
         Do While Not (myStoryRange.NextStoryRange Is Nothing)
            Set myStoryRange = myStoryRange.NextStoryRange
             With myStoryRange.Find
                .Text = "findme"
                .Replacement.Text = ""
                .Wrap = wdFindContinue
                .Execute Replace:=wdReplaceAll
             End With
         Loop
     End If
Next myStoryRange

And the fastest, but flakiest, workaround ...

If you want your code to be  as fast as doing a replace via the user interface, and/or if you want it to be completely immune to the  headers get missed out if the first header is blank  bug, the only solution is to call Word's Find and Replace dialog directly, by executing the menu button (using Word's Dialogs collection doesn't help); and using the SendKeys command to execute it. You can set the dialog's settings the way you want them by using the a With Selection.Find ... End With construct, with no .Execute command, before you execute the menu button. You would need to include DoEvents in your code to allow the command to complete it's search.
But using SendKeys is notoriously flaky, and especially so in this case, because the Find and Replace dialog is modeless; so this is usually  not a good method. It is mentioned here for the sake of completeness.









本文转自 h2appy  51CTO博客,原文链接:http://blog.51cto.com/h2appy/235004,如需转载请自行联系原作者
目录
相关文章
|
7月前
|
前端开发
HTML中的pre标签表示空格或换行
HTML中的pre标签表示空格或换行
273 0
|
4月前
|
JavaScript 前端开发
JS - 正则替换富文本内容的所有图片地址,并提取src、alt、style等属性
这篇文章提供了使用JavaScript正则表达式来替换富文本中所有图片地址,并提取`src`、`alt`、`style`等属性的示例代码和方法。
345 1
|
6月前
|
JavaScript
jquery在光标位置插入内容指定内容(input、textarea)通用
jquery在光标位置插入内容指定内容(input、textarea)通用
42 0
css3 text文本超出单行溢出省略和 css3文本超出两行溢出省略
css3 text文本超出单行溢出省略和 css3文本超出两行溢出省略
68 0
|
JavaScript
js:判断文本溢出隐藏生效text-overflow: ellipsis
js:判断文本溢出隐藏生效text-overflow: ellipsis
314 0
js:判断文本溢出隐藏生效text-overflow: ellipsis
|
前端开发
HTML单行、多行超出不换行显示省略号使用Clamp.js兼容IE
HTML单行、多行超出不换行显示省略号使用Clamp.js兼容IE
179 0
|
开发者
HTML标签 -base标签|学习笔记
快速学习HTML标签 -base标签
HTML标签 -base标签|学习笔记
|
Java
【Java用法】java 8两个List集合取交集、并集、差集、去重并集
【Java用法】java 8两个List集合取交集、并集、差集、去重并集
920 0
|
JavaScript 前端开发
JavaScript用document.write()输出换行
JavaScript用document.write()输出换行
JavaScript用document.write()输出换行
|
前端开发
css3 新属性 text-overflow 实现截取多余文字内容 以省略号来代替多余内容
我们在设计网站的时候有时会遇到这样一个需求:因为页面空间大小的问题,需要将多余的文字隐藏起来,并以省略号代替,类似这样的效果: 做到这样的效果,我们不仅需要运用到css3的新属性 text-overflow ,该属性的作用就是设置一下被隐藏文本的展示形式(例如隐藏文本用……展示),除此之外还需要用到属性 white-space 使文字不换行,以及使用属性 overflow:hidden 隐藏多余的文字 接下来我们就来分步讲解一下这几个属性的应用吧
337 0
css3 新属性 text-overflow 实现截取多余文字内容 以省略号来代替多余内容