MS Office Forum / Word / Programming / June 2007
Replace using section breaks
|
|
Thread rating:  |
ckxplus@yahoo.com - 13 Jun 2007 08:44 GMT I've got a document with multiple sections. I need to replace any occurrences of 2 consecutive section breaks by a single section break and any isolated section breaks by a page break. This wouldn't be too difficult if Word's search/replace function supported section breaks as the replacement text but it does not. So I need to loop through the text, detect whether a section break is followed by a second section break, and act accordingly. But how can I determine if a section break is followd by a second section break? That's what's got me stumped at this point.
The background of this problem is that I have a series of .rtf files, each with different headers and footers. Some of these .rtf files contain section breaks, others do not. If the file contains a section break then this is to become a page break in the merged document. At present, I'm inserting a double section break between files while merging them in order to distinguish between sections that are to remain sections and sections breaks that are to become page breaks.
Can anyone explain how to detect 2 consecutive section breaks versus 1 isolated section break? Advance thanks for any help,
John Hendrickx
Doug Robbins - Word MVP - 13 Jun 2007 10:14 GMT Why don't you use the information in the artcle "Find & ReplaceAll on a batch of documents in the same folder" at:
http://www.word.mvps.org/FAQs/MacrosVBA/BatchFR.htm
To go through the individual files and replace the Section Breaks with Page Breaks before combining them.
 Signature Hope this helps.
Please reply to the newsgroup unless you wish to avail yourself of my services on a paid consulting basis.
Doug Robbins - Word MVP
> I've got a document with multiple sections. I need to replace any > occurrences of 2 consecutive section breaks by a single section break [quoted text clipped - 18 lines] > > John Hendrickx Russ - 13 Jun 2007 11:33 GMT Doug's idea is a good one.
In the meantime, I played around and got this to work on a test document:
Public Sub Sects() Dim aRange As Word.Range Set aRange = ActiveDocument.Range(0, 0) With aRange.Find .MatchWildcards = True .Text = "([!\^m])^m([!\^m])" .Replacement.Text = "\1^m\2" .Execute replace:=wdReplaceAll .MatchWildcards = False .Text = "^b^b" While .Execute aRange.Characters(2).Delete aRange.SetRange Start:=aRange.End, End:=ActiveDocument.Content.End Wend End With End Sub
> Why don't you use the information in the artcle "Find & ReplaceAll on a > batch of documents in the same folder" at: [quoted text clipped - 25 lines] >> >> John Hendrickx
 Signature Russ
drsmN0SPAMikleAThotmailD0Tcom.INVALID
ckxplus@yahoo.com - 13 Jun 2007 12:39 GMT Hi Russ,
I just tried your idea on a test document, just using the find/replace dialog to test it out. But my version of Word (Word 2000) doesn't seem to be able to handle wildcards and special characters at the same time. Searching for "[!\^m]", "[!^m]" or just "^m" work fine but "([! \^m])^m([!\^m])" is not found. A limitation of Word 2000?
Doug's solution would work although I'd prefer a solution that would leave the original rtf files unchanged. But that would be doable too.
Thanks for the help, John Hendrickx
> Doug's idea is a good one. > [quoted text clipped - 64 lines] > > - Tekst uit oorspronkelijk bericht weergeven - Bear - 13 Jun 2007 16:31 GMT Ckxplus:
Check your work. I used ([!\^m])^m([!\^m]) as a Find argument in a wildcard find and it works just as you'd expect. It locates all instances of a single section break, selecting the character before, the break, and the character after.
As you can see in my signature, I'm also using Word 2000.
Bear
 Signature Windows XP, Word 2000
> Hi Russ, > [quoted text clipped - 78 lines] > > > > - Tekst uit oorspronkelijk bericht weergeven - Russ - 13 Jun 2007 19:11 GMT Sorry to reply late, but I needed some sleep time. I work afternoons.
I should have mentioned, too, that I tested on a document that had only single and double section breaks and that those section breaks were all type 'continuous'.
The macro turns on wildcards when searching for the single breaks, then turns off wildcards when searching for the double breaks. Also you have to use the macro and its loop to change the double ones to single because like you mentioned, it can't be done in the find and replace dialog; it won't let you put a section break ^b in the 'replacement' text field. The macro takes 'advantage' of a quirk, that a ^m will find both a page and section break when in the 'find' text field of the dialog, but replaces with a page break when ^m is in 'replacement' text field.
> Ckxplus: > [quoted text clipped - 90 lines] >>> >>> - Tekst uit oorspronkelijk bericht weergeven -
 Signature Russ
