Word vba перекрестные ссылки

title keywords f1_keywords ms.prod api_name ms.assetid ms.date ms.localizationpriority

Selection.InsertCrossReference method (Word)

vbawd10.chm158663074

vbawd10.chm158663074

word

Word.Selection.InsertCrossReference

3aa9261d-8e2a-6230-8f02-629f0a0104bf

06/08/2017

medium

Selection.InsertCrossReference method (Word)

Inserts a cross-reference to a heading, bookmark, footnote, or endnote, or to an item for which a caption label is defined (for example, an equation, figure, or table).

Syntax

expression. InsertCrossReference( _ReferenceType_ , _ReferenceKind_ , _ReferenceItem_ , _InsertAsHyperlink_ , _IncludePosition_ , _SeparateNumbers_ , _SeparatorString_ )

expression Required. A variable that represents a Selection object.

Parameters

Name Required/Optional Data type Description
ReferenceType Required Variant The type of item for which a cross-reference is to be inserted. Can be any WdReferenceType or WdCaptionLabelID constant or a user defined caption label.
ReferenceKind Required WdReferenceKind The information to be included in the cross-reference.
ReferenceItem Required Variant If ReferenceType is wdRefTypeBookmark, this argument specifies a bookmark name. For all other ReferenceType values, this argument specifies the item number or name in the Reference type box in the Cross-reference dialog box. Use the GetCrossReferenceItems method to return a list of item names that can be used with this argument.
InsertAsHyperlink Optional Variant True to insert the cross-reference as a hyperlink.
IncludePosition Optional Variant True to insert «above» or «below,» depending on the location of the reference item in relation to the cross-reference.
SeparateNumbers Optional Variant True to use a separator to separate the numbers from the associated text. (Use only if the ReferenceType parameter is set to wdRefTypeNumberedItem and the ReferenceKind parameter is set to wdNumberFullContext.)
SeparatorString Optional Variant Specifies the string to use as a separator if the SeparateNumbers parameter is set to True.

Remarks

If you specify wdPageNumber for the value of ReferenceKind, you may need to repaginate the document to see the correct cross-reference information.

Example

This example inserts a sentence that contains two cross-references: one cross-reference to heading text, and another one to the page where the heading text appears.

With Selection 
 .Collapse Direction:=wdCollapseStart 
 .InsertBefore "For more information, see " 
 .Collapse Direction:=wdCollapseEnd 
 .InsertCrossReference ReferenceType:=wdRefTypeHeading, _ 
 ReferenceKind:=wdContentText, ReferenceItem:=1 
 .InsertAfter " on page " 
 .Collapse Direction:=wdCollapseEnd 
 .InsertCrossReference ReferenceType:=wdRefTypeHeading, _ 
 ReferenceKind:=wdPageNumber, ReferenceItem:=1 
 .InsertAfter "." 
End With

See also

Selection Object

[!includeSupport and feedback]

I have quite a large word document (> 400 pages) with lots of cross references to headings. So far, I have always referred to the title of the heading, but now I would like to change that and refer to the page the heading resides on.

I didn’t find a solution to this via the GUI (except manual treatment, of course), so I was looking into writing some VBA. Unfortunately, I have only found a way to list all targets that can be cross referenced (via GetCrossReferenceItems), but I need a way to access the actual cross reference field.

Can you help me with that? Is a cross reference field the same as a hyperlink?

0m3r's user avatar

0m3r

12.2k15 gold badges33 silver badges70 bronze badges

asked Jul 25, 2014 at 8:39

kafman's user avatar

1

Cross-references are fields in a Word document, and can be accessed via the Fields collection (ActiveDocument.Fields). You can loop through them like any other collection and check their types to see if it’s one you want to work on. It looks like cross-references to text are type 3 (wdFieldRef) and cross-references to page numbers are type 37 (wdFieldPageRef). Changing fields can be a little tricky; the following should get you started:

Sub ChangeFields()
    Dim objDoc As Document
    Dim objFld As Field
    Dim sFldStr As String
    Dim i As Long, lFldStart As Long

    Set objDoc = ActiveDocument
    ' Loop through fields in the ActiveDocument
    For Each objFld In objDoc.Fields
        ' If the field is a cross-ref, do something to it.
        If objFld.Type = wdFieldRef Then
            'Make sure the code of the field is visible. You could also just toggle this manually before running the macro.
            objFld.ShowCodes = True
            'I hate using Selection here, but it's probably the most straightforward way to do this. Select the field, find its start, and then move the cursor over so that it sits right before the 'R' in REF.
            objFld.Select
            Selection.Collapse wdCollapseStart
            Selection.MoveStartUntil "R"
            'Type 'PAGE' to turn 'REF' into 'PAGEREF'. This turns a text reference into a page number reference.
            Selection.TypeText "PAGE"
            'Update the field so the change is reflected in the document.
            objFld.Update
            objFld.ShowCodes = True
        End If
    Next objFld   
