Using VBA to Set Multiple Styles in the Footer in Word - vba

I am new to VBA in Word with some experience in Excel. I am trying to produce a Word document from an Excel file. The first task is to set up the headers and footers, which I am struggling with. For context, I have added the reference to Word in Excel and will likely convert to late-binding at a later date because this is a tool I will distribute to peers. The goal of this macro is to generate a document with data that matches a report format, so the formatting is not my choice; I have to match it as the Word template is set up. At this point I am not using late binding so that I can use Intellisense while I learn this.
Requirements for the footer:
Centered text, Arial, size 8: "Page " and then an automatically generated page number.
Right-aligned text, Arial, size 8, bold: "Other Support Page"
A top line border for the entire footer.
What I want:
I can get most of this to function except it's either entirely bold or entirely not bold. I have looked into using "Collapse 0", however, it screws up the top border. Also, I have tried to use style objects to lower the amount of code, but it then wipes out the default tab stops. I am struggling to add the tab stops back into the footer (center 3.25" and right 6.5"). I have no problem adding tab stops in the body, but for some reason the code executes but does nothing with the tab stops when I try and put them in the footer. First try here has it set up correctly, but bolds the entire thing:
With rngFooter
.Font.Name = "Arial"
.Font.Size = "8"
.Fields.Add rngFooter, wdFieldPage, , False
.InsertBefore vbTab & "Page "
.Font.Bold = True
.InsertAfter vbTab & "Other Support Page"
With rngFooter.Borders(wdBorderTop)
.LineStyle = wdLineStyleSingle
.LineWidth = wdLineWidth075pt
.Color = Options.DefaultBorderColor
End With
End With
I have read about moving styles until after the text you want to format. So if I were to use the styles I have created, the tab stops get wiped out and the formatting isn't right anyways (the "b" in the style name means it is set to bold):
With rngFooter
.Fields.Add rngFooter, wdFieldPage, , False
.InsertBefore vbTab & "Page "
.Style = A8
.InsertAfter vbTab & "Other Support Page"
.Style = AB8
With rngFooter.Borders(wdBorderTop)
.LineStyle = wdLineStyleSingle
.LineWidth = wdLineWidth075pt
.Color = Options.DefaultBorderColor
End With
End With
If I add the collapse in, it screws up the borders.
With rngFooter
.Fields.Add rngFooter, wdFieldPage, , False
.InsertBefore vbTab & "Page "
.Style = A8
.Collapse 0
.InsertAfter vbTab & "Other Support Page"
.Style = AB8
With rngFooter.Borders(wdBorderTop)
.LineStyle = wdLineStyleSingle
.LineWidth = wdLineWidth075pt
.Color = Options.DefaultBorderColor
End With
End With
I really want to understand how to do this properly because I will also be trying to change styles mid-way through table cells. I find the documentation on how ranges work to be confusing, but I do understand that the point of the collapse is to prevent it from overwriting the entire footer, which is what I was doing before. I just can't see how I can do the collapse and then also apply the top-line border to the whole footer. I have to put it in at the end also or it interferes with the page number.

Thank you Timothy Rylatt for the pointers to alignment tabs and character styling. I was able to avoid tables and generating a template file (which would be a lot more work as I need to distribute this Excel file to many users). My solution is as follows:
With rngFooter
.Style = A8
.InsertAlignmentTab 1, 0
.InsertAlignmentTab 2, 0
.Fields.Add rngFooter, wdFieldPage, , False
.InsertBefore vbTab & "Page "
.InsertAfter vbTab & "Other Support Page"
End With
' Make "Other Support Page" bold
With rngFooter.Find
.ClearFormatting
.Text = "Other Support Page"
.Replacement.ClearFormatting
.Replacement.Style = AB8
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceOne
End With
'Add border to entire footer
With rngFooter
.Expand Unit:=wdParagraph
With .Borders(wdBorderTop)
.LineStyle = wdLineStyleSingle
.LineWidth = wdLineWidth075pt
.Color = Options.DefaultBorderColor
End With
End With
Essentially I applied the base style (now a character style and not a paragraph style), then inserted the alignment tabs as the base tab stops from the Normal template were wiped out. I then add the page number, then the "Page " text, then the "Other Support Page" text. I do a find and replace on the specific expression to format, and apply a character style to ensure it doesn't expand the formatting to the full paragraph. The border issue is fixed by using .Expand on the range prior to applying the border. Order of operations was very important to making this work.
For me, the documentation on the Word object model is more confusing than Excel is, and I appreciate the specific topics to research. I also used this StackOverflow answer for the tip on using find and replace to change the styles, which worked once they were converted to Character Styles.

