Macro to toggle page borders

H

Heather Mills

I want to write a macro to toggle the page borders on and off.

I recorded the code for turning them on and off and after some
fiddling, came up with the code below. It seems to work, but I have a
few questions and would appreciate any suggestions for improvements.

I ended up with three macros. The main macro queries whether borders
are on or not and then calls one to turn them on or off.


'=========================================================
' Main Macro

' Query the borders, then call the on or off macro.
'=========================================================
Sub MyPageBorderToggle()
With Selection.Sections(1) (1)
If .Borders(wdBorderLeft).LineStyle Or _ (2)
.Borders(wdBorderRight).LineStyle Or _
.Borders(wdBorderTop).LineStyle Or _
.Borders(wdBorderBottom).LineStyle Then 'If any border is on,
Call MyPageBorderToggleOff 'Turn them all off.
MsgBox "Page borders off"
Else 'If they are all off,
Call MyPageBorderToggleOn 'Turn them all on.
MsgBox "Page borders on"
End If
End With
End Sub

Questions:

1. Is the Selection.Sections(1) the right code? I'm setting a *page*
border, not a *paragraph* border.

2. Is ".borders.linestyle" the right setting to test?



'=========================================================
' Macro to Turn Page Borders Off
'=========================================================
Sub MyPageBorderToggleOff()
With Selection.Sections(1) (1)
.Borders(wdBorderLeft).LineStyle = wdLineStyleNone
.Borders(wdBorderRight).LineStyle = wdLineStyleNone
.Borders(wdBorderTop).LineStyle = wdLineStyleNone
.Borders(wdBorderBottom).LineStyle = wdLineStyleNone
End With
End Sub

Questions:

1. Apparently, the selection is not passed to the subroutine, so I
need to do the Selection.Sections(1) again, right?

2. Is there anything else I need to do?



'=========================================================
' Macro to Turn Page Borders On
'=========================================================
Sub MyPageBorderToggleOn()
With Selection.Sections(1)

' This code was at the end in the recorded macro (1)
With Options
' .DefaultBorderLineStyle = wdLineStyleSingle (2)
.DefaultBorderLineWidth = wdLineWidth100pt
.DefaultBorderColor = wdColorAutomatic
End With

' Turn on each edge individually. (3)
With .Borders(wdBorderLeft)
.LineStyle = wdLineStyleSingle
' .LineWidth = wdLineWidth025pt (4)
' .Color = wdColorAutomatic
End With
With .Borders(wdBorderRight)
.LineStyle = wdLineStyleSingle
' .LineWidth = wdLineWidth025pt
' .Color = wdColorAutomatic
End With
With .Borders(wdBorderTop)
.LineStyle = wdLineStyleSingle
' .LineWidth = wdLineWidth025pt
' .Color = wdColorAutomatic
End With
With .Borders(wdBorderBottom)
.LineStyle = wdLineStyleSingle
' .LineWidth = wdLineWidth025pt
' .Color = wdColorAutomatic
End With

' Relate it to the text, not the page.
' This must be done last. (5)
With .Borders
.DistanceFrom = wdBorderDistanceFromText
' .AlwaysInFront = True (6)
' .SurroundHeader = True
' .SurroundFooter = True
' .JoinBorders = False
.DistanceFromTop = 0
.DistanceFromLeft = 0
.DistanceFromBottom = 0
.DistanceFromRight = 0
' .Shadow = False
' .EnableFirstPageInSection = True
' .EnableOtherPagesInSection = True
' .ApplyPageBordersToAllSections
End With

End With

End Sub

Questions:

1. The With Options code was at the end of the recorded macro. I moved
it to the top, which allowed me to eliminate the LineWidth and Color
statements. Any reason this had to be at the end?

2. The LineStyle statement seems redundant, since I have to do it for
each edge. I tried eliminating that and it failed.

3. I assume there is no "Box" group that will set all 4 edges with one
commend...

4. I eliminated these statements, because they are in the With Options
code above. Any problem with that?

5. I tried moving this to the top, but BorderDistanceFromText didn't
stick.

6. I eliminated a bunch of state,ments that didn't seem to make any
difference for what I'm doing. Any problems with this?
 
J

Jay Freedman

'========================
' Main Macro

1. Is the Selection.Sections(1) the right code? I'm setting a *page* border, not a *paragraph* border.

It is the right code for this specific task. If you wanted to affect more than one section, up to the entire document, you would have to use a loop to change the borders in each such section.

In the VBA editor, click on the word Borders and press F1; in the Help topic, look at the "Applies to" information. Each of those things (table cells, frames, paragraphs, sections, etc.) has its own
Borders collection, and you choose which one you want to work with.
2. Is ".borders.linestyle" the right setting to test?

Yes -- maybe. Switching the line style between None and Single is certainly effective, and in that case you should test the value of the current .LineStyle. Another way to achieve the same effect
would be to set up the borders the way you want them (line style, width, distance from text) and just switch each border's .Visible property between True and False; in that case you would test the
value of the current .Visible.
'========================
' Macro to Turn Page Borders Off

1. Apparently, the selection is not passed to the subroutine, so I need to do the Selection.Sections(1) again, right?

Yes, as long as each of the three macros works on Selection.Sections(1). If the main macro was modified to loop through multiple sections, then you would want to pass the current section as a
parameter to the other two macros. Incomplete sample code to work on an entire document:

Sub MyPageBorderToggle()
Dim mySection As Section
For Each mySection in ActiveDocument.Sections
With mySection
If .Borders(wdBorderLeft).LineStyle Or _
' etc.
Then
MyPageBorderToggleOff whichSection:=mySection
MsgBox ...
Else
MyPageBorderToggleOn whichSection:=mySection
MsgBox ...
End If
End With
Next mySection
End Sub

Sub MyPageBorderToggleOff(whichSection As Section)
With whichSection
.Borders(wdBorderLeft).LineStyle = wdLineStyleNone
' etc.
End With
End Sub

Sub MyPageBorderToggleOn(whichSection As Section)
With whichSection
' etc.
End With
End Sub
2. Is there anything else I need to do?

No, but see the comment above, about using the .Visible property.
'========================
' Macro to Turn Page Borders On

1. The With Options code was at the end of the recorded macro. I moved it to the top, which allowed me to eliminate the LineWidth and Color statements. Any reason this had to be at the end?

No, it's OK to move it. In fact, it would be better to move it up one more line, above the With Selection.Sections(1) statement. The Options object belongs to the entire Word application, not just to
that one section, so VBA ignores the Selection.Sections(1) statement when it executes the With Options statement. (In other words, there's no difference in how the macro executes, but it's
inefficient.)
2. The LineStyle statement seems redundant, since I have to do it for each edge. I tried eliminating that and it failed.

This seems to be a quirk in the way VBA works. Sometimes you just have to find these things by trial and error.
3. I assume there is no "Box" group that will set all 4 edges with one commend...

In theory, you could toggle the value of Selection.Sections(1).Borders.Enable between True and False. In testing this theory, I found that it turned on and off the borders in all sections of a
multi-section document, even though I addressed a specific section. Again, VBA doesn't always behave as expected or as documented.
4. I eliminated these statements, because they are in the With Options code above. Any problem with that?

No, that's fine. The macro recorder acts "stupid" about certain things. I wrote this up in http://www.word.mvps.org/FAQs/MacrosVBA/ModifyRecordedMacro.htm.
5. I tried moving this to the top, but BorderDistanceFromText didn't stick.

More VBA oddness. Only experiment and experience can tell you what works and what doesn't.
6. I eliminated a bunch of statements that didn't seem to make any difference for what I'm doing. Any problems with this?

As in question 4, no problem. When you record the use of a dialog that sets values, the macro recorder just dumps everything from the dialog into the code, even if you only changed one value. Take
what you need and delete the rest.
 
H

Heather Mills

It is the right code for this specific task. If you wanted to affect more than one section, up to the entire document, you would have to use a loop to change the borders in each such section.

In the VBA editor, click on the word Borders and press F1; in the Help topic, look at the "Applies to" information. Each of those things (table cells, frames, paragraphs, sections, etc.) has its own
Borders collection, and you choose which one you want to work with.


Yes -- maybe. Switching the line style between None and Single is certainly effective, and in that case you should test the value of the current .LineStyle. Another way to achieve the same effect
would be to set up the borders the way you want them (line style, width, distance from text) and just switch each border's .Visible property between True and False; in that case you would test the
value of the current .Visible.


Yes, as long as each of the three macros works on Selection.Sections(1). If the main macro was modified to loop through multiple sections, then you would want to pass the current section as a
parameter to the other two macros. Incomplete sample code to work on an entire document:

Sub MyPageBorderToggle()
Dim mySection As Section
For Each mySection in ActiveDocument.Sections
With mySection
If .Borders(wdBorderLeft).LineStyle Or _
' etc.
Then
MyPageBorderToggleOff whichSection:=mySection
MsgBox ...
Else
MyPageBorderToggleOn whichSection:=mySection
MsgBox ...
End If
End With
Next mySection
End Sub

Sub MyPageBorderToggleOff(whichSection As Section)
With whichSection
.Borders(wdBorderLeft).LineStyle = wdLineStyleNone
' etc.
End With
End Sub

Sub MyPageBorderToggleOn(whichSection As Section)
With whichSection
' etc.
End With
End Sub


No, but see the comment above, about using the .Visible property.


No, it's OK to move it. In fact, it would be better to move it up one more line, above the With Selection.Sections(1) statement. The Options object belongs to the entire Word application, not just to
that one section, so VBA ignores the Selection.Sections(1) statement when it executes the With Options statement. (In other words, there's no difference in how the macro executes, but it's
inefficient.)


This seems to be a quirk in the way VBA works. Sometimes you just have to find these things by trial and error.


In theory, you could toggle the value of Selection.Sections(1).Borders.Enable between True and False. In testing this theory, I found that it turned on and off the borders in all sections of a
multi-section document, even though I addressed a specific section. Again, VBA doesn't always behave as expected or as documented.


No, that's fine. The macro recorder acts "stupid" about certain things. I wrote this up in http://www.word.mvps.org/FAQs/MacrosVBA/ModifyRecordedMacro.htm.


More VBA oddness. Only experiment and experience can tell you what works and what doesn't.


As in question 4, no problem. When you record the use of a dialog that sets values, the macro recorder just dumps everything from the dialog into the code, even if you only changed one value. Take
what you need and delete the rest.

Thank you very much. Now I have some experimenting to do.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top