drsmN0SPAMikleAThotmailD0Tcom.INVALID
ckxplus@yahoo.com - 13 Jun 2007 20:59 GMT The problem seems to be that in my document, the single breaks are preceeded and followed by a table. Russ's method *does* work (at home, using Word XP) if the single break is preceded by and followed by text or an end of paragraph mark. Insert a table before and after the single break and presto! Word can't find it anymore. Interesting but rather frustrating as well.
Thanks for the help, John Hendrickx
> Ckxplus: > [quoted text clipped - 92 lines] > > > > - Tekst uit oorspronkelijk bericht weergeven - Russ - 14 Jun 2007 08:16 GMT > The problem seems to be that in my document, the single breaks are > preceeded and followed by a table. John, This subroutine changes all tables to text before searching for section breaks. Will that work for you?
Public Sub Sects() Dim aRange As Word.Range Dim oTable As Word.Table
Application.ScreenUpdating = False For Each oTable In ActiveDocument.Tables oTable.Select Selection.Rows.ConvertToText Separator:=wdSeparateByTabs, _ NestedTables:=True Next oTable Set aRange = ActiveDocument.Range(0, 0) With aRange.Find .MatchWildcards = True .Text = "([!\^m])^m([!\^m])" .Replacement.Text = "\1^m\2" .Execute replace:=wdReplaceAll .MatchWildcards = False .Text = "^b^b" While .Execute aRange.Characters(2).Delete aRange.SetRange Start:=aRange.End, End:=ActiveDocument.Content.End Wend End With Application.ScreenUpdating = True End Sub
> The problem seems to be that in my document, the single breaks are > preceeded and followed by a table. Russ's method *does* work (at home, [quoted text clipped - 104 lines] >> >>>> - Tekst uit oorspronkelijk bericht weergeven -
 Signature Russ