Do not use tabs for alignment because they are part of the paragraph and a paragraph can only have one style without some trickery.
By far the easiest way to get what you want is to follow this procedure which can be applied to either headers or footers
Insert a 1 row, 3 column table to get left, center and righgt 'fields'
Turn off the table borders
Insert the relevant text into each cell
Set the formatting of paragraph(1) of each cell
If required, turn on the bottom border of the Header Table and or the Top border of the Footer table.
If stuck for vertical space you might need to set the font hieght of the compulsory row after each table to 1 or 2 points.
Be aware that each section in the document has its own Headers and Footers and that there are three headers and three footers in each section.

Related

Add images and captions programmatically, with bold label

I would like to add captions to figures where chapters would be included in the numbering, and the text "Figure x.x." was bold:
Figure 1.1. Sample figure.
Autocaptions is not possible because it will only allow for styles named Heading 1-9 to be considered as chapters, while I am using a custom style. As I understand, there is no way to include any personalised style to the list.
Please take into consideration that my knowledge of VBA is virtually nonexistant (I usually try to find a similar problem in multiple forums and adapt it using guides or other similar solved problems), so my error might be trivial for those who are more experienced. I could manage to write a macro to do almost everything I needed, but there is this one thing that is not working as expected.
Ideally, the macro would:
Prompt the user to select an image
Insert the image with a specific paragraph style
Insert a caption that includes chapter number with a custom paragraph style, instead of builtin ones
Search for "Figure x.x." text and make it bold using Find and Replace with wildcards <== This is where I'm having problems
Sub PicCaption()
Dim intChoice As Integer
Dim strPath As String
'only allow the user to select one file
Application.FileDialog(msoFileDialogOpen).AllowMultiSelect = True
'make the file dialog visible to the user
intChoice = Application.FileDialog(msoFileDialogOpen).Show
'determine what choice the user made
If intChoice <> 0 Then
'get the file path selected by the user
strPath = Application.FileDialog( _
msoFileDialogOpen).SelectedItems(1)
End If
'insert the image
Selection.InlineShapes.AddPicture FileName:= _
strPath, LinkToFile:=False, _
SaveWithDocument:=True
Selection.Range.Style = "Figures"
'Add caption in the form of "Figure x.x. "
Selection.TypeParagraph
Selection.TypeText Text:="Figure "
Selection.Fields.Add Range:=Selection.Range, Type:=wdFieldEmpty, Text:= _
"STYLEREF ChapNum \n \t", PreserveFormatting:=False
Selection.TypeText Text:="."
Selection.Fields.Add Range:=Selection.Range, Type:=wdFieldEmpty, Text:= _
"SEQ Figure \* ARABIC", PreserveFormatting:=False
Selection.TypeText Text:="."
Selection.Style = ActiveDocument.Styles("Figures")
Selection.TypeText Text:=" "
'Make "Figure x.x." bold (last space not included)
With Selection.Find
.ClearFormatting
.Replacement.ClearFormatting
.Forward = False
.Text = "Figure*.*"
.Font.Bold = False
.MatchWildcards = True
.Replacement.Text = "^&"
.Replacement.Font.Bold = True
.Execute Replace:=wdReplaceOne, Forward:=True, _
Wrap:=wdFindContinue
End With
End Sub
The replacing bit does not make the recently inserted "Figure x.x." bold, but the next one in the text, even if I specified the search to be backwards. If I type .Execute Replace:=wdReplaceOne, Forward:=False, _, it goes to the end of the document and moves upwards, making everything bold.
In my sample document I have multiple already captioned images, but that wouldn't normally be the case; I would like to format captions as I insert them, instead of reformatting them when the document is finished.
Where is my mistake and why, if you were so kind to explain?
Thank you kindly.
I found my answer: for whatever reason, once fields are involved, finding and replacing does not work that well; i.e. it won't correctly find periods within "1.1.". I tried it with and without wildcards, using ?, * and anything I could think of.
I resorted to another method:
Select whole line
Make bold
Go to the end of the line
Uncheck bold so that the description has normal font width
'Code before this point remains identical
'Make "Figure x.x." bold (last space not included)
'Select from cursor point to beginning of line; make bold
Selection.MoveStart Unit:=wdLine, Count:=-1
Selection.Font.Bold = True
'Move cursor to end of the line; uncheck bold format
Selection.EndKey Unit:=wdLine
Selection.Font.Bold = wdToggle
This way, the cursor is placed right after the caption label, bold not selected. Seems clumsy and highly unprofessional, but works.
Thanks, everyone!
When Word inserts a caption it is basically providing a shortcut for the insertion of a number of fields and their associated switches.
Thus if we insert a Figure caption that references Heading 3 style for the chapter numbers we get something like
Figure 2.1.3-1: Text for the caption
If we highlight the 'Figure 2.1.3-1' in the Word document and press Shift-F9 this will show that the caption numbering is composed of a styleref field and a seq field
Figure {Styleref 3 \w}-{Seq Figure}
When the field codes are shown we can easily use the built in Find/Replace of word to change the text between the field brackets. So we could search for 'Styleref 3' and replace it with 'Styleref "Heading 2"' or in fact 'Styleref "myStyle"'.
If the Word wildcard search is used then you can simultaneously change the style ref to the desired style and apply the bold effect, thus achieving the effect that the OP desires. I'll leave that to a little research by the OP.
This is fine if we have to convert an existing document. If we are inserting Captions as we type then it would be preferable to use a macro to insert the caption numbering that is desired by firing a macro that inserts the appropriate caption numbering/formatting from a set of keystrokes.
The macro below will insert a caption of the type desired, use the defined style for chapter numbering and apply the bold effect to all the numbering upto the separating tab.
Option Explicit
' Any Leading and Trailing spaces in the Const definition strings are deliberate
' Heading 2 is used for ease of demonstration. Heading 2 should be replaced by the style
' from which you wish to take the heading numbers.
Const SpecialCaptionStyle As String = """Heading 2""" ' Name of the style to reference for the heading number
Const CaptionType As String = "Figure " ' The trailing space is required
Const CaptionNUmberingStyle As String = " \w " ' see switches for the styleref field
Const CaptionNumberSeparator As String = "-"
Public Sub InsertSpecialCaption()
' Get the range into which we insert the styleref and seq fields
Dim myFieldRange As Word.Range
Set myFieldRange = Selection.Range
'Preserve the srarting range for later use
Dim myEffectRange As Word.Range
Set myEffectRange = Selection.Range.Duplicate
'Set the style to Caption style.
'Caption style will be applied to any text in the paragraph of the selection point
myFieldRange.Collapse direction:=wdCollapseEnd
myFieldRange.Paragraphs.Item(1).Style = myFieldRange.Document.Styles(wdStyleCaption)
'Insert the label of the caption type. In this case it is the text 'Figure'
myFieldRange.InsertAfter Text:=CaptionType
myFieldRange.Collapse direction:=wdCollapseEnd
Dim myField As Word.Field
' Insert the styleref field to obtain the heading number of the style we specify
Set myField = myFieldRange.Document.Fields.Add(Range:=myFieldRange, Preserveformatting:=False)
myField.Code.Text = "Styleref " & SpecialCaptionStyle & CaptionNUmberingStyle
Set myFieldRange = myField.Result
'Insert the text string used as a seperator between the chapter number and the captiontype number
myFieldRange.InsertAfter Text:=CaptionNumberSeparator
myFieldRange.Collapse direction:=wdCollapseEnd
' Insert the Seq field to get the sequential number of the caption
' in this case we use the same name of the label but it could be different
Set myField = myFieldRange.Document.Fields.Add(Range:=myFieldRange, Type:=wdFieldEmpty, Preserveformatting:=False)
myField.Code.Text = "Seq " & CaptionType
Set myFieldRange = myField.Result
myFieldRange.Collapse direction:=wdCollapseEnd
' Insert the seperator text from the number to the Caption text NB I always use : followed by a tab
myFieldRange.InsertAfter Text:=":" & vbTab
' Adjust the range to omit the tab from formatting
' update the fields
' Apply bold effect to the inserted caption label
myFieldRange.MoveEnd unit:=wdCharacter, Count:=-1
myEffectRange.End = myFieldRange.End
myEffectRange.Fields.Update
myEffectRange.Font.Bold = True
End Sub
All that is required is to link the macro to a suitable key sequence, which is the provenance of the OP.
First though, I'd strongly suggest using F8 to step through the macro to see how the Caption number is inserted.