End Sub

answered Jul 25, 2014 at 19:44

Christina's user avatar

ChristinaChristina

1,3491 gold badge11 silver badges22 bronze badges

3

Show All

InsertCrossReference Method

Inserts a cross-reference to a heading, bookmark, footnote, or endnote, or to an item for which a caption label is defined (for example, an equation, figure, or table).

expression.InsertCrossReference(ReferenceType, ReferenceKind, ReferenceItem, InsertAsHyperlink, IncludePosition, SeparateNumbers, SeparatorString)

expression    Required. An expression that returns one of the objects in the Applies To list.

ReferenceType   Required Variant. The type of item for which a cross-reference is to be inserted. Can be any WdReferenceType
or WdCaptionLabelID
constant or a user defined caption label.

WdReferenceType can be one of these WdReferenceType constants.
wdRefTypeBookmark
wdRefTypeEndnote
wdRefTypeFootnote
wdRefTypeHeading
wdRefTypeNumberedItem
WdCaptionLabelID can be one of these WdCaptionLabelID constants.
wdCaptionEquation
wdCaptionFigure
wdCaptionTable

ReferenceKind   Required WdReferenceKind. The information to be included in the cross-reference.

WdReferenceKind can be one of these WdReferenceKind constants.
wdContentText
wdEndnoteNumber
wdEndnoteNumberFormatted
wdEntireCaption
wdFootnoteNumber
wdFootnoteNumberFormatted
wdNumberFullContext
wdNumberNoContext
wdNumberRelativeContext
wdOnlyCaptionText
wdOnlyLabelAndNumber
wdPageNumber
wdPosition

ReferenceItem   Required Variant. If ReferenceType is wdRefTypeBookmark, this argument specifies a bookmark name. For all other ReferenceType values, this argument specifies the item number or name in the Reference type box in the Cross-reference dialog box. Use the GetCrossReferenceItems
method to return a list of item names that can be used with this argument.

InsertAsHyperlink   Optional Variant. True to insert the cross-reference as a hyperlink to the referenced item.

IncludePosition   Optional Variant. True to insert «above» or «below,» depending on the location of the reference item in relation to the cross-reference.

SeparateNumbers Optional Variant. True to use a separator to separate the numbers from the associated text. (Use only if the ReferenceType parameter is set to wdRefTypeNumberedItem and the ReferenceKind parameter is set to wdNumberFullContext.)

SeparatorString Optional Variant. Specifies the string to use as a separator if the SeparateNumbers parameter is set to True.

Remarks

If you specify wdPageNumber for the value of ReferenceKind, you may need to repaginate the document in order to see the correct cross-reference information.

Example

This example inserts at the beginning of the active document a cross-reference to the page that includes the first bookmark in the document.

Set myRange = ActiveDocument.Range(Start:=0, End:=0)
myBookmarks = ActiveDocument _
    .GetCrossReferenceItems(wdRefTypeBookmark)
With myRange
    .InsertBefore "Page "
    .Collapse Direction:=wdCollapseEnd
    .InsertCrossReference ReferenceType:=wdRefTypeBookmark, _
        ReferenceKind:=wdPageNumber, ReferenceItem:=myBookmarks(1)
End With
		

This example inserts a sentence that contains two cross-references: one cross-reference to heading text, and another one to the page where the heading text appears.

With Selection
    .Collapse Direction:=wdCollapseStart
    .InsertBefore "For more information, see "
    .Collapse Direction:=wdCollapseEnd
    .InsertCrossReference ReferenceType:=wdRefTypeHeading, _
        ReferenceKind:=wdContentText, ReferenceItem:=1
    .InsertAfter " on page "
    .Collapse Direction:=wdCollapseEnd
    .InsertCrossReference ReferenceType:=wdRefTypeHeading, _
        ReferenceKind:=wdPageNumber, ReferenceItem:=1
    .InsertAfter "."
End With
		

