We help IT Professionals succeed at work.

We've partnered with Certified Experts, Carl Webster and Richard Faulkner, to bring you two Citrix podcasts. Learn about 2020 trends and get answers to your biggest Citrix questions!Listen Now

x

Word Automation inserting Page Numbers

Medium Priority
1,087 Views
Last Modified: 2012-08-14
Hi to all,

I created a Visual Basic .Net application using Visual Studio 2008. This application creates one word document from files in a selected folder and then numbers the pages. All is working just fine, but I am having issues numbering the pages correctly. The code below shows what I am doing to number the pages, but some pages are not correct. For instance: after page 4 comes page 6 and so on. Can anyone please let me know what I am doing wrong and if possible give me code to use the built in "Building Blocks" that comes with office 2007.

Thanks
Public Shared Sub InsertPageNumbers(ByVal myWordApplication As Word.Application)
            myWordApplication.ActiveDocument.Repaginate()
            
            Dim NumberOfSections As Integer = myWordApplication.ActiveDocument.Sections.Count
            Dim i As Integer = 1
            Do Until i = NumberOfSections
                Dim rng As Word.Range = myWordApplication.ActiveDocument.Sections(i).Footers _
                (Word.WdHeaderFooterIndex.wdHeaderFooterPrimary).Range
                rng.Fields.Add(rng, , "NumPages", False)
                rng.Fields.Add(rng, , "        Page ", False)
                rng.InsertBefore(vbTab & "        Page ")
                rng.Collapse(Word.WdCollapseDirection.wdCollapseStart)
                i += 1
            Loop
        End Sub

Open in new window

Comment
Watch Question

You'll find some good code samples here:  http://blogs.msdn.com/microsoft_office_word/archive/2009/02/03/managing-and-administrating-building-blocks.aspx

Hopefully that will help

Dawn Crosier-Bleuel
Word MVP

Author

Commented:
dlc110161,

Thanks for the reply. The link you posted is very helpful and I used the contents in that post, but I keep on getting the following error when I use that (or any building blocks) code.

'Microsoft.Office.Interop.Word.BuildingBlockTypes' cannot be indexed because it has no default property.

Do you maybe have an idea what might cause this?

Thanks


Do you have more than one set of building blocks in your building blocks folder? If so, you may need to loop until you find the proper one.

You might also want to post the code that you are using to see whether there is something that might stick out.

Dawn Crosier-Bleuel
Word MVP
Templates.LoadBuildingBlocks
 
 
i = 1
For Each atemp In Templates
    If atemp = "Building Blocks.dotx" Then Set strMasterTemplate = Templates(i)
    Debug.Print atemp
    i = i + 1
Next atemp

Open in new window

I just ran through Jodie's code and did not get any errors. So it's got to be something extra that you are doing in your code. I am using straight Word, and not .Net.

Dawn Crosier-Bleuel
Word MVP

Author

Commented:
Dawn,

Thanks for the reply. The only thing I can think of is the fact that all the documents are located on a file server on a share. This file server has word 2007 installed. If that is not the issue, I included my code using building blocks below:

Public Shared Sub BuildingPageNumbers(ByVal myWordApplication As Word.Application)
myWordApplication.ActiveDocument.Repaginate()
'myWordApplication.Templates.LoadBuildingBlocks()
'With myWordApplication
'    .ActiveDocument.AttachedTemplate.BuildingBlockEntries("Plain Number 2").Insert _
'    (myWordApplication.Selection.Range, True)
'    .Selection.TypeText("Page ")
'    .ActiveWindow.ActivePane.View.SeekView = Word.WdSeekView.wdSeekMainDocument
'End With
 
