Создание номера динамического списка в MS Word с использованием VBA

avatar
nafarkash
8 апреля 2018 в 11:44
1278
1
0

Интересно, как вставить номера динамического многоуровневого списка.
Клиент запрашивает применение своего шаблона Word 2010 «Заголовки точек» — аналогично поведению страниц точек.

Значение:
Предполагая следующие форматы заголовков:
Заголовок 2 - 1.1
Заголовок 3 - 1.1.1
Заголовок 4 - 1.1.1.1
Заголовок 5 - 1.1.1.1.1

Цель состоит в том, чтобы сохранить существующую нумерацию и добавить промежуточный нумерованный список.
Например:
Между двумя заголовками 1.3.5 и 1.3.6 в стиле Заголовка 3 будет 1.3.5.A, за которым следует 1.3.5.B и так далее. очевидно, требование состоит в том, что 1.3.6 не будет изменен.

Что я хочу получить и самый простой способ туда добраться (на мой взгляд):
Мне нужны 4 макроподпрограммы (по одной для каждого стиля заголовка), которые будут вставлять в текущую позицию курсора (можно предположить, что Selection - это только место курсора) выбранный «точечный заголовок».

Я думал выполнить следующий поток:
(Формат строки: Действие — Пример)

  • Применить выбранный стиль (скажем, Заголовок 3) - результат: 1.2.3
  • Найти предыдущее значение (можно предположить, что оно не первое) - результат: 1.2.2
  • Скопируйте содержимое строки (используя ListFormat.ListString) - результат: значение 1.2.2 скопировано
  • Применить новый стиль к этому конкретному местоположению с алфавитным числовым форматом и префиксом, который у меня есть. - результат: номер списка будет 1.2.2.A

Что я уже пробовал:

  • Первая проверка работоспособности состояла в том, чтобы вручную вставить новый стиль списка в меню многоуровневого списка. Проблема в том, что этот стиль нельзя использовать более одного раза (по крайней мере, я так видел). Если я захочу изменить префикс номера, он будет применяться ко всем его дочерним элементам с тем же стилем.

  • Затем я попробовал фрагмент кода, взятый из ЗДЕСЬ с некоторыми изменениями

    Sub applyPointHeadingTest()
    With ListGalleries(wdOutlineNumberGallery).ListTemplates(1).ListLevels(2)
        .NumberFormat = "1.1.%2"
        .TrailingCharacter = wdTrailingSpace
        .NumberStyle = wdListNumberStyleUppercaseLetter
        .NumberPosition = CentimetersToPoints(0)
        .Alignment = wdListLevelAlignLeft
        .TextPosition = CentimetersToPoints(5.31)
        .TabPosition = CentimetersToPoints(5.95)
        .StartAt = 1
        .LinkedStyle = "Point Heading Style 2"
    End With
    
    ListGalleries(wdOutlineNumberGallery).ListTemplates(1).name = "ComplexNo2"
    Selection.Range.ListFormat.ApplyListTemplateWithLevel ListTemplate:= _
        ListGalleries(wdOutlineNumberGallery).ListTemplates(1), _
        ContinuePreviousList:=True, ApplyTo:=wdListApplyToSelection, _
        DefaultListBehavior:=wdWord10ListBehavior
    End Sub
    

    Хотя это работает в первый раз, когда я запускаю метод, при следующих запусках он изменяет каждый список в документе.

  • В основном это все. У меня нет идей..

Кто-нибудь может подсказать, как это сделать?

Спасибо.

Источник
Cindy Meister
8 апреля 2018 в 14:18
1

Сделайте 1.2.3.A другим уровнем заголовка (4 или 5). Последующие уровни заголовков должны игнорировать нумерацию этого уровня (пропускать — не включать). Вам не нужен макрос или какой-либо новый стиль списка.

nafarkash
9 апреля 2018 в 07:42
0

Спасибо, это элегантный способ. Тем не менее, в моей ситуации используются стили заголовков 6-9. Есть ли другой способ?

Cindy Meister
9 апреля 2018 в 07:58
1

Посмотрите на коды полей, точнее: StyleRef и SEQ.

Ответы (1)

avatar
Cindy Meister
9 апреля 2018 в 12:05
2

Коды полей могут использоваться для "прерывистой" нумерации, связанной с нумерацией заголовков, но по какой-то причине не подходящей для шаблона списка, назначенного уровням заголовков. Эта нумерация является динамической в ​​том смысле, что она обновляется в соответствии с предшествующей нумерацией. Однако он не может обновляться автоматически — результаты поля необходимо обновлять либо вручную (F9, чаще всего Ctrl+A, F9 для всего документа), либо с помощью макроса (Fields.Update). Вы также можете настроить параметры печати документа для автоматического обновления полей.

Для описываемой вами ситуации эта пара полей должна работать:

{ StyleRef 3 \n }{ SEQ "between" \* ALPHABETIC \s 3 }
  • StyleRef отражает первый предшествующий экземпляр указанного стиля. В данном случае это «Заголовок 3» — вы можете использовать от 1 до 9, чтобы указать встроенный стиль заголовка, который делает поле независимым от местного языка.
  • В \n отображается только нумерация, без текста.
  • SEQ вставляет последовательную нумерацию — вы даете ему метку для нумерации, принадлежащей этой последовательности во всем документе.
  • \* ALPHABETIC помещает результат в заглавные буквы.
  • \s позволяет вам сказать, с какого уровня заголовка и далее следует перезапустить нумерацию.

Если вы хотите использовать код для вставки этих полей, то что-то вроде этого:

Dim rng As word.Range
Dim fld As word.Field
Dim sQuote As String

sQuote = Chr(34)
Set rng = Selection.Range
Set fld = rng.Fields.Add(rng, wdFieldEmpty, "StyleRef 3 \n", False)
Set rng = fld.result
'Move focus after the inserted field
rng.Collapse wdCollapseEnd
rng.MoveStart wdCharacter, 1
rng.InsertAfter "."
rng.Collapse wdCollapseEnd
rng.Fields.Add rng, wdFieldEmpty, "SEQ " & sQuote & "between" & _
                    sQuote & " \* ALPHABETIC \s 3", False
rng.Parent.Fields.Update 'update fields in the document body
nafarkash
10 апреля 2018 в 07:31
0

Как всегда - элегантно, организованно и отлично работает. Спасибо!