Word VBA Macro - Center+bold+caps first line of text

I am trying to center the first line of text on a document, which would usually be the title.
I am able to center the line with
Selection.Paragraphs.Alignment = wdAlignParagraphCenter
But I am not sure how it is selecting the file line, as I would also like to set the title to bold and caps.
Selection.Font.Bold = wdToggle
Selection.Font.AllCaps = True
_
Also is there a way to "detect" any text that is centered already and has an empty space(line) above and below it, or would that be too difficult to achieve?
Use a with statement to apply multiple formats. Here is an example:
With Selection
.Paragraphs.Alignment = wdAlignParagraphCenter
.Font.Bold = wdToggle
.Font.AllCaps = True
End With

InsertAlignmentTab() in Footer

I have been attempting to add, using VBA, an alignment tab into the footer text - the line of code concerning this is as such
ActiveDocument.Sections(Selection.Information(wdActiveEndSectionNumber)).Footers(wdHeaderFooterPrimary).Range.Text = "Some text" & <ALIGNMENT TAB RIGHT> & "Some more text"
however, it appears that the InsertAlignmentTab() method can only be used when the insertion point is in the designated position. As I cannot move the insertion point into the footer, I cannot accomplish my goal.
My question is - is there a way to add an alignment tab to the footer without moving the insertion point there or is there a way to move the insertion point into the footer.
You can also do this without moving the insertion point.
Sub AddAlignmentTabToFooter()
Dim rngFooter As Range
Set rngFooter = ActiveDocument.Sections(Selection.Information(wdActiveEndSectionNumber)).Footers(wdHeaderFooterPrimary).Range
With rngFooter
.Text = "Some more text"
.Collapse wdCollapseStart
.InsertAlignmentTab wdRight, wdMargin
.InsertBefore "Some text"
End With
Set rngFooter = Nothing
End Sub
You should be able to do both, depending on what exactly it is you want to do.
To set the insertion point in the primary footer:
ActiveWindow.ActivePane.View.SeekView = wdSeekPrimaryFooter
To set it back to the main document:
ActiveWindow.ActivePane.View.SeekView = wdSeekMainDocument
Also, InsertAlignmentTab can be called on any Range object:
Selection.Range.InsertAlignmentTab wdRight, wdMargin
If you put it all together:
ActiveWindow.ActivePane.View.SeekView = wdSeekPrimaryFooter
Selection.Range.Text = "Some more text"
Selection.Range.InsertAlignmentTab wdRight, wdMargin
Selection.Range.Text = "Some text"
ActiveWindow.ActivePane.View.SeekView = wdSeekMainDocument
(Note that Some text and Some more text are reversed, because the InsertAlignmentTab command sends the current range to the right and afterwards the selection is still to the left, at least in my Word 2010 environment.)

