Как получить уровень списка, когда в списке есть новый параграф - PullRequest
0 голосов
/ 14 декабря 2018

Я перебираю абзацы документа Word, используя VB.Документ содержит маркированные списки.

Я нашел, как проверить, является ли текущий абзац элементом маркированного списка:

If (Not pParagraph.Range.ListFormat.List Is Nothing) Then
  ...
End If

Я хотел бы различать две следующие ситуации вДокумент Word:

Ситуация 1:

  • Первый абзац первого элемента

    Второй абзац первого элемента

  • Первый абзац второго элемента

Ситуация 2:

  • Первый (и единственный) элемент первого маркированного списка

Некоторый текст между двумя маркированными списками

  • Первый (и единственный) элемент второго маркированного списка

Когда я анализирую второй абзац, какмогу ли я узнать, нахожусь ли я в первой или второй ситуации?

В целом, если существует несколько уровней списка, как я могу узнать, на каком уровне находится мой абзац?

(яизвестно, что я могу проверить pParagraph.Range.ListFormat.ListLevelNumber, но это работает только для абзацев, соответствующих новым элементам;есть новый абзац без элемента, pParagraph.Range.ListFormat.List - ничто, а уровень - всегда 1).

Ответы [ 2 ]

0 голосов
/ 18 декабря 2018

Я наконец нашел способ сделать то, что хотел.

Каждый раз, когда у меня есть абзац, соответствующий открытию списка, я записываю левый отступ этого абзаца, используя pParagraph.LeftIndent.Поскольку в списке может быть несколько уровней, я записываю стек, содержащий отступ каждого открытого в данный момент уровня.

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

Например, в этом примере:

  • Уровень 1 уровня 1

    • Уровень элемента 1 2

      Линия 1

    Линия 2

Строка 3

Я могу сделать вывод, что "Строка 1" является частью "Предмета 1 уровня2", "Строка 2" является частью "Предмета 1 уровня 1", а "Строка 3" выходит за пределысписок.

0 голосов
/ 17 декабря 2018

Я только изредка работаю с Word-VBA, и это только для записи в слове из какого-то кроссплатформенного приложения, а не для интенсивной обработки любого документа Word.Я могу честно назвать себя новичком в Word_VBA.Тем не менее, найдя это интересным, я прошел через поиск в Интернете и узнал некоторые интересные моменты.

По крайней мере, в Word 2007 (я использую только 2007) не может быть абзаца внутри элемента списка (т. Е. Ситуация 1: второй абзац первого элемента) .Пожалуйста, обратитесь к link1 , link2 & link3 .

Предполагая, что вам необходимо трактовать Ручные разрывы строк как абзац и требовать наличия соответствующего объекта диапазона, текста, уровня списка, значения списка и т. Д. Для дальнейшей обработки, якак-то прийти к рабочему решению.Он работает с временной выборкой из 3-х уровней вложенного списка и ручных разрывов строк.Можно попробовать код

Sub test()
Dim Pg As Paragraph, Sl As Long, Rng As Range, LineRng As Range
Dim PgType As String, ListNo As Long, LevelNo As Long, PgTxt As String, LIneTxt As String
Dim ManNewLine As Long, St As Long
Sl = 0
    For Each Pg In ThisDocument.Paragraphs
        If Pg.Range.ListFormat.List Is Nothing Then
        PgType = "Normal Para"
        Else
        PgType = "List Para"
        End If
    Set Rng = Pg.Range
    ListNo = Pg.Range.ListFormat.ListValue  ' Document level Paragraph will return zero as ListValue. 
    LevelNo = Pg.Range.ListFormat.ListLevelNumber
    PgTxt = Pg.Range.Text

    'Add the below section code for treating Manual Line breaks as pargarph
    'Start of code section
    St = 1
    ManNewLine = InStr(St, PgTxt, Chr(11))
        If ManNewLine > 0 Then
            Do While ManNewLine > 0 And St <= Len(PgTxt)
            Sl = Sl + 1
            LineRng.SetRange Start:=Rng.Characters(St).Start, End:=Rng.Characters(ManNewLine).End
            LIneTxt = LineRng.Text
            'Debug.Print St, ManNewLine, LIneTxt
            'Process Paragraph based on LineRng, PgType, ListNo, LevelNo, LIneTxt, Sl
            ProcessParagraph LineRng, PgType, ListNo, LevelNo, LIneTxt, Sl
            St = ManNewLine + 1
            ManNewLine = InStr(St, PgTxt, Chr(11))
            ManNewLine = IIf(ManNewLine <= 0, Len(PgTxt), ManNewLine)
            Loop
        Else
        Sl = Sl + 1
        Set LineRng = Rng
        LIneTxt = PgTxt
        'Process Paragraph based on LineRng, PgType, ListNo, LevelNo, LIneTxt, Sl
        ProcessParagraph LineRng, PgType, ListNo, LevelNo, LIneTxt, Sl
        End If
    'End of code section
    Next Pg
End Sub
Private Sub ProcessParagraph(LineRng As Range, PgType As String, ListNo As Long, LevelNo As Long, LIneTxt As String, Sl As Long)
'Remark = "Para Type:" & PgType & " List No=" & ListNo & " ListLevel=" & LevelNo & "*" & LIneTxt & "*"
'Debug.Print "Sl=" & Sl & Remark
'add your code to Process Paragraph based on LineRng, PgType, ListNo, LevelNo, LIneTxt, Sl
End Sub

рад, если найдется полезным.

...