一旦与...一起使用,Word宏将无法正常工作。

时间:2018-07-04 15:34:44

标签: vba word-vba

我今天在制作宏时经历了一些奇怪的事情。 我有很多使用相同模板的文档,因此我的宏扫描其中一个文档,并根据标题(级别和编号)进行一些处理。无论如何,这并不重要。这是代码

Private Sub MyMacro()
     Selection.HomeKey Unit:=wdStory

        While Not (Left(Selection.Paragraphs(1).Range.ListFormat.ListString, 1) = "3")  'go to Title n°3
            Selection.GoTo what:=wdGoToHeading, which:=wdGoToNext
        Wend

        While ((Left(Selection.Paragraphs(1).Range.ListFormat.ListString, 1) = "3"))  'do not go further than title n°3
            'if the curent title level is 2 and ended with 1,2 or 3 then
            If Selection.Paragraphs(1).Range.ListFormat.ListLevelNumber = 2 And Selection.Paragraphs(1).Range.ListFormat.ListValue < 4 Then
                'Do Something
            ElseIf Selection.Paragraphs(1).Range.ListFormat.ListLevelNumber = 3 And Selection.Paragraphs(1).Range.ListFormat.ListValue <> 4 And Left(Selection.Paragraphs(1).Range.ListFormat.ListString, 4) = "3.1." Then
                'Do something else
            ElseIf Selection.Paragraphs(1).Range.ListFormat.ListLevelNumber = 4 And Left(Selection.Paragraphs(1).Range.ListFormat.ListString, 5) = "3.2.1" Then
                'and a last one
            End If
            'go to the next title in the document
            Selection.GoTo what:=wdGoToHeading, which:=wdGoToNext
        Wend
End Sub

此代码有效,但是如您所见,它并不是很容易阅读... 我尝试插入With...End With语句来改善这一点。

    With Selection.Paragraphs(1).Range.ListFormat
        'isert here the same code as before with only .ListString and .ListLevelNumber
    End With

不幸的是,这使我的While循环失败了,我不知道为什么。 我监视了输出,看来ListString总是返回第一个标题(宏开始的地方)。 你知道为什么吗?

非常感谢

致谢

编辑: 最终的代码应该看起来像这样

Private Sub MyMacro()
Selection.HomeKey Unit:=wdStory

With Selection.Paragraphs(1).Range.ListFormat
    While Not (Left(.ListString, 1) = "3")  'go to Title n°3
        Selection.GoTo what:=wdGoToHeading, which:=wdGoToNext
    Wend

    While ((Left(.ListString, 1) = "3"))  'do not go further than title n°3
        'if the curent title level is 2 and ended with 1,2 or 3 then
        If .ListLevelNumber = 2 And .ListValue < 4 Then
            'Do Something
        ElseIf .ListLevelNumber = 3 And .ListValue <> 4 And Left(.ListString, 4) = "3.1." Then
            'Do something else
        ElseIf .ListLevelNumber = 4 And Left(.ListString, 5) = "3.2.1" Then
            'and a last one
        End If
        'go to the next title in the document
        Selection.GoTo what:=wdGoToHeading, which:=wdGoToNext
    Wend
End With
End Sub

1 个答案:

答案 0 :(得分:1)

您尝试执行失败的原因是With在调用此行时始终引用Selection.Paragraphs(1).Range 并测试是否最左边的字符是“ 3”。由于第一段开头的数字永远不变,因此代码无法按您希望的那样工作。如果将Debug.Print .ListString放在Wend之前,您会发现它永远不会改变。

这是另一种编写代码的方法,可以简化代码的编写过程,只是让您了解如何使用Range对象。它循环文档中所有编号的(“列表”)段落,并跳过所有未编号的段落。对于您而言,这可能不是最佳选择-因为您没有提供有关该文档的任何详细信息,所以很难知道。

Sub MyMacro()
    Dim rng As Word.Range
    Dim paras As Word.ListParagraphs
    Dim para As Word.Paragraph
    Dim lvl As Long, listVal As Long

    Set paras = ActiveDocument.ListParagraphs

    For Each para In paras
        Set rng = para.Range
        If Left(rng.ListFormat.ListString, 1) = "3" Then
            lvl = rng.ListFormat.ListLevelNumber
            listVal = rng.ListFormat.ListValue
            Select Case lvl
                Case 2
                    If listVal < 4 Then
                        Debug.Print "Case 2: lvl " & lvl & "; listVal " & listVal
                    End If
                Case 3
                    If listVal <> 4 And Left(rng.ListFormat.ListString, 4) = "3.1." Then
                        Debug.Print "Case 3: lvl " & lvl & "; listVal " & listVal
                    End If
                Case 4
                    If Left(rng.ListFormat.ListString, 5) = "3.2.1" Then
                        Debug.Print "Case 4: lvl " & lvl & "; listVal " & listVal
                    End If
                Case Else
                    Debug.Print "Case else"
            End Select
        End If
    Next
End Sub