drsmN0SPAMikleAThotmailD0Tcom.INVALID
ckxplus@yahoo.com - 14 Jun 2007 09:09 GMT Hello Russ,
Thanks for going through all the trouble but no, the tables mustn't be modified. Your code could be modified to insert an empty paragraph before and after each table. The replace function would work then and the extra paragraphs could be deleted afterwards. But I think Doug's solution, to replace any section breaks in the individual input files with page breaks and then merge the files, is probably the best solution.
Thanks, John Hendrickx
> > The problem seems to be that in my document, the single breaks are > > preceeded and followed by a table. [quoted text clipped - 144 lines] > > - Tekst uit oorspronkelijk bericht weergeven - ckxplus@yahoo.com - 19 Jun 2007 08:32 GMT A followup on my own posting: this problem is documented in knowledge base article 94130 (see http://support.microsoft.com/kb/94130). It turns out that Word cannot replace a section break followed by a table and this is apparently true for versions from "Word 1.0 Standard Edition" to "Word 2003". This means that Doug's solution won't work either, not without inserting an empty paragraph above each table. Sigh.
John Hendrickx
On 13 jun, 21:59, "ckxp...@yahoo.com" <ckxp...@yahoo.com> wrote:
> The problem seems to be that in my document, the single breaks are > preceeded and followed by a table. Russ's method *does* work (at home, [quoted text clipped - 104 lines] > > - Tekst uit oorspronkelijk bericht weergeven - Russ - 19 Jun 2007 10:45 GMT John, This may be as close as you can get, since a pagebreak cannot be immediately before a table. Building upon the discussion so far, this macro will insert a paragraph mark before and after each table. Then it will do the search and replace for single and double section breaks. Next it will remove all the extra paragraph marks before each table, if there are two paragraph marks in a row, before the table. Finally it removes the extra paragraph mark after each table. Public Sub Sects() Dim aRange As Word.Range Dim oTable As Word.Table
Application.ScreenUpdating = False For Each oTable In ActiveDocument.Tables oTable.Range.InsertBreak Type:=wdColumnBreak oTable.Range.Next.InsertBefore vbCr Next oTable Set aRange = ActiveDocument.Range(0, 0) With aRange.Find .MatchWildcards = True .Text = "([!\^m])^m([!\^m])" .Replacement.Text = "\1^m\2" .Execute Replace:=wdReplaceAll .MatchWildcards = False .Text = "^b^b" While .Execute aRange.Characters(2).Delete aRange.SetRange Start:=aRange.End, _ End:=ActiveDocument.Content.End Wend End With For Each oTable In ActiveDocument.Tables If oTable.Range.Previous & oTable.Range.Previous.Previous _ = vbCr & vbCr Then oTable.Range.Previous.Delete End If oTable.Range.Next.Delete Next oTable Application.ScreenUpdating = True End Sub
> A followup on my own posting: this problem is documented in knowledge > base article 94130 (see http://support.microsoft.com/kb/94130). It [quoted text clipped - 118 lines] >> >> - Tekst uit oorspronkelijk bericht weergeven -
 Signature Russ
drsmN0SPAMikleAThotmailD0Tcom.INVALID
ckxplus@yahoo.com - 19 Jun 2007 15:27 GMT Hi Russ,
Thanks very much once again for your help. Your solution didn't work as is on my document but it pointed me in the right direction for *a* solution.
Apparently, searching for and replacing break characters around tables is asking for trouble. The first problem (of today) was that your method of searching "([!\^m])^m([!\^m])" and replacing it by "\1^m\2" works, provided "\2" is some character. If "\2" is a paragraph then the search string is found but it isn't replaced. So I chose to insert text in the paragraph above each table and that solves this problem.
But inserting a paragraph with text creates headaches of its own. The first solution I tried was to replace "\\Delete this text!\\^p" with "", deleting the paragraph. But that doesn't work, the find string is found but it is not replaced. So I modified your macro to extract the text of the paragraph above each table and to delete it if the contents were right. This was complicated by the fact that if the text was preceeded by a pagebreak then the pagebreak was included in the text found (at least using the method I used).
In any case, here's your macro with the modifications I made. It seems to work for me but I'll have to check it carefully before I can be totally sure. Thanks once again for the help!
' This macro replaces single section breaks by a page break ' and double section breaks by a single section break ' ' This is complicated by the fact a section break (^b) will not be found by ' search/replace if it is preceeded by or followed by a Word table. ' The macro therefore inserts a paragraph with text above and an empty paragraph ' below each Word table in the document. ' ' The next step is to replace single section breaks by a page break. This is done ' using a search/replace with wildcards. Search/replace with wildcards does not ' allow the section break character ^b to be specified in the find string. A ' workaround is to use ^m in both the find and replace strings. The find string ' consists of any non-break character, followed by a break character, followed ' by a non-break character. The break character will find either a section break ' or a page break. The find string is replaced by the first non-break character ' followed by a page break followed by the second non-break character. ' ' However, this workaround will *not* work if the paragraph following the section ' break is empty. In that case, the section break is found but is not replaced ' by a page break. This is the reason a paragraph with text was inserted above ' each table. ' ' Once the single section breaks have been replaced by page breaks, the double ' section breaks can be replaced by single section breaks. ' ' The last step is to cleanup. The paragraph with text and the empty paragraph ' must be deleted. Here again there is a complication. If the paragraph above a ' table is preceeded by a section break then its text is returned as "text" plus ' a paragraph mark. If the paragraph is preceeded by a page break, then its ' text included that page break as a form feed character (chr(12)). ' ' The workaround is therefore to test for both conditions. The empty paragraph ' below each table can be deleted without any further trouble. ' ' Note that a search/replace for "\/\\This text is to be deleted!!\/\ \^p" with ' an empty replacement string will not work. The text will be found but it will ' not be deleted. Public Sub Sects() Dim aRange As Word.Range Dim oTable As Word.Table
Application.ScreenUpdating = False
'Insert a paragraph with text above and an empty paragraph below 'each table in the document For Each oTable In ActiveDocument.Tables oTable.Range.InsertBreak Type:=wdColumnBreak oTable.Range.Previous.InsertBefore "\\Delete this text!\\" oTable.Range.Next.InsertBefore vbCr Next oTable
Set aRange = ActiveDocument.Range(0, 0) With aRange.find .MatchWildcards = True .Text = "([!\^m])^m([!\^m])" 'character1 -- page/section break -- character2 .Replacement.Text = "\1^m\2" 'character1 -- page break -- character2 .Execute replace:=wdReplaceAll .MatchWildcards = False .Text = "^b^b" 'two consecutive section breaks While .Execute aRange.Characters(2).Delete aRange.SetRange Start:=aRange.End, _ End:=ActiveDocument.Content.End Wend End With
'Delete the paragraph with text and the empty paragraph inserted above For Each oTable In ActiveDocument.Tables If oTable.Range.Paragraphs(1).Previous.Range.Text = "\\Delete this text!\\" & vbCr Then oTable.Range.Previous.Paragraphs(1).Range.Delete ElseIf oTable.Range.Paragraphs(1).Previous.Range.Text = vbFormFeed & "\\Delete this text!\\" & vbCr Then oTable.Range.Previous.Paragraphs(1).Range.Delete oTable.Range.InsertBreak Type:=wdPageBreak End If oTable.Range.Next.Delete Next oTable Application.ScreenUpdating = True End Sub
John Hendrickx
> John, > This may be as close as you can get, since a pagebreak cannot be [quoted text clipped - 169 lines] > > - Tekst uit oorspronkelijk bericht weergeven - Russ - 19 Jun 2007 18:42 GMT Hey John, You're welcome for the help, it was a learning experience. As I mentioned in the first sentence of my previous post, you can't insert normal pagebreak immediately before a table because it just disappears automatically. But I did discover that you can insert a section break of type (Next Page) and that will work, although it will increase the section count.
> Hi Russ, > [quoted text clipped - 307 lines] >> >> - Tekst uit oorspronkelijk bericht weergeven -
 Signature Russ
drsmN0SPAMikleAThotmailD0Tcom.INVALID
Russ - 13 Jun 2007 19:24 GMT > but "([!> \^m])^m([!\^m])" is not found. > A limitation of Word 2000? It looks like you have an extra, unwanted > character and space together in the first parentheses group.
 Signature Russ
drsmN0SPAMikleAThotmailD0Tcom.INVALID
Russ - 13 Jun 2007 19:27 GMT Disregard last post, the extra characters were an artifact from copy and pasting the lines below and joining them back together.
> but "([! > \^m])^m([!\^m])" is not found. A limitation of Word 2000?
 Signature Russ
drsmN0SPAMikleAThotmailD0Tcom.INVALID
|
|
|