查找标题选择号以及前一个标题号

时间:2018-03-29 17:01:56

标签: excel vba ms-word

我试图通过文本的选择来获取单词VBA中的选项的标题级别号码和所有前面的标题级别号码。例如:

10.1

10.1.1

10.1.1.1

"这是我的文字"

我希望能够选择"这是我的文字"并将每个标题级别(即10.1.1.1,10.1.1,10.1)写入数组,以便我可以将每个值写入Excel中的单独单元格。

我提出了一个使用的解决方案。

oWord.Selection.GoTo(wdGoToHeading, wdGoToPrevious).Select

获取文本" 10.1.1.1"然后我进入各种循环,循环通过每个前一个标题以确定标题级别并获得它们的编号,如下所示。

HeadingSearch4:

                    If oWord.Selection.Style = "Heading 4" Then
                            Do
                                prevHeading = oWord.Selection.Style
                                oWord.Selection.GoTo(wdGoToHeading, wdGoToPrevious).Select
                                prevHeading = oWord.Selection.Style
                            Loop Until prevHeading = "Heading 3"
                        GoTo HeadingSearch3
                    End If

HeadingSearch3:

                    If oWord.Selection.Style = "Heading 3" Then
                        lgHeading3num = oWord.Selection.Paragraphs(1).Range.ListFormat.ListString
                            Do
                                prevHeading = oWord.Selection.Style
                                oWord.Selection.GoTo(wdGoToHeading, wdGoToPrevious).Select
                                prevHeading = oWord.Selection.Style
                            Loop Until prevHeading = "Heading 2"
                        GoTo HeadingSearch2
                    End If
HeadingSearch2:
                    If oWord.Selection.Style = "Heading 2" Then
                        lgHeading2num = oWord.Selection.Paragraphs(1).Range.ListFormat.ListString
                            Do
                                prevHeading = oWord.Selection.Style
                                oWord.Selection.GoTo(wdGoToHeading, 
wdGoToPrevious).Select
                                prevHeading = oWord.Selection.Style
                            Loop Until prevHeading = "Heading 1"
                        GoTo HeadingSearch1
                    End If
HeadingSearch1:
                    If oWord.Selection.Style = "Heading 1" Then
                        lgHeading1num = "Section " & oWord.Selection.Paragraphs(1).Range.ListFormat.ListString
                    End If

显然,当我在轮廓深处(即10.10.5.5)获得几个级别时,这需要花费大量时间,因为它必须遍历每个前一个标题,而不管标题级别。

我的问题是......是否有更简单的使用方法。

oWord.Selection.GoTo(wdGoToHeading, wdGoToPrevious).Select

转到上一个标题级别?例如,如果我的文字位于" 10.1.5"下,我可以直接进入" 10.1"没有循环前面的标题3的其余部分?或者我有选择的属性,我错过了吗?我无法找到一种方法来使用" wdGoToPrevious"进入下一个最高标题。非常感谢任何帮助,谢谢!

2 个答案:

答案 0 :(得分:0)

我将使用伪代码只是因为我没有时间在Word中完全测试它。

我将以不同的方式解决您的问题。

  • 重要的一点是不要使用Selection - 选择可以 根据代码或用户输入进行更改,您可能没有意识到这一点。
  • 我将在Whole Document范围的上下文中使用内置的Paragraphs集合(为了我的伪代码,我们将其称为wdAllDocRange。)

我最初考虑使用Turing-tape风格的流程。但是下面的代码确定了一种更简单的方法。

Dim counter as Long ' set up the navigation
Dim coll as Collection
Counter = 1 ' start at the beginning
While counter < wdAllDocRange.Paragraphs.Count ' error check - we have reached the end of file
    GetCurrentLevel wdAllDocRange.Paragraphs(counter) 'Code here to get current level
    if a Heading
        if a new level then
            coll.add currentlevel
        else if same level then
            coll.replace lastlevel with currentlevel number
        else if a previous level then
            coll.removelevels until at the right level then set level number
    else
        output coll and text into the array for further use
    endif
    counter = counter + 1
Loop

上面的代码使用了一个老式的循环(因为我想在这个范围内来回移动),但实际上你可以将所有主代码包含在for-each循环中

Dim coll as Collection
Dim para as Paragraph
For Each para in wdAllDocRange.Paragraphs 
    GetCurrentLevel para 'Code here to get current level
    if a Heading
        if a new level then
            coll.add currentlevel
        else if same level then
            coll.replace lastlevel with currentlevel number
        else if a previous level then
            coll.removelevels until at the right level then set level number
    else
        output coll and text into the array for further use
    endif
Next

答案 1 :(得分:0)

根据以下内容尝试:

Sub Demo()
Dim Rng As Range, i As Long, j As Long, StrOut As String
Set Rng = Selection.Range: j = 10
Do While Rng.Paragraphs.First.Range.Style <> "Heading 1"
  If InStr(Rng.Paragraphs.First.Range.Style, "Heading") <> 0 Then
    i = CLng(Split(Rng.Paragraphs.First.Range.Style, " ")(1))
    If i < j Then
      j = i
      StrOut = Rng.Paragraphs.First.Range.ListFormat.ListString & ", " & StrOut
    End If
  End If
  Rng.Start = Rng.Start - 1
  Set Rng = Rng.GoTo(What:=wdGoToBookmark, Name:="\HeadingLevel")
Loop
StrOut = Rng.Paragraphs.First.Range.ListFormat.ListString & ", " & StrOut
MsgBox StrOut
End Sub