Этот код будет — условно — делать то, что вы хотите.

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, потому что у меня нет этого стиля на моем ПК. Однако на моем ПК «Заголовки» есть пронумерованные пункты. Если код не работает на ваших документах, обмен wdRefTypeNumberedItem за wdRefTypeHeading в отмеченной строке в коде.
  2. Я предполагал формат нумерации, такой как «1», «1.1», «1.1.1». Если у вас есть что-то другое, возможно, «1». «1.1.», «1.1.1.», Код необходимо будет настроить. Ключевым моментом является то, что код будет искать пробел или табуляцию после числа. Если за ним следует точка или закрывающая скобка или тире, это не сработает. Также, если вам случится выбрать «1.2». (с окончательной полной остановкой) в тексте код игнорирует полную остановку и ищет ссылку «1.2». Обратите внимание, что код нечувствителен к случайным ошибкам в выборе. Он удалит все начальные или конечные пробелы, а также случайно включенные возврат каретки или знаки абзаца — и точки остановки.

Код заменит выбранный вами текст своим (идентичным) текстом. Это может привести к изменению существующего форматирования. Фактически, вставленное поле ссылки берет текст от цели. Я не совсем понял, какой формат он применяет, цель или заменяемый. Я не занимался этой проблемой, если она одна.

Пожалуйста, взгляните на свойства перекрестной ссылки на вставки кода. Вы увидите, что InsertAsHyperlink правда. Вы можете установить его в False, если хотите. IncludePosition Неверно Если вы установите для этого свойства значение True, к номеру, который заменяет код, добавится «выше» или «ниже».

Простое создание связи (перекрёстной ссылки) в Word

Alex_ST

Дата: Среда, 11.07.2012, 10:20 |
Сообщение № 1

Группа: Друзья

Ранг: Участник клуба

Сообщений: 3176


Репутация:

604

±

Замечаний:
0% ±


2003

Совершенно случайно наткнулся на мало кому известный, но очень удобный хоткей Ворда!
Оказывается, создать в документе связь (автоматически обновляемый дубликат какого-то другого его фрагмента — аналог инструмента «камера» в Excel’e) очень просто.
Достаточно выделить копируемый текст-образец, нажать ОДНОВРЕМЕННО Ctrl+Shift и утащить выделенный текст в нужное место документа мышкой (ЛКМ).
Полученная копия окажется OLELink-объектом, значение и формат которого будет автоматически меняться при изменении образца.

biggrin Смешно то, что я наткнулся на этот хоткей действительно случайно: при копировании выделил текст и, собравшись зажать Ctrl и тянуть фрагмент ЛКМ, зацепил «сарделькой» ещё и Shift… А когда скопировалось, получилась не копия, а ссылка.

К сообщению приложен файл:

OLELink.doc
(19.0 Kb)



С уважением,
Алексей
MS Excel 2003 — the best!!!

Сообщение отредактировал Alex_STЧетверг, 12.07.2012, 09:43

 

Ответить

vikttur

Дата: Четверг, 12.07.2012, 09:49 |
Сообщение № 2

Группа: Друзья

Ранг: Участник клуба

Сообщений: 2941

Спасибо, пригодится.

 

Ответить

Alex_ST

Дата: Четверг, 12.07.2012, 11:52 |
Сообщение № 3

Группа: Друзья

Ранг: Участник клуба

Сообщений: 3176


Репутация:

604

±

Замечаний:
0% ±


2003

Пожалуйста, Вить, юзай.
А круто я по кнопочке-то промахнулся! biggrin
Аж сам удивился, что так просто можно делать то, что вообще стандартными средствами не делалось (ведь обычную перекрёстную ссылку поставить можно только на абзац, заголовок, закладку, сноску, рисунок, таблицу, но никак не на произвольный фрагмент текста, да ещё и с форматированием).



С уважением,
Алексей
MS Excel 2003 — the best!!!

 

Ответить

Alex_ST

Дата: Четверг, 12.07.2012, 12:50 |
Сообщение № 4

Группа: Друзья

Ранг: Участник клуба

Сообщений: 3176


Репутация:

604

±

Замечаний:
0% ±


2003

Ну, а из экспериментов с новым хоткеем родились и два макроса:
Первый макрос: Вставить не форматированную связь (такую связь можно форматировать на месте и её формат не зависит от формата источника)[vba]

Code

Sub InsertUnFormatedLink()
       With Selection
          If .Type <> wdSelectionNormal And .Type <> wdSelectionIP Then MsgBox «ERROR»: Exit Sub
          .PasteSpecial Link:=True, DataType:=wdPasteText
       End With
End Sub

[/vba]Таким макросом удобно, например, какое-то название из текста (ну, например, «Регламент взаимодействия с ЗАО «Рога и Копыта») вставить в колонтитул. Тогда при изменении текста в документе одновременно изменятся и колонтитулы. Второй макрос: Вставить форматированную связь (формат такой связи зависит от формата источника — это точно то же самое, что получается при «тягании» выделенного фрагмента ЛКМ+Ctrl+Shift)[vba]