How to insert two headers on the same page through word automation? - VB.NET

I am trying to insert a header that includes a logo and a text field onto the FIRST PAGE of my word document through word automation using vb.net.
So far I have gotten the logo to show up on the right side, but I cannot seem to get the text to display on the left side of the header of the first page. Instead it will display on the second page.
Below is my code:
'Insert header notes.
oDoc.Sections(1).PageSetup.DifferentFirstPageHeaderFooter = True
With oDoc.Sections(1).Headers(Word.WdHeaderFooterIndex.wdHeaderFooterPrimary).Range
.Font.Bold = False
.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphRight
.Text = "The Shareholder Communication Strategists"
.Font.Size = 10
End With
oDoc.Sections(1).PageSetup.DifferentFirstPageHeaderFooter = True
With oDoc.Sections(1).Headers(Word.WdHeaderFooterIndex.wdHeaderFooterFirstPage).Range
.InlineShapes.AddPicture("S:\Databases\^Tyler & Rich Database\GUI\Alliance_logo.png")
.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphLeft
.ParagraphFormat.SpaceAfter = 24
End With
Any suggestions on how I can put a logo and a text on the same header of the first page?
Your first With-statement defines the headers of the pages starting at page 2 (because of wdHeaderFooterPrimary) and the second With-statement defines the header of the first page (because of wdHeaderFooterFirstPage).
If you move the content of the first With-statement to the second one, everything should display on the first page.
Microsoft’s reference of WdHeaderFooterIndex Enumeration says:
wdHeaderFooterPrimary Returns the header or footer on all pages other than the first page of a document or section.
I don't know how it will display. This article might give you some usefull hints on how to Insert Images at Specific Locations in Word Document.
Also, there is no point in calling oDoc.Sections(1).PageSetup.DifferentFirstPageHeaderFooter = True twice.
If you want to insert multiple headers or footers left, center or right, use wdAlignParagraphLeft and switch between positions with tabs.
With oDoc.Sections(1).Headers(Word.WdHeaderFooterIndex.wdHeaderFooterPrimary).Range
.Font.Bold = False
.Font.Size = 10
.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphLeft
.Text = "Left" & vbTab & "Center" & vbTab & "Right"
End With

