Макрос для вставки перекрестной ссылки на основе выбора
В настоящее время я работаю в компании, которая использует установленный домашний стиль для своих документов. Это включает в себя многоуровневые пронумерованные заголовки, встроенные в наш шаблон Word. Т.е.
- Заголовок 1
1.1 Заголовок 2
1.1.1 Заголовок 3
так далее...
Большая часть нашей текущей задачи заключается в добавлении перекрестных ссылок на другие части документа. Это может занять довольно много времени, когда документ работает на нескольких сотнях страниц с примерно 10 ссылками на каждой странице.
Мне было интересно, можно ли настроить макрос для добавления x-ref на основе того, что выделено курсором. Т.е., если бы у вас было предложение, которое гласило "пожалуйста, обратитесь к пункту 3.2", вы могли бы выделить часть "3.2", запустить макрос и вставить x-ref, связанный с заголовком 3.2.
Не уверен, что это вообще возможно, но был бы благодарен за любой совет.
2 ответа
Этот код будет - условно - делать то, что вы хотите.
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
Вот условия:
- В документе есть "Нумерованные элементы" и "Заголовки". Вы просили заголовки. Я сделал Numbered Items, потому что у меня нет этого стиля на моем ПК. Однако на моем ПК "Заголовки" есть пронумерованные пункты. Если код не работает на ваших документах, обмен
wdRefTypeNumberedItem
заwdRefTypeHeading
в отмеченной строке в коде. - Я предполагал формат нумерации, такой как "1", "1.1", "1.1.1". Если у вас есть что-то другое, возможно, "1". "1.1.", "1.1.1.", Код необходимо будет настроить. Ключевым моментом является то, что код будет искать пробел или табуляцию после числа. Если за ним следует точка или закрывающая скобка или тире, это не сработает. Также, если вам случится выбрать "1.2". (с окончательной полной остановкой) в тексте код игнорирует полную остановку и ищет ссылку "1.2". Обратите внимание, что код нечувствителен к случайным ошибкам в выборе. Он удалит все начальные или конечные пробелы, а также случайно включенные возврат каретки или знаки абзаца - и точки остановки.
Код заменит выбранный вами текст своим (идентичным) текстом. Это может привести к изменению существующего форматирования. Фактически, вставленное поле ссылки берет текст от цели. Я не совсем понял, какой формат он применяет, цель или заменяемый. Я не занимался этой проблемой, если она одна.
Пожалуйста, взгляните на свойства перекрестной ссылки на вставки кода. Вы увидите, что InsertAsHyperlink
правда. Вы можете установить его в False, если хотите. IncludePosition
Неверно Если вы установите для этого свойства значение True, к номеру, который заменяет код, добавится "выше" или "ниже".
Да, это вполне возможно...
Но так как это не служба написания кода, я приведу вам (пример) ключевые элементы:
' Check if a reference exists
If instr(lcase(selection.Sentences(1).Text), "refer to clause") then
' Figure out the reference number...
(see here: https://stackru.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...
Возможно, посмотрите, как далеко вы можете получить, и отправьте ответ с более конкретными и целенаправленными вопросами:)