none
Word VBA : Index XE entries entered in the right place, but are pushed down RRS feed

  • Question

  • CodeLine0 sVal = ""Addison Gilbert Hospital"
    CodeLine1 Selection.TypeText Text:=sVal
    CodeLine2 oDoc.Indexes.MarkEntry Entry:=sVal, Range:=Selection.Range
    CodeLine3 Selection.TypeText vbCrLf

    I get this... which is OK, until I insert something else:
    Addison Gilbert Hospital{ XE "Addison Gilbert Hospital" }

    then I do this
    CodeLine4 Selection.TypeText "23 Main Street" & vbCrLf
    CodeLine5 Selection.TypeText "Seattle, WA 01234" & vbCrLf

    I get this... which is NOT OK:
    Addison Gilbert Hospital
    23 Main Street
    Seattle, WA 01234
    { XE "Addison Gilbert Hospital" }

    What am I doing wrong?
    I do not want the Index XE's to be pushed down and but want them stay where they belong (within the Paragraph marker)

    Thursday, October 11, 2012 5:30 PM

Answers

  • Hi Cornelia

    The problem is that the selection remains "ahead" of the field so, using Selection.TypeText is "pushing" the XE field ahead of it.

    Generally, it's  better to not use Selection.TypeText, but to work directly with the object representations - in this case Range and Field objects. Probably even less intuitive for you, until you get the hang of it, but definitely more predictable and usually it's easier to follow what the code is supposed to be doing when you come back to it much later :-)

    And just to make things even more confusing, when working with Ranges there's more than one way to do things. Everyone has their preferences. Here's one possibility, just to give you an idea:

    Sub InsertXEField()
        Dim rngInput As word.Range
        Dim rngXETarget As word.Range
        Dim sVal As String
        
        sVal = "Addison Gilbert Hospital"
        Set rngInput = Selection.Range
        rngInput.Text = sVal & vbCr & "23 Main Street" _
          & vbCr & "Seattle, WA 01234" & vbCr
            
        Set rngXETarget = rngInput.Paragraphs(1).Range
        ActiveDocument.Indexes.MarkEntry _
          Range:=rngXETarget, entry:=sVal
    End Sub
    vbCr inserts a paragraph mark, so it's possible to insert the text in one step. Since the XE field should contain the first paragraph, we get the first paragraph of the entire range to use for inserting the field.


    Cindy Meister, VSTO/Word MVP, my blog

    Saturday, October 13, 2012 7:51 AM
    Moderator

All replies

  • Hi Cornelia,

    Thanks for posting in the MSDN Forum.

    It’s based on my experience that the selection has not been change when you input second and third paragraph. I would recommend you use following snippet to approach your goal:

    Sub test()
        Dim sVal As String
        
        sVal = "Addison Gilbert Hospital"
        Selection.TypeText sVal
        Selection.TypeParagraph
        Selection.Range.InsertAfter "23 Main Street"
        Selection.TypeText "Seattle, WA 01234"
        Selection.TypeParagraph
        
        With ActiveDocument.Range().Find
            .Text = sVal
            If .Execute Then
                ActiveDocument.Indexes.MarkEntry Range:=.Parent, Entry:=sVal
            End If
        End With
        
            
    End Sub

    I hope it can help you.

    Have a good day,

    Tom


    Tom Xu [MSFT]
    MSDN Community Support | Feedback to us

    Friday, October 12, 2012 5:12 AM
    Moderator
  • Hi Tom,

    Thanks for the help.... I sort of fixed in ... not in an elegant way, with this:

    oDoc.Indexes.MarkEntry Range:=oSel.Range, Entry:=sVal
    Selection.EndKey Unit:=wdStory
    Selection.TypeText "23 Main Street" & vbCrLf

    (it took hours to figure it out, very counter intuitive)

    Friday, October 12, 2012 1:42 PM
  • Hi Cornelia

    The problem is that the selection remains "ahead" of the field so, using Selection.TypeText is "pushing" the XE field ahead of it.

    Generally, it's  better to not use Selection.TypeText, but to work directly with the object representations - in this case Range and Field objects. Probably even less intuitive for you, until you get the hang of it, but definitely more predictable and usually it's easier to follow what the code is supposed to be doing when you come back to it much later :-)

    And just to make things even more confusing, when working with Ranges there's more than one way to do things. Everyone has their preferences. Here's one possibility, just to give you an idea:

    Sub InsertXEField()
        Dim rngInput As word.Range
        Dim rngXETarget As word.Range
        Dim sVal As String
        
        sVal = "Addison Gilbert Hospital"
        Set rngInput = Selection.Range
        rngInput.Text = sVal & vbCr & "23 Main Street" _
          & vbCr & "Seattle, WA 01234" & vbCr
            
        Set rngXETarget = rngInput.Paragraphs(1).Range
        ActiveDocument.Indexes.MarkEntry _
          Range:=rngXETarget, entry:=sVal
    End Sub
    vbCr inserts a paragraph mark, so it's possible to insert the text in one step. Since the XE field should contain the first paragraph, we get the first paragraph of the entire range to use for inserting the field.


    Cindy Meister, VSTO/Word MVP, my blog

    Saturday, October 13, 2012 7:51 AM
    Moderator