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