2

I am writing an Excel VBA macro that copies text to a Word for Windows file and  adds formatting to it later.

It uses a .dotx template that contains a logo. In the lower left corner is a textbox with a serial-number. The text of the serial-number is written  vertically (from the bottom upwards).

Using trial and error I managed to write one serial-number to the textbox  using:

serialnumber = "abc1x"
wdoc.Sections(1).Headers(wdHeaderFooterEvenPages).Shapes(2).TextFrame.TextRange.text 
= serialnumber

So I found the right object to write to. Now I get the same serialnumber on every page.

My goal is to get an increasing serialnumber on the pages: The serial-number has the shape:

  • On page 1:       abc1x
  • on page 2:        abc2x
  • on page 3:        abc3x
  • ...
  • on page 10:     abc10x

It's the page number surrounded by 2 strings.

On a different project I did something similar. I wrote "Page 1 of 10" etc. with the following script:   

    Dim uRange As Object
    Dim uneven As Object

    Set uneven = wdoc.Sections(1).Footers(wdHeaderFooterPrimary)
    Set uRange = wdoc.Sections(1).Footers(wdHeaderFooterPrimary).Range
    uRange.Delete

    uneven.Range.InsertAfter "Page "
    uRange.SetRange Start:=uneven.Range.End + 1, End:=uneven.Range.End + 1
    wdoc.Sections(1).Footers(wdHeaderFooterPrimary).Range.Fields.Add 
Range:=uRange, Type:=wdFieldEmpty, text:= _
    "PAGE  \* Arabic ", PreserveFormatting:=True

    uRange.SetRange Start:=uneven.Range.End + 1, End:=uneven.Range.End + 1
    uneven.Range.InsertAfter " of "
    uRange.SetRange Start:=uneven.Range.End + 1, End:=uneven.Range.End + 1

    wdoc.Sections(1).Footers(wdHeaderFooterPrimary).Range.Fields.Add 
Range:=uRange, Type:=wdFieldEmpty, text:= _
     "NUMPAGES  \* Arabic ", PreserveFormatting:=True

How do I insert the text around the Page field in the TextBox?

(Side note: What is the difference between the range and rangetext object?)

Remarks: I will have to apply the solution to the even and uneven pages seperately. That doesn't pose a problem. To make matters more difficult: I am obliged to keep the text-field, because it comes from the hands of  the corporate identity folks.

Community
  • 1
  • 1
Ratilius
  • 133
  • 1
  • 9
  • I don't know what you mean by `rangetext` object. There is `Range.Text` which is the actual string content "in" a particular `Range`. `Text` is also the default property of Word's `Range` object, so if you leave it away in VBA and assign (or try to read) a string, VBA will *assume* you mean the `Text` property and use that. But it's better to be specific... – Cindy Meister May 14 '18 at 18:54
  • If you mean `TextFrame.TextRange` that's just the name of the Range property inside a `Shape` object. This is shared across all Office applications. I don't know whether it's named differently simply because the developers of this part of the object model liked it better, or whether to distinguish the property from `ShapeRange` and Word and Excel's `Range` objects... – Cindy Meister May 14 '18 at 19:09

1 Answers1

1

There are a number of ways to go about this. All involve "collapsing" the target Range before inserting the next thing (text or field code).

Some time ago, I wrote a set of generalized functions so that I could insert any combination of text and field codes comfortably, without having to "tweak" for each combination.

First define the Range object. If there might be any content you want to keep, collapse it. The procedures InsertNewText and InsertNewField take the target Range and the text to insert, respectively the field code for the field to be inserted. The collapsing of the Range is done in these procedures and is passed back to the calling procedure for the next step.

Sub InsertTextAndFields()
    Dim rngContent As Word.Range

    Set rngContent = wdoc.Sections(1).Headers( _
        wdHeaderFooterEvenPages).Shapes(2).TextFrame.TextRange
    rngContent.Collapse wdCollapseEnd

    Set rngContent = InsertNewText(rngContent, "abc")
    Set rngContent = InsertAField(rngContent, "Page")
    Set rngContent = InsertNewText(rngContent, "x")

End Sub

Function InsertNewText(rng As word.Range, newText As String) As word.Range
    rng.Text = newText
    rng.Collapse wdCollapseEnd
    Set InsertNewText = rng
End Function

Function InsertAField(rng As word.Range, _
                      fieldText As String) As word.Range

    Dim fld As word.Field
    Dim rngField As word.Range

    Set fld = rng.Document.Fields.Add(Range:=rng, _
              Text:=fieldText, PreserveFormatting:=False)

    Set rngField = fld.result
    rngField.Collapse wdCollapseEnd
    rngField.MoveStart wdCharacter, 1
    Set InsertAField = rngField
End Function
Cindy Meister
  • 25,071
  • 21
  • 34
  • 43
  • Great it worked and the solution is neatly packaged! Eine meisterhafte Loesung. (the work of a true master) – Ratilius May 15 '18 at 06:22
  • I need one more tweak: The counting is 1, 2, 3..., 8, 9, A, B, C, .... instead of 1, 2,3, ..., 8,9, 10, 11     On page 1:       abc1x     on page 2:        abc2x     on page 3:        abc3x     ...     on page 10:     abcAx Can I combine your solution with logic in tex-fields? it should look like {IF {PAGE} < 10 ""{PAGE \* Arabic }"" ""{ PAGE \* ALPHABETIC }""} I get the formula into the text-field, (if I look at it in the word-dokument the formula is in the properties  of the textfield)  but i doesn't display the numbers. – Ratilius May 15 '18 at 10:06
  • @Ratilius You should never edit a question in a way that invalidates the answer - and this was very clearly *not* in the original problem statement. Creating *nested* fields is an entirely different kettle of fish. Look at my Answer in this discussion https://stackoverflow.com/a/49805695/3077495, in particular the function GenerateNestedField – Cindy Meister May 15 '18 at 15:09
  • Thank you for pointing this out. Asking a new question would have been the preferred way? I will change back the question later on my pc. the interface on my mobile is very clumsy. – Ratilius May 15 '18 at 15:31
  • @Ratilius It's alright, I've rolled it back for you. Asking a new question would be preferred, yes, IF the information in the link doesn't solve the problem for you. FWIW all the information to solve it is there - it's just a matter of fitting it together. – Cindy Meister May 15 '18 at 16:11