Code

Sub InsertFormatedLink()
       With Selection
          If .Type <> wdSelectionNormal And .Type <> wdSelectionIP Then MsgBox «ERROR»: Exit Sub
          .PasteSpecial Link:=True, DataType:=wdPasteRTF
       End With
End Sub

[/vba]Правда, куда это можно с толком применить, пока не придумал smile



С уважением,
Алексей
MS Excel 2003 — the best!!!

Сообщение отредактировал Alex_STЧетверг, 12.07.2012, 22:28

 

Ответить

#excel #vba #bookmarks #cross-reference

Вопрос:

Я пытаюсь получить нумерованные местоположения моих закладок (номер абзаца без контекста) в документе Word (длинный шаблон юридического документа) и. В настоящее время я использую следующий код для извлечения текстовых значений с закладками из документа Word в книгу Excel, которую я создал, чтобы получить другие данные из других источников, но я не смог понять, как манипулировать кодом, чтобы захватить номера абзацев в закладках (я тоже искал их повсюду, и я новичок в VBA. Я знаю ровно столько, чтобы быть опасным, но недостаточно, чтобы быть полезным, лол). Пожалуйста, Помогите!

 Sub SectionLocationImportTESTING()
Dim intDocCount As Integer
Dim wdApp As Word.Application, wdDoc As Word.Document, xlWb As Excel.Workbook, xlWs As Excel.Worksheet
Dim BookmarkText As String

Set wdApp = GetObject(, "Word.Application")
On Error GoTo 0

If wdApp Is Nothing Then
    MsgBox "There are no MS Word Documents open.", vbInformation, "No Word Documents open"
    Exit Sub
End If

Set xlWb = ThisWorkbook
Set xlWs = ActiveWorkbook.Sheets("Data Input")
intDocCount = wdApp.Documents.Count

If intDocCount > 1 Then
    MsgBox "There are " amp; intDocCount amp; " Word Documents open." amp; vbNewLine amp; vbNewLine amp; _
    "Please close the additional MS Word Documents", vbCritical, "Too many Word Documents open!"
    Set wdApp = Nothing
    Exit Sub
End If

With wdApp
    Set wdDoc = wdApp.ActiveDocument
    wdDoc.Activate
    
'This is very abbreviated, I have about 300 bookmarks that transfer

If wdDoc.Bookmarks.Exists("Section_Rent") = True Then
    BookmarkText = wdDoc.Bookmarks("Section_Rent").Range.Text
xlWs.Cells(202, 22) = ("Section_Rent")
xlWs.Cells(202, 23) = BookmarkText
End If

End With

    ActiveWorkbook.RefreshAll
    ActiveSheet.PivotTables("Data_Input_Table").PivotFields("Trimmed Data"). _
    PivotFilters.Add2 Type:=xlCaptionIsGreaterThan, Value1:="0"
    

    Columns("D:D").EntireColumn.AutoFit
    Range("A1").Select

MsgBox "Transfer is complete."

End Sub
 

Комментарии:

1. Вы ищете автоматически пронумерованный текст абзаца закладки? например, (a), (1) и т. Д. В вашем коде это может быть wdDoc.Bookmarks("Section_Rent").Range.ListFormat.ListString , и вместо жесткого кодирования имени вашей закладки вы можете подумать о циклическом просмотре коллекции закладок (но я надеюсь, что у вас есть формат для закладки, который вы можете использовать для фильтрации, поскольку закладка, как правило, используется и для множества других вещей).

2. Я понятия не имею, что такое автоматический номер. Я хотел бы, чтобы word сообщил excel, в каком номере раздела находится текст, который я добавляю в закладку. Как номер раздела с перекрестной ссылкой из word.

3. Я также понятия не имею, что такое зацикливание и как это делается.

4. Основываясь на вашем комментарии в ответе Тима, то, что вы хотите, должно быть wdDoc.Bookmarks("Section_Rent").Range.ListFormat.ListString .

Ответ №1:

Я не думаю, что есть прямой способ сделать это.
Вы могли бы сделать это, например:

 Sub Tester()
    Debug.Print ParagraphNumber(Selection.Range)
End Sub


Function ParagraphNumber(rng As Range)
    ParagraphNumber = rng.Document.Range(0, rng.End).Paragraphs.Count
End Function
 

…но это также будет учитывать «пустые» абзацы.

Если у вас много закладок, вы можете просмотреть список имен на листе Excel, а затем выполнить цикл по этому диапазону для извлечения текста. Если вы жестко закодируете все эти имена в свой VBA, это будет очень сложно поддерживать.

