PDA

View Full Version : Solved: Find and Replace in Footer



GMan
11-22-2005, 11:17 AM
I have a report to be created in word. I have used the find and replace to make most of the monthly updates that need to be made but have noticed that when completing a replace with wdReplaceAll the changes are not made to the footer. How can I do a find and replace that will also update the footer as well as the document (or, at least some code to complete a find and replace in the footer).

Thanks!

fumei
11-22-2005, 04:03 PM
First off, the footers are in another "story", and the basic find and replace only works in individual stories.

We need a little more detail.

WHAT is being replaced? I will assume since you describe it as a find and replace that you are working with plain text. You may want to consider using fields of some kind. This makes updates (generally speaking) much easier.

Are there many places for this? Are any of them identical values? The reason I ask is that, for example, say you have "January" in a number of places, and you want to change them to "February". It would be easier to have ONE "January", and all the others take their values from that one. Then all you need is to update that one to "February", and all the other update, taking the values from the first one.

There is, of course, code that will do find and replace in the header/footer. However, would be good to find out exactly what you have happening.

GMan
11-23-2005, 07:01 AM
Well, I am glad that this isn't a case where I just couldn't find the method. Coming from a mainframe system and teaching myself VBA on the fly is a bit of a challenge. Lets just say there is a lot of trial and error (especially the error part).

The footer is nothing complexed, it is located in Section 2 of the document and is the same throughout. I am using a shell word document to create the report each month. The update is to change the string "[MMMM yyyy]" with the previous month with year. For example, if I was to run this now, I would expect "October 2005" to replace "[MMMM yyyy]". This will only need to be replaced in one place.

I am not sure if this will have much affect on any solution but the change is in the first line of the footer and would read similar to "Status Report - [MMMM yyyy]"

EricFletcher
11-24-2005, 10:45 AM
... The footer is nothing complexed, it is located in Section 2 of the document and is the same throughout. I am using a shell word document to create the report each month. The update is to change the string "[MMMM yyyy]" with the previous month with year. For example, if I was to run this now, I would expect "October 2005" to replace "[MMMM yyyy]". This will only need to be replaced in one place. ..."

I'd go with Fumei's suggestion for this one and use fields in the footer. An easy way to do it is to use one of the built-in fields in Document Properties (File menu). For example, if you type "October 2005" in the Subject field in the Properties dialog, and then include a { Subject } field in the footer, it gets displayed the way you want it. Change the Subject in the dialog and the field in the footer changes with it. [Note: you can insert the field via the Insert | Field dialog, or type it in, select it and press Ctrl-F9. The braces shown here will be automatically applied by Word; you cannot (and should not) type them in.]

You can use any of the built-in fields or create your own (last tab of the dialog box) and any can be modified from either the dialog or VBA. I find that fields frequently offer an easier solution than VBA -- yet the feature is commonly overlooked.

fumei
11-25-2005, 06:40 AM
Fields are good.

here is a VBA solution though. This replaces (in my example) the text "January" with "February" through all existing footers - including ones that have not had text set for them.
Sub FooterDates()
Dim oSection As Word.Section
Dim oRange As Word.Range
Dim var
For Each oSection In ActiveDocument.Sections()
For var = 1 To 3
Set oRange = oSection.Footers(var).Range
oRange.Find.Execute FindText:="January", _
ReplaceWith:="February", Replace:=wdReplaceAll
Set oRange = Nothing
Next
Next
End Sub

EricFletcher
11-25-2005, 11:30 AM
Very slick Gerry! Your code sometimes seems so far away from what gets recorded, it looks like a different language altogether...

It also shows me that I need to find a big chunk of time to learn more about VBA -- and in particular the range concept. So far, that's been a very foggy area for me, but from testing this little macro, I can see it is MUCH more efficient than what I'd get if I tried to modify recorded code!

fumei
11-25-2005, 12:05 PM
Absolutely,it IS almost like a different language. This comes only from really looking at the object model, from using the object model.

I have never understood why the recorder goes through such contortions, but it does. For one thing it ALWAYS uses the Selection object...which does in fact make sense. It is not going to create objects for you.

If you want to write slick and efficient code for Word VBA you must grasp the object model for the basic elements of what makes up a Word document. In particular, these three:

Range - and everything associated with it
Paragraph - and everything associated with it
Section - and everything associated with it

It is impossible to work efficiently without them.

fumei
11-25-2005, 12:39 PM
I might add this - HeaderFooters are a great start to getting a grasp of the weird and wonderful aspects of the Word object model. In particular using Range with them. That way you avoid all the crap involved with the macro recorder - like this:
If ActiveWindow.View.SplitSpecial <> wdPaneNone Then
ActiveWindow.Panes(2).Close
End If
If ActiveWindow.ActivePane.View.Type = wdNormalView Or ActiveWindow. _
ActivePane.View.Type = wdOutlineView Then
ActiveWindow.ActivePane.View.Type = wdPrintView
End If
ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageHeader
If Selection.HeaderFooter.IsHeader = True Then
ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageFooter
Else
ActiveWindow.ActivePane.View.SeekView = wdSeekCurrentPageHeader
End If
The above comes the macro recorder, which uses the Selection object and actually opens the headerfooter window. It has to.

My code (previous post) never uses the headerfooter window, so never has to go through all the junk in the code above. It uses the header or footer OBJECT.

Actually, it does not even use that - it uses a Range of each Section footer. So it does not have to use the footer object.

Confused? It takes a while.

EricFletcher
11-25-2005, 01:20 PM
Very helpful info Gerry... But of course, now you've made it almost impossible for me to kick back and relax tonight! As if I needed more work... ;-)

GMan
11-29-2005, 08:58 AM
Well, this has made for some very interesting reading material now that I have returned to work after the Holiday. Thank you for the help Gerry. Also, Eric thanks for sparking the interesting conversation. I also have some work to do with this new information. Thanks again for the help and guidance!