宏根据选择插入交叉引用

时间:2017-11-29 18:21:16

标签: word-vba

我目前在一家公司工作,该公司为其文件使用套房式。这包括内置于Word模板中的多级编号标题。即。

  1. 标题1
  2. 1.1标题2

    1.1.1标题3

    等...

    我们当前任务的很大一部分涉及添加对文档中其他部分的交叉引用。当文档运行到几百页并且每页上有大约10个引用时,这可能非常耗时。

    我想知道的是,是否可以设置宏来根据光标突出显示的内容添加x-ref。即如果你的句子是"请参阅第3.2和34条;你可以突出显示" 3.2"部分,运行宏并插入链接到标题3.2的x-ref。

    不确定这是否可能,但对任何建议都会感激不尽。

2 个答案:

答案 0 :(得分:1)

此代码将 - 有条件地 - 执行您想要的操作。

Sub InsertCrossRef()

    Dim RefList As Variant
    Dim LookUp As String
    Dim Ref As String
    Dim s As Integer, t As Integer
    Dim i As Integer

    On Error GoTo ErrExit
    With Selection.Range
        ' discard leading blank spaces
        Do While (Asc(.Text) = 32) And (.End > .Start)
            .MoveStart wdCharacter
        Loop
        ' discard trailing blank spaces, full stops and CRs
        Do While ((Asc(Right(.Text, 1)) = 46) Or _
                  (Asc(Right(.Text, 1)) = 32) Or _
                  (Asc(Right(.Text, 1)) = 11) Or _
                  (Asc(Right(.Text, 1)) = 13)) And _
                  (.End > .Start)
            .MoveEnd wdCharacter, -1
        Loop

ErrExit:
        If Len(.Text) = 0 Then
            MsgBox "Please select a reference.", _
                   vbExclamation, "Invalid selection"
            Exit Sub
        End If

        LookUp = .Text
    End With
    On Error GoTo 0

    With ActiveDocument
        ' Use WdRefTypeHeading to retrieve Headings
        RefList = .GetCrossReferenceItems(wdRefTypeNumberedItem)
        For i = UBound(RefList) To 1 Step -1
            Ref = Trim(RefList(i))
            If InStr(1, Ref, LookUp, vbTextCompare) = 1 Then
                s = InStr(2, Ref, " ")
                t = InStr(2, Ref, Chr(9))
                If (s = 0) Or (t = 0) Then
                    s = IIf(s > 0, s, t)
                Else
                    s = IIf(s < t, s, t)
                End If
                If LookUp = Left(Ref, s - 1) Then Exit For
            End If
        Next i

        If i Then
            Selection.InsertCrossReference ReferenceType:="Numbered item", _
                                           ReferenceKind:=wdNumberFullContext, _
                                           ReferenceItem:=CStr(i), _
                                           InsertAsHyperlink:=True, _
                                           IncludePosition:=False, _
                                           SeparateNumbers:=False, _
                                           SeparatorString:=" "
        Else
            MsgBox "A cross reference to """ & LookUp & """ couldn't be set" & vbCr & _
                   "because a paragraph with that number couldn't" & vbCr & _
                   "be found in the document.", _
                   vbInformation, "Invalid cross reference"
        End If
    End With
End Sub

以下是条件: -

  1. 文档中有“编号项”和“标题”。你问了标题。我做了Numbered Items,因为我的PC上没有这种风格。但是,在我的电脑上“标题”编号的项目。如果代码无法在您的文档中使用,请在代码中标记的行与wdRefTypeNumberedItem交换wdRefTypeHeading
  2. 我假设编号格式为“1”“1.1”,“1.1.1”。如果你有什么不同,也许“1”。 “1.1。”,“1.1.1。”,代码需要调整。关键点是代码将查找数字后面的空格或制表符。如果它后跟一个句号或右括号或短划线则不起作用。此外,如果您碰巧选择“1.2”。 (在文本中最后一个句号)代码将忽略句号并查找引用“1.2”。请注意,代码对选择中的偶然错误不敏感。它将删除任何前导或尾随空格以及意外包含的回车或段落标记 - 以及完全停止。
  3. 代码将用您自己的(相同的)文本替换您所做的选择。这可能会导致现有格式更改。实际上,插入的引用字段从目标中获取文本。我没有弄清楚它适用的格式,目标或被替换的格式。我没有处理这个问题,如果它是一个。

    请查看代码插入的交叉引用的属性。您将看到InsertAsHyperlink为True。如果您愿意,可以将其设置为False。 IncludePosition是假的。如果将此属性设置为True,则会在代码替换的数字中添加“above”或“below”。

答案 1 :(得分:0)

是的,这完全有可能......

但由于这不是代码编写服务,我会给你(一个例子)关键元素:

' Check if a reference exists
If instr(lcase(selection.Sentences(1).Text), "refer to clause") then

' Figure out the reference number...
(see here: https://stackoverflow.com/questions/15369485/how-to-extract-groups-of-numbers-from-a-string-in-vba)

' Get a list of available references
refList = ActiveDocument.GetCrossReferenceItems(wdRefTypeNumberedItem)

' Add the reference
selection.InsertCrossReference(wdRefTypeNumberedItem ,wdNumberFullContext, xxxxxx...

也许看看你可以获得多远,并回答更具体和专注的问题:)