Напр.

 '...
Dim c As Range, bm As String, rngBM As Word.Range

'...
'...

Set wdDoc = wdApp.ActiveDocument
wdDoc.Activate
'range with your bookmark names
Set rngBM = ThisWorkbook.Sheets("Bookmarks").Range("A2:A300")

For Each c In rngBM.Cells
    bm = c.Value 'bookmark name
    If wdDoc.Bookmarks.Exists(bm) Then
        Set rngBM = wdDoc.Bookmarks(bm).Range
        'for demo purposes just putting info next to the bookmark name...
        c.Offset(0, 1).Value = rngBM.Text
        c.Offset(0, 2).Value = ParagraphNumber(rngBM)
    End If
Next c
 

Комментарии:

1. У меня есть формула excel, которая объединяет имеющиеся у меня закладки в общие формулы. Я надеялся, что есть какой-то способ интегрировать «перекрестную ссылку» или «перекрестную ссылку», которые, как я вижу, используются в word. Пример: Выбор. Тип ссылки InsertCrossReference:=»Закладка», ссылка на ссылку:= _ wdNumberNoContext, элемент ссылки:=»SECTION_RENT», ссылка на вставку:=True _ , Включение:=Ложь, Отдельные номера:=Ложь, строка разделителя:=» » Но в любом случае я понятия не имею, как подключить то, что вы только что перечислили… ПОЛНЫЙ новичок.

2. *** Это не позволит мне редактировать, у меня есть рабочий лист excel, который генерирует основную часть кода для закладок. это более 800 строк, поэтому я не включил его сюда

3. Если вы используете Excel для создания VBA, то вместо этого вы можете использовать ту же информацию для управления извлечением (т. Е. Без создания более 800 строк VBA). Однако вы показываете только одну отметку книги, поэтому трудно увидеть, какой схеме следуют другие. Это может помочь вашему вопросу включить скриншот части документа (отредактированный соответствующим образом) с указанием расположения примера закладки и «Номера абзаца», который вы хотите извлечь вместе с текстом закладки.

Ответ №2:

Есть 2 способа получить номер абзаца, в зависимости от того, что вы хотите:

Вариант 1

Это позволит получить точную строку автоматической нумерации, которую вы видите в самом абзаце:

Например, приведенный ниже абзац поможет вам 1.

  1. Это тестовый абзац.
 If wdDoc.Bookmarks.Exists("Section_Rent") Then
    Dim BookmarkText As String
    BookmarkText = wdDoc.Bookmarks("Section_Rent").Range.Text
                    
    xlWs.Cells(202, 22) = "Section_Rent"
    xlWs.Cells(202, 23) = BookmarkText
            
    Dim BookmarkParaNum As String
    BookmarkParaNum = wdDoc.Bookmarks("Section_Rent").Range.ListFormat.ListString
    
    xlWs.Cells(202, 24) = BookmarkParaNum
End If
 

Вариант 2
Это приведет к получению строки, которую вы увидите, если вставите перекрестную ссылку на абзац:

Использование приведенного ниже кода для того же абзаца в варианте 1 даст вам то 1 же самое , что и вставка его в качестве перекрестной ссылки.

 wdDoc.Paragraphs.Last.Range.InsertParagraphAfter 'A temporary paragraph for inserting field later

Dim fieldRng As Range
Set fieldRng = wdDoc.Paragraphs.Last.Range.Duplicate

If wdDoc.Bookmarks.Exists("Section_Rent") Then
    Dim BookmarkText As String
    BookmarkText = wdDoc.Bookmarks("Section_Rent").Range.Text
                            
    xlWs.Cells(202, 22) = "Section_Rent"
    xlWs.Cells(202, 23) = BookmarkText
                            
    fieldRng.InsertCrossReference ReferenceType:="Bookmark", ReferenceKind:=wdNumberNoContext, ReferenceItem:="Section_Term", InsertAsHyperlink:=True, IncludePosition:=False, SeparateNumbers:=False, SeparatorString:=" "
    Dim tempField As Field
    Set tempField = fieldRng.Fields(1)
    
    Dim BookmarkParaNum As String
    BookmarkParaNum = tempField.Result
       
    xlWs.Cells(202, 24) = BookmarkParaNum
    
    tempField.Delete
End If

fieldRng.Delete 'Delete the temporary paragraph
 

Like this post? Please share to your friends:
  • Word vba межстрочный интервал
  • Word vba массив строк
  • Word vba add row and table
  • Word vba activedocument saved
  • Word vba activedocument save