'MSDN Code
Dim wordDocument As Word.Document = Nothing
Dim wordTemplate As Word.Template = Nothing
Dim wordBuildingBlock As Word.BuildingBlock
Dim paramBBType As Word.WdBuildingBlockTypes = Word.WdBuildingBlockTypes.wdTypePageNumberBottom
Dim paramBBCategory As String = "Simple"
Dim paramBBName As String = "Plain Number 2"
myWordApplication.Templates.LoadBuildingBlocks()
myWordApplication.Templates.LoadBuildingBlocks()
wordTemplate = myWordApplication.Templates(1)
Dim TemplateName As String = wordTemplate.Name
wordBuildingBlock = _
wordTemplate.BuildingBlockTypes.Item(paramBBType) _
.Categories.Item(paramBBCategory).BuildingBlocks.Item(paramBBName)
wordBuildingBlock.Insert(wordDocument.Sections(1) _
.Footers(Word.WdHeaderFooterIndex.wdHeaderFooterPrimary).Range)
End Sub

Open in new window

Dawn,

I found an easier way using OpenXMLDeveloper. You need to create a word document (ONLY Word 2007). Insert the footer you want, save the file and then open it as a ZIP file. Get the footer1.xml file and then copy that to an area where you can get to it. Use the code below to create a footer in your document.

Thanks for the help though

 Public Sub WDAddFooter(ByVal docName As String, ByVal footerContent As Stream)
        ' Given a document name, and a stream containing valid Footer content,
        ' add the stream content as a Footer in the document and remove the original Footer
        Const wordmlNamespace As String = "http://schemas.openxmlformats.org/wordprocessingml/2006/main"
        Const relationshipNamespace As String = "http://schemas.openxmlformats.org/officeDocument/2006/relationships"
        Dim wdDoc As WordprocessingDocument = WordprocessingDocument.Open(docName, True)
 
        Using (wdDoc)
            ' Delete existing Footer part
            wdDoc.MainDocumentPart.DeleteParts(wdDoc.MainDocumentPart.FooterParts)
 
            ' Create a new Footer part.
            Dim FooterPart As FooterPart = wdDoc.MainDocumentPart.AddNewPart(Of FooterPart)()
            Dim rId As String = wdDoc.MainDocumentPart.GetIdOfPart(FooterPart)
            Dim footerDoc As XmlDocument = New XmlDocument
            footerContent.Position = 0
            footerDoc.Load(footerContent)
 
            ' Write the Footer out to its part.
            footerDoc.Save(FooterPart.GetStream)
 
            ' Manage namespaces to perform Xml XPath queries.
            Dim nt As NameTable = New NameTable
            Dim nsManager As XmlNamespaceManager = New XmlNamespaceManager(nt)
            nsManager.AddNamespace("w", wordmlNamespace)
 
            ' Get the document part from the package.
            ' Load the XML in the part into an XmlDocument instance.
            Dim xdoc As XmlDocument = New XmlDocument(nt)
            xdoc.Load(wdDoc.MainDocumentPart.GetStream)
 
            ' Find the node containing the document layout.
            Dim targetNodes As XmlNodeList = xdoc.SelectNodes("//w:sectPr", nsManager)
            For Each targetNode As XmlNode In targetNodes
                ' Delete any existing references to Footer.
                Dim footerNodes As XmlNodeList = targetNode.SelectNodes("./w:footerReference", nsManager)
                For Each footerNode As System.Xml.XmlNode In footerNodes
                    targetNode.RemoveChild(footerNode)
                Next
                ' Create the new Footer reference node.
                Dim node As XmlElement = xdoc.CreateElement("w:footerReference", wordmlNamespace)
                Dim attr As XmlAttribute = node.Attributes.Append(xdoc.CreateAttribute("r:id", relationshipNamespace))
                attr.Value = rId
                node.Attributes.Append(attr)
                targetNode.InsertBefore(node, targetNode.FirstChild)
            Next
 
            ' Save the document XML back to its part.
            xdoc.Save(wdDoc.MainDocumentPart.GetStream(FileMode.Create))
        End Using
    End Sub

Open in new window

Not the solution you were looking for? Getting a personalized solution is easy.

Ask the Experts
Very Cool! Thanks for sharing that. I really need to get with it with XML :)

Dawn Crosier-Bleuel
Word MVP
Access more of Experts Exchange with a free account
Thanks for using Experts Exchange.

Create a free account to continue.

Limited access with a free account allows you to:

  • View three pieces of content (articles, solutions, posts, and videos)
  • Ask the experts questions (counted toward content limit)
  • Customize your dashboard and profile

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.