I'm trying to create a header that begins on the second page, inserts an em dash, the page number and another em dash, centered in vba - vba

document.Application.ActiveDocument.Sections(1).Headers(WdHeaderFooterIndex.wdHeaderFooterPrimary) _
.PageNumbers.StartingNumber = 2
For Each section As Word.Section In document.Application.ActiveDocument.Sections
Dim headerRange As Word.Range = section.Headers(Word.WdHeaderFooterIndex.wdHeaderFooterPrimary).Range
headerRange.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter
headerRange.Text = " — "
headerRange.Fields.Add(headerRange, Word.WdFieldType.wdFieldPage)
headerRange.Text = headerRange.Text & " — "
Next
The issue that I am having is I cannot get the dashes on either side of the page number. It will always place both of them before or after the page number.
I have tried concatenating, I have tried various placements of the dashes. I have tried the headerRange.Collapse with no success.
'document.Application.ActiveDocument.Sections(1).Headers(WdHeaderFooterIndex.wdHeaderFooterPrimary) _
' .PageNumbers.StartingNumber = 2
'For Each section As Word.Section In document.Application.ActiveDocument.Sections
' Dim headerRange As Word.Range = section.Headers(Word.WdHeaderFooterIndex.wdHeaderFooterPrimary).Range
' headerRange.Text = "—"
' headerRange.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter
' headerRange.Collapse(Word.WdCollapseDirection.wdCollapseEnd)
' headerRange.Fields.Add(headerRange, Word.WdFieldType.wdFieldPage)
' headerRange.Collapse(Word.WdCollapseDirection.wdCollapseEnd)
' headerRange.Text = "-"
'Next

To a man with a hammer, everything looks like a nail.
You are doing this the hard way, in my opinion.
I look at using a macro for this as reinventing the wheel - Instead, use Templates or Building Blocks
Perhaps I am lazy, but setting things up in vba and formatting it is hard, at least to me.
You could create a template with your header and use that as the basis for new documents. Here is my page on Templates in Microsoft Word.
You could save this as a Building Block if you want to use it in existing documents. Remember that using a page number building Block for top of page replaces any existing header, for bottom of page replaces any existing footer.
Here is a temporary link to a template containing three page number building blocks with those for top and bottom of the page being centered. All have M-dashes on either side. The font and size will be determined by the Header or Footer styles in the document. The template contains instructions for using it.
If you want to use vba to insert these building blocks, there are examples shown on my web page with specific instructions on placement of the macros and building blocks. Here is my answer here about using vba to insert a Table of Contents a Building Block.
You could also have a macro to create a new document based on your template.
No matter how you decide to do this, keep in mind that each Word section has three headers, whether or not they are seen. In multi-section documents, these may, or may not, be linked to like headers in previous sections.
Here is my recap of Header and Footer Settings.

Related

Set background color of headers and footers