How do we change styles in a word contentcontrol via VB.Net

I'm trying, since a few days, to control a word document via vb.net. I've put some contentControl in it in order to mark the location where I have to make automatic changes.
Writting in it is really easy, replacing also.
Writting a continuous text with a lot of paragraphs is a little more tricky but I manage to do it via functions.
Where I have more problems is by writting one title in a "Style1", a subtitle in a "Style2" and the text in "Normal style".
When I write this :
With tfDocx.BodyCC("startFormulas").Range
.Style = tfDocx.Doc.Styles("Titre 2")
.Text = "Produits"
End With
I have the good text in the good style. But when I add this code:
With tfDocx.BodyCC("startFormulas").Range
.Style = tfDocx.Doc.Styles("Titre 2")
.Text = "Produits"
End With
With tfDocx.BodyCC("startFormulas").Range.Characters.Last
.InsertParagraphAfter()
.Style = tfDocx.Doc.Styles("Titre 3")
.Text = "essais"
End With
The .InsertParagraphAfter is not taken into account and when I debug it I have a single line "Produits essais" in my word document with needer of the two styles.
Does someone have an idea?
Converting your code to VBA (second part where you add 'essais' text) I would have this one:
With CC.Range.Characters.Last
.InsertParagraphAfter
.Move wdParagraph '!!!!!!!!!
.Style = "Nagłówek 1"
.Text = "essais"
End With
As you can see I've added one line with '!!!! comment moving insertion point to next paragraph which was add with .InsertParagraphAfter method.