【问题标题】:Insert text before bookmark在书签前插入文本
【发布时间】:2018-01-23 03:00:34
【问题描述】:

好的,我正在努力让这段代码按照我想要的方式工作。我有一个文档,我正在尝试设置一个宏来将复制的文本从源文档插入到目标文档的中间。我在那里放置了一个书签,我拥有的代码实际上会粘贴文本,但它总是将文本粘贴在书签的最开头。我需要能够多次运行此宏以在书签后插入多个段落。

源文档充满了段落,每个段落都在一个名为“B”的封闭书签内,然后是一个字母数字代码。我们试图填充的目标表单将需要这些段落中的 1 到 7 个。我不介意必须多次运行宏(虽然,如果有办法使用逗号分隔的输入框列表来循环,那会很好),但是宏现在运行的方式,它将段落放入反向顺序,这意味着如果我为第 1 段运行它,然后为第 2 段运行它,它会将它们排序为第 2 段,然后是第 1 段。我需要能够在第一个段落之后插入第二个(和后续)段落。

我尝试过使用 insertbefore 和 insertafter,但无法让它们工作。我尝试在原始书签之前添加一个新书签,然后将新书签用作文本的放置位置,但无法使该代码正常工作。在我希望段落插入的下方还有一个命令按钮 (1),所以如果可以将其用作插入点,那就太好了。但是我根本找不到任何东西,所以我去了书签路线。

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

【问题讨论】:

  • FWIW(与您的问题无关[老实说我什至没有读过问题])-Mark = vbNullString 可以替换为Exit Do,这可能是一种更直观的退出方式循环

标签: vba ms-word


【解决方案1】:

下面的代码将寻找书签,移动到它之前的空间并在那里插入一个文本。因此,书签保持不变,并将位于新插入文本的末尾。您可以在循环中使用它来继续使用相同的书签添加文本。

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

在我的试验中,书签的长度为 1 个字符。事实上,长度无关紧要。但是,我认为如果它仅包含段落结束标记并且您想插入具有自己格式的段落,则可能会出现问题,因为插入的文本将继承插入它的段落的格式。因此,如果您希望使用上述代码插入整个段落,则书签的开头必须与新段落的开头重合。这样,添加书签的段落将保持其格式,而插入的文本将具有自己的格式。

【讨论】:

  • 我已将您的代码添加到我的代码中,但是当我运行宏时,它会删除插入文本上方的所有内容。当我第二次运行宏时,它再次删除了我刚刚添加的段落。
  • 当前代码:Do Mark = InputBox("119f, 979, 981a...", "Enter Number and Letter as Shown") If Len(Mark) Then MarkB = "B" & Mark If SourDoc.Bookmarks.Exists(MarkB) Then SourDoc.Bookmarks(MarkB).Range.Copy With aRng Debug.Print .Start, .End .SetRange .Start - 1, Start - 1 .PasteAndFormat (wdFormatOriginalFormatting) Debug.Print .Start, .End End With Exit Do
  • 看起来很糟糕。有没有办法在这里格式化评论?在我发布之前它看起来好多了。
  • 事实证明,我错过了第二个 .start - 1 之前的一段时间,现在它工作得很好。谢谢你。如果你愿意(而且你已经很棒了!),你能评论代码的debug.print 部分吗?我以前没见过,我不明白它是如何工作的。再次,非常感谢!
  • Debug.Print "whatever" 将“whatever”打印到 VBE 的即时窗口(查看->即时窗口或 Ctl+G)。我用它来让您看到范围的开始和结束位置,因为它首先设置为包含书签,然后移动到标记之前的点。一旦你看到了你想看到的内容,从代码中删除这些行。
【解决方案2】:

variatus 的答案确实有效。我以稍微不同的方式实现了它,这可能对其他人有所帮助。

我的实现需要传递文本/书签名称,并且可以选择在书签不存在时进行处理。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-27
    • 1970-01-01
    相关资源
    最近更新 更多