I have been able to change the background color of Word tables in the body of the document with: oSourceTable.Shading.BackgroundPatternColor = wdRed. However, the same code does not work for header or footer Word tables. I have also tried setting the Section back color as well, but to no avail. The code runs, but the Headers and Footers are always displayed with white backgrounds.
I have done mostly Excel VBA, and only a little bit of Word VBA so maybe I am missing something obvious here. Thanks in advance for any ideas and/or suggestions.
As requested, here is the code I am using. vTableBackColors is just an array of colors. This code is for the body tables and is working perfectly.
For Each oWordTable In oWordDoc.Tables
lIndex = lIndex + 1
oWordTable.Shading.BackgroundPatternColor = vTableBackColors(lIndex)
Next
I tried to do the same thing for the header and footer tables, but it does not work. I tried using the Header/Footer tables as below.
For Each oWordSection In oWordDoc.Sections
For Each oWordTable In oWordSection.Headers.Item(wdHeaderFooterPrimary).Range.Tables
' I selected this one to see if it would make a difference.
oWordTable.Select
oWordTable.Shading.BackgroundPatternColor = m_HeaderBackColor
Next
For Each oWordTable In oWordSection.Footers.Item(wdHeaderFooterPrimary).Range.Tables
oWordTable.Shading.BackgroundPatternColor = m_FooterBackColor
Next
Next
I also tried using the Section Headers / Footers directly. Before and after checking shows that the BackgroundPatternColor has changed as desired, but it is not displayed.
oWordSection.Headers.Item(wdHeaderFooterPrimary).Range.Shading.BackgroundPatternColor = m_HeaderBackColor
Here is a screenshot showing the colorized body tables and the unchanged header.
Is it possible that, unlike the Body table colors, the Header / Footer colors are never displayed as such by the Word designer, but are only true at runtime?
Thanks for any additional information.
«I have been able to change the background color of Word tables in the body of the document with: oSourceTable.Shading.BackgroundPatternColor = red.» That would not work unless you have defined 'red' as an RGB value.
As for the header/footer issue, this works for me:
For Each oWordSection In oWordDoc.Sections
For Each oWordTable In oWordSection.Headers.Item(wdHeaderFooterPrimary).Range.Tables
oWordTable.Shading.BackgroundPatternColorIndex = wdRed
Next
For Each oWordTable In oWordSection.Footers.Item(wdHeaderFooterPrimary).Range.Tables
oWordTable.Shading.BackgroundPatternColorIndex = wdRed
Next
Next
Perhaps your underlying problem is in the value you have assigned to 'm_HeaderBackColor' and 'm_FooterBackColor' - which your posted code doesn't show. It's also possible your code is addressing the wrong headers/footers (i.e. maybe it's not the primary ones you need to address).

Combining Rich Text Content Control Content in MS Word using VBA

I'm trying to create a form for a non-technical user in MS Word to capture some text content in MS Word. This word doc consists of several rich text content controls where the user will type in or paste in some formatted data (bold, underlined, links, ...).
Once they get all the content entered into these various content controls I'm trying to make it easy for them to combine them together to paste in a consistent order into some podcast show notes which is in an HTML form.
So basically, I want to take three rich text content controls that have formatted data in them, combine them together into one formatted piece of content, and then copy it to the clipboard so they can then go to this web form, paste it in, and do some minor cleanup. The problem is that whenever I try to combine the RTF content it loses the formatting.
The only way I seem to be able to keep the formatting is if I copy the range object and then paste it. However, this doesn't paste just the formatted text. It pastes the whole rich text content control.
I've tried creating a blank RTF field at the bottom of the Word doc to combine everything in but I just can't figure it out. I wouldn't think this would be rocket science.
Being none of the code I've tried works and keeps the formatting I"m not sure if posting it here will do any good. Here's how I'm getting the value of the text object:
ActiveDocument.SelectContentControlsByTitle("txtShowNotes").Item(1).Range.Text
tried this:
ActiveDocument.SelectContentControlsByTitle("txtShowNotes").Item(1).Range.Copy
ActiveDocument.SelectContentControlsByTitle("txtCombinedContentSection").Item(1).Range.Paste
but this copies the whole RTF and not just the text.
Try something based on:
Sub Demo()
Dim Rng As Range
With ActiveDocument
Set Rng = .SelectContentControlsByTitle("txtCombinedContentSection").Item(1).Range
Rng.FormattedText = _
.SelectContentControlsByTitle("txtShowNotes").Item(1).Range.FormattedText
Rng.InsertAfter vbCr & vbCr
Rng.Characters.Last.FormattedText = _
.SelectContentControlsByTitle("txtShowNotes").Item(2).Range.FormattedText
End With
End Sub

VBA code not exiting list (MS Word)

Writing a macro to automatically fix paraphrase spacing issues in MS Word docs generated from software we use.
Goal:
All standard paragraphs have 0pt before and after spacing.
All bullet lists have 3pt before and after spacing.
Progress:
Currently I have a function that sets the entire document to 0pt, then looks through for all lists and changes them to 3pt. (currently also have a highlight on so I can easily see what is being treated as a list).
It works great on some parts, but on other parts (I assume based on how the software we use generates the document), the list doesn't exist and it will continue to format blocks of text and heading to 3pt when it is not wanted (see attached images).
Current code is:
Sub Paragraph()
ActiveDocument.Range.ParagraphFormat.SpaceAfter = 0
ActiveDocument.Range.ParagraphFormat.SpaceBefore = 0
Dim li As Word.list
For Each li In ActiveDocument.lists
li.Range.ParagraphFormat.SpaceBefore = 3
li.Range.ParagraphFormat.SpaceAfter = 3
li.Range.HighlightColorIndex = wdYellow
Next li
End Sub
Working:
Not working:
According to the MSDN:
List Object: Represents a single list format that's been applied to specified paragraphs in a document.
So if you have more than one list with some non-bulleted paragraph(s) in the middle, the Range will start with the first item of the first list and end with the last item of the last list including all non-bulleted paragraph(s) in the middle.
To fix this issue, you need to separate the lists (right-click on the bullet and select Separate List). However, you mentioned that the document was generated by some software, so that is probably not an option. In that case, you will have to iterate though the paragraphs of the Range of each List and check if it has a ListFormat.ListTemplate which indicates that it is a list item, otherwise it is a non-bulleted paragraph:
Sub Paragraph()
ActiveDocument.Range.ParagraphFormat.SpaceAfter = 0
ActiveDocument.Range.ParagraphFormat.SpaceBefore = 0
Dim li As Word.List
Dim p As Paragraph
For Each li In ActiveDocument.Lists
For Each p In li.Range.Paragraphs
If Not p.Range.ListFormat.ListTemplate Is Nothing Then
p.Range.ParagraphFormat.SpaceBefore = 3
p.Range.ParagraphFormat.SpaceAfter = 3
p.Range.HighlightColorIndex = wdYellow
End If
Next p
Next li
End Sub
Even before touching VBA:
Use Styles in the document.
Limit the use of Styles in the document to only those that are in the
template.
Set your spacing in the Styles.
If, at some stage, you change your mind and want to use 6pt spacing, you can adjust the template and re-apply it, rather than finding all the VBA code and re-writing it. Not only that, but by using Styles, you can avoid having VBA code, or having VBA-enabled documents which may interfere with some corporate security settings.
Oh, and set up your corporate structure to limit the use of templates to only the approved ones.

Different PPT templates reacting different on the same macros

I'm new here, so I might have not seen a possibility to upload my problem files, which would make it easier to describe the problem.
Edit: The files a here: https://drive.google.com/file/d/0B--IbmtX58h8TnVrdlRyUXZ5a2dEOVJBQkplVjFuVEVMVXhJ/view?usp=docslist_api
and: https://drive.google.com/file/d/0B--IbmtX58h8TFR6d3FkWlZpSGFVUGF5bHVhRTR5ZTlnbXAw/view?usp=docslist_api
(Thank you for the idea, Steve)
What it is about:
I have two documents with different master templates reacting completely different on the same set of macros and I have no idea how and why this can happen and how to repair or avoid it.
Two of the macros just create objects - one is a single textbox, the other one a group of a rectangle and a textbox . The first mentioned appears on the position defined in the code in one of the templates, but a bit below it in the other one. Even more strange is the behavior of the group. The rectangle appears on the correct position in both of the templates, the textbox only in one of it.
Next is a macro for increasing the paragraphing between text lines by 3 pt. It works fine in one template, but in the other template it increases the spacing by 43.2 pt!
Macro number four is made to set back the paragraphing space after back to 0. This one works fine in both templates.
Funny enough, the mistakes appear in opposite to each other. The single textbox and the group produce their error in the template, where the spacing tool works fine, and the spacing tool does strange things in the template where the single textbox and the group work well.
Any idea will be appreciated!
Thanks,
RG
I work with PowerPoint 2010.
Your footnote is getting misplaced because the default text settings in one presentation are different from those in the other; in this case the auto fit setting.
' in this section of your FOOTNOTE routine:
With .TextFrame
' Add this next line and it will work as expected
.AutoSize = ppAutoSizeNone
.TextRange.Text = "Note: " & vbCrLf & "Source: "
.VerticalAnchor = msoAnchorBottom
Likewise, in your SectionMarker subroutine:
With .TextFrame
' add this
.AutoSize = ppAutoSizeNone
' then the rest of your code
Then it all works as you'd expect. Or at least, it works the same with both templates.

How to choose a different header image in MS Word 2013 using a macro/button

I'd like to create a Word stationary template with ability to cycle through different colored logos in its header. My company uses a logo in five different colors and I would like to create a single template with a button that would allow me to cycle through the different colored logos every time I create a new document from this template. Can this be done, perhaps with a little VBA?
Edit:
After working with an answer from Olle Sjögren I've come up with the following working script:
Option Explicit
Public imgCounter As Integer
Sub cycle_logos()
Dim I As Variant
Dim logoColors(4) As String
logoColors(0) = "logo_magenta.png"
logoColors(1) = "logo_teal.png"
logoColors(2) = "logo_orange.png"
logoColors(3) = "logo_red.png"
logoColors(4) = "logo_grayscale.png"
For Each I In logoColors
ActiveDocument.StoryRanges(wdPrimaryHeaderStory).ShapeRange.Item(I).Visible = msoFalse
Next I
imgCounter = imgCounter + 1
If imgCounter = 5 Then imgCounter = 0
ActiveDocument.StoryRanges(wdPrimaryHeaderStory).ShapeRange.Item(logoColors(imgCounter)).Visible = msoTrue
End Sub
It is worth mentioning how I came up with the image names, since I didn't find a way to do this from inside Word. I renamed the template extension to zip and unzipped it. In the extracted files I opened word\header2.xml (this may vary, depending on the position in the document) and edited the nodes containing the names of pictures, i.e. <wp:docPr/>, e.g.:
<wp:docPr name="Picture 1" id="1"/>
became:
<wp:docPr name="logo_magenta.png" id="1"/>
etc. I then replaced the XML file in the ZIP with my edited version and changed the extension back to dotm.
As mentioned, there are several ways to do this. I would suggest storing the images outside of the template, otherwise all documents based on the templates would include all logo images, even if they are not shown, making the documents bigger than they need to be. That approach makes installing the template a bit harder, since you would have to copy the images to the clients as well as the template file.
To answer your question regarding addressing the images in the header - you can address then through the correct story range object. In my example I assume that they are in the primary header. To tell the different images apart, you can use the Name property or the index in the Item collection:
ThisDocument.StoryRanges(wdPrimaryHeaderStory).ShapeRange.Item("Picture 1").Visible = msoTrue
ThisDocument.StoryRanges(wdPrimaryHeaderStory).ShapeRange.Item(1).Visible = msoFalse