0
votes

Ok, I'm struggling to get this code to work the way I want it to. I have a document that I'm trying to set up a macro to insert copied text from a source document into the middle of the target document. I have placed a bookmark there, and the code that I have will actually paste the text, but it always pastes the text at the very beginning of the bookmark. I need to be able to run this macro multiple times to insert multiple paragraphs after the bookmark.

The source document is filled with paragraphs, each one of which is inside an enclosing bookmark named "B", then an alpha-numeric code after. The target form we are trying to populate will need anywhere from 1 to 7 of these paragraphs. I don't mind having to run the macro several times (although, if theres a way to use a comma separated input box list to loop through, that would be nice), but the way the macro runs now, it puts the paragraphs in reverse order, meaning that if I run it for Paragraph 1, then for Paragraph 2, it orders them as Paragraph 2, then Paragraph 1. I need to be able to insert the second (and subsequent) paragraph after the first one.

I've tried using insertbefore and insertafter, and can't get them to work. I tried to add a new bookmark before the original bookmark, and then using the new bookmark as the drop location for the text, but couldn't get that code functioning. There is also a command button (1) just below where I would want the paragraphs to drop in, so if it's possible to use that as an insertion point, that would be wonderful. But I couldn't find anything at all on that, so I went the bookmark route.

Private Sub CommandButton1_Click()

    Dim TarDoc As Document, SourDoc As Document
    Dim aRng As Word.Range
    Dim Mark As String, MarkB As String

    Application.ScreenUpdating = False

    Set SourDoc = Documents.Open("C:\Projects\SourceDocument.docx")
    Set TarDoc = ThisDocument
    Set aRng = TarDoc.Bookmarks("End").Range

    Do
        Mark = InputBox("100, 289, 981a...", "Enter Number and Letter as Shown")
        If Len(Mark) Then              ' do nothing if user enters nothing
            MarkB = "B" & Mark
            If SourDoc.Bookmarks.Exists(MarkB) Then
                SourDoc.Bookmarks(MarkB).Range.Copy
                aRng.PasteAndFormat (wdFormatOriginalFormatting)
                Mark = vbNullString    ' to enable exiting the loop

            Else
                MsgBox "Bookmark """ & Mark & """ doesn't exist.", vbInformation, _
                       "Invalid entry"
            End If
        End If
    Loop While Len(Mark)               ' the user entered a wrong mark

    Application.ScreenUpdating = True
End Sub
2
FWIW (not related to your problem [to be honest I haven't even read the question]) - Mark = vbNullString can be replaced with Exit Do which might be a more intuitive way of exiting the loopYowE3K

2 Answers

3
votes

The code below will look for the bookmark, move to the space immediately before it and insert a text there. The bookmark therefore remains untouched and will be at the end of the newly inserted text. You can use it in a loop to continue adding texts using the same bookmark.

Sub InsertBeforeMark()

    Dim Bmk As String
    Dim InsText As String
    Dim Rng As range

    Bmk = "InsertHere"
    InsText = "Something new."

    With ActiveDocument
        If .Bookmarks.Exists(Bmk) Then
            Set Rng = .Bookmarks(Bmk).range
        End If
    End With
    With Rng
        Debug.Print .Start, .End
        .SetRange .Start - 1, .Start - 1
        .Text = InsText
        Debug.Print .Start, .End
    End With
End Sub

In my trials the bookmark had a length of 1 character. In fact, the length is immaterial. However, I think there might be a problem if it were to contain an end-of-paragraph mark only and you wanted to insert paragraphs with their own formatting because the inserted text would inherit the formatting of the paragraph into which it is inserted. Therefore, if you wish to use the above code to insert entire paragraphs it would be essential that the beginning of the bookmark coincides with the beginning of a new paragraph. In that way the bookmarked paragraph would keep its formatting while the inserted text would bring its own.

0
votes

The answer by variatus does indeed work. I implemented it a slightly different way that might help someone else.

My implementation requires passing the text/bookmark name and has an option to handle if the bookmark doesn't exist.

Sub insertStringBeforeBookmark(str1 As String, bmkName As String)

    Dim rng As Range

    If ActiveDocument.Bookmarks.Exists(bmkName) Then
        Set rng = ActiveDocument.Bookmarks(bmkName).Range

        With rng
            rng.SetRange .Start - 1, .Start - 1
            .Text = str1
        End With
    Else 'do some handling here.
        Debug.Print "The procedure insertStringBeforeBookmark " _
        ; "was called but the bookmark does not exist."

    End If   

End Sub