View Full Version : Solved: Need help with searching for a style and then inserting column break
janaboo13
07-12-2011, 02:49 PM
Greetings all! It's been a while since I've been doing any coding, but I'm stumped and need help.
I need to search a Word document for a particular style and when found, let the user indicate whether or not they want to insert a column break.
I can get the search part of the code, but I need help with the user input side of things.
Any suggestions?
Many thanks! Jan:banghead:
Frosty
07-14-2011, 12:49 PM
I would be much easier to insert the "right" answer if you posted what you already have. Something along the following lines may be all you need.
'messagebox which defaults to "no"
If MsgBox("Insert a Column Break?", vbQuestion + vbYesNo + vbDefaultButton2, "My Title") = vbYes Then
'insert the column break at your .Found range
End If
Talis
07-14-2011, 12:54 PM
Try this:
Sub StylesParaBreak()
Dim myStyle As String
'Selection.HomeKey Unit:=wdStory 'UNCOMMENT if you always want to start at beginning
myStyle = "Heading 2" 'replace with the desired style
For Each oPara In ActiveDocument.Paragraphs
If oPara.Style = myStyle Then
oPara.Range.Select
Select Case MsgBox("Enter a column break before this paragraph?", vbYesNoCancel, "Break?")
Case 2
GoTo abort
Case 6
With oPara.Range
.Collapse Direction:=wdCollapseStart 'change to wdCollapseEnd if wanted after and modify MsgBox prompt in line above
.InsertBreak Type:=wdColumnBreak
End With
Case 7
GoTo continue
End Select
End If
continue:
Next
abort:
End Sub
I'm assuming that the style in question is a paragraph style and that you want to insert the break before the found style. If not the latter it should be fairly obvious what to change.
janaboo13
07-14-2011, 01:34 PM
Thank you Talis! I'm working on this now and I think this will do it!
Frosty, I know I didn't give you enough info...turns out what I had didn't work anyway...sorry!
Jan
Frosty
07-14-2011, 01:41 PM
Clarification in Talis' code:
Uncommenting the Selection.Homekey line of code will have no effect on a For Each...Loop which iterates through ActiveDocument.Paragraphs. Regardless of where your selection (cursor) is, you will cycle through the paragraphs in the document starting from the first and ending up at the last.
janaboo13
07-14-2011, 02:11 PM
Hi All!
Talis' solution worked great. I have modified the code a bit, however, and need a little more help buttoning it up. We have our docs open to two pages and when I run this macro, I set the view to zoom to page width.
I'd like to reset the view back to two pages when done, and am having brain freeze. Can you help?
Here's the code that I'm using now:
Sub StylesParaBreak()
Dim myStyle As String
ActiveWindow.ActivePane.View.Zoom.PageFit = wdPageFitBestFit
Selection.HomeKey Unit:=wdStory 'UNCOMMENT if you always want to start at beginning
myStyle = "Table Break" 'replace with the desired style
For Each oPara In ActiveDocument.Paragraphs
If oPara.Style = myStyle Then
oPara.Range.Select
Select Case MsgBox("Enter a column break here?", vbYesNoCancel, "Break?")
Case 2
GoTo abort
Case 6
With oPara.Range
.Collapse Direction:=wdCollapseStart 'change to wdCollapseEnd if wanted after and modify MsgBox prompt in line above
.InsertBreak Type:=wdColumnBreak
End With
Case 7
GoTo continue
End Select
End If
continue:
Next
abort:
End Sub
Thanks in advance! Jan
Frosty
07-14-2011, 02:24 PM
Take out
ActiveWindow.ActivePane.View.Zoom.PageFit = wdPageFitBestFit
and
Selection.HomeKey Unit:wdStory
I don't have anything but Word2003 at the moment, so the only options there are:
wdPageFitBestFit
wdPageFitFullPage
wdPageFitNone
wdPageFitTextFit
But this is a good opportunity to learn about the object browser for yourself.
In the VBA IDE, hit F2 (the Object Browser will come up).
Search in <All Libraries> for "PageFit" (which is the property you want to learn about).
You'll see a list come up, and you want to look for what members of the wdPageFit enumeration are... you'll probably see the one you want.
However, the best way to do this (if you still want to change the .PageFit property at the top of your routine to something specific for purposes of selecting the paragraph in the middle of your For Each... Loop), is to store whatever the current .PageFit is before you change it, and then restore it... a la...
Dim lOrigPageFit As WdPageFit
lOrigPageFit = ActiveWindow.View.Zoom.PageFit
ActiveWindow.View.Zoom.PageFit = wdPageFitBestFit
'the rest of your routine
ActiveWindow.View.Zoom.PageFit = lOrigPageFit
Instead of assuming how your user starts the routine, it's better to store whatever it is and then restore it later.
Frosty
07-14-2011, 02:37 PM
Incidentally... depending on the length of the document, a For Each... Loop iterating through all of the paragraphs will be slower than using the .Find object (especially if, for example, there are big, complicated tables in your document).
In my own tests, there is also a flaw in this process if there is an existing column break and you are in a one column section (you'll only see that the paragraph is at the top of a page, but won't know if that's luck or because there is already a column break at the beginning of the range).
Here's an alternative bit of code which basdically works the same way.
Sub SearchForStyleAndAskToInsertColumn()
Dim rngSearch As Range
Dim lOrigPageFit As WdPageFit
'store
lOrigPageFit = ActiveWindow.View.Zoom.PageFit
'change
ActiveWindow.View.Zoom.PageFit = wdPageFitBestFit
'set up our search
Set rngSearch = ActiveDocument.Content
With rngSearch.Find
.Style = "Heading 1"
'while we find it...
Do While .Execute = True
'select
rngSearch.Select
'messagebox which defaults to "no"
Select Case MsgBox("Insert a Column Break?", vbQuestion + vbYesNoCancel + vbDefaultButton2, "My Title")
Case vbYes
rngSearch.Collapse wdCollapseStart
rngSearch.InsertBreak Type:=wdColumnBreak
Case vbNo
'do nothing, but continue our loop
Case vbCancel
'exit our loop
Exit Do
Case Else
Stop
'always good habit to use a Case Else
End Select
Loop
End With
'restore
ActiveWindow.View.Zoom.PageFit = lOrigPageFit
End Sub
Be careful with using Go To frequently, it will occasionally cause you problems if your routines become complex and you haven't thought out exactly every item (i.e., if you put your ActiveWindow.View.Zoom.PageFit = lOrigPageFit in front of your abort: label, if the user hits cancel he/she won't get his original view restored).
You may want to test the beginning of your rngSearch within the find to see if the first character is a column break or not... something along the lines of
'if the first character isn't already a column break then
If rngSearch.Characters.First <> Chr(14)
'collapse the range and insert the column break
End If
Talis
07-14-2011, 11:43 PM
I bow to the far superior knowledge of Frosty.
janaboo13
07-15-2011, 07:23 AM
Hi Frosty!
Thank you so much for some much needed education...I'm getting the hang of using F2! YEAH!
Your solution works great and at the end, the restore works. Now, to throw a little kink into things. I have the following in my AutoOpen macro:
' Change view of window to Print View and set facing pages
With ActiveWindow.View
.Type = wdPrintView
With .Zoom
.PageColumns = 2
.PageRows = 1
End With
End With
My writers want to see two facing pages so they can do necessary copy editing and layout modifications (they are also used to using PageMaker), so I want to make them happy. It would be nice if the restore would take them back to this view...any suggestions???
Again, thank you so much! While on th subject, do you know of any online courses that help folks like me who are just learning VBA?
Jan :friends:
Frosty
07-15-2011, 09:05 AM
I have seen "MindLeaders" as an online resource offered by one of my jobs, but by the time I encountered it, I was a bit ahead of their programming offerings. But it seemed like a good online tutoring program. However, as a (mostly) self-taught programmer who had the occasional mentor help, I think your best resource is simply a combination of patience and desire. And knowing when to ask for help :)
As for your coding question: probably best to encapsulate that functionality, and then call it whenever you want. My sample was simply a "typical" best practice (i.e., leaving things the way you find them). However, each project has different needs. If your users want to have the view 'reset' to the standard view after running the InsertColumns function, I'd suggest doing this:
Public Sub SetMyView
With ActiveWindow.View
.Type = wdPrintView
With .Zoom
.PageColumns = 2
.PageRows = 1
End With
End With
End Sub
And then put "SetMyView" anywhere in the code (AutoOpen, at the end of the InsertColumnBreak routine, etc) you want to run it.
janaboo13
07-15-2011, 01:13 PM
Hi Frosty!
That's what I was leaning toward but wasn't sure how to do that.
Now, I run the macro from a form that calls InsertColumnBreaks macro (using a command button). There are some other things that a user can do to cleanup the document using the same form. When done, the user clicks a Close button and ideally that's when I want the view to return to facing pages. So if that's possible, where should I put the "SetMyView" code?
Here's the code that behind the form:
Dim RemovePages As Boolean
Dim DidColumns As Boolean
Dim SecondRun As Boolean
Private Sub CloseButton_Click()
CleanUp.Hide
End Sub
Private Sub CloseButton_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
End Sub
Private Sub InsertBackCover_Click()
CleanUp.Hide
Application.Run MacroName:="InsertBackCover"
CleanUp.Show
CheckBox10.Value = True
End Sub
Private Sub FixTableBordersButton_Click()
CleanUp.Hide
Application.Run MacroName:="FixTableBorders"
CleanUp.Show
CheckBox4.Value = True
End Sub
Private Sub HelpButton_Click()
CleanUpHelp.Show
End Sub
Private Sub DeleteTableSpacer_Click()
CleanUp.Hide
Call DeleteTableSpacer
CleanUp.Show
CheckBox5.Value = True
End Sub
Private Sub AddColumnBreaks_Click()
'Column Breaks
If DidColumns = True Then
MsgBox "You have already run this procedure."
Else
If RemovePages <> True Then
If ActiveDocument.BuiltInDocumentProperties(wdPropertySubject) = "Russian" Then
GoTo RussianDoc
Else
x = MsgBox("The procedure " & Chr(34) & "Remove Blank Pages/Breaks" & Chr(34) & " removes the column breaks added by this procedure" & Chr(13) & _
"and should be run before this procedure. Would you like to run it now?" & Chr(13) & Chr(13) & _
"Selecting 'Yes' will run both procedures." & Chr(13) & _
"Selecting 'No' will run only this procedure.", vbYesNoCancel)
If x = vbYes Then
CleanUp.Hide
RemovePages = True
Call RemoveBlanks
CheckBox1.Value = True
Call InsertColumnBreaks
DidColumns = True
CleanUp.Show
ElseIf x = vbNo Then
CleanUp.Hide
Call InsertColumnBreaks
DidColumns = True
CleanUp.Show
Else
'Cancel
End If
End If
Else
RussianDoc:
CleanUp.Hide
Call InsertColumnBreaks
DidColumns = True
CleanUp.Show
End If
End If
CheckBox3.Value = True
Call SetMyView
End Sub
Private Sub UpdateAllFields_Click()
CleanUp.Hide
Application.Run MacroName:="UpdateAllFields"
CleanUp.Show
CheckBox9.Value = True
End Sub
Private Sub FixSpaces_Click()
'Don't do for Russian
If ActiveDocument.BuiltInDocumentProperties(wdPropertySubject) = "Russian" Then
MsgBox "This feature is not available for Russian documents."
Else
CleanUp.Hide
Call RemoveSpaces
CleanUp.Show
End If
CheckBox2.Value = True
End Sub
Private Sub RemoveBlankPagesButton_Click()
'Removes blank pages and breaks
'Don't do for Russian
If ActiveDocument.BuiltInDocumentProperties(wdPropertySubject) = "Russian" Then
MsgBox "This feature is not available for Russian documents."
Else
If RemovePages <> True Then
x = MsgBox("This procedure removes blank pages, as well as extra column breaks." & Chr(13) & Chr(13) & _
"Do you wish to run this procedure?", vbYesNo)
If x = vbYes Then
CleanUp.Hide
RemovePages = True
Call RemoveBlanks
CleanUp.Show
Else
'Do nothing
End If
Else
MsgBox "You have already run this procedure."
End If
End If
CheckBox1.Value = True
End Sub
I hope this makes sense. Please let me know if you need something else, ok?
Thanks, again! Jan
Powered by vBulletin® Version 4.2.5 Copyright © 2025 vBulletin Solutions Inc. All rights reserved.