Макрос Word не работает, как только я использую С - PullRequest
0 голосов
/ 04 июля 2018

Я испытал что-то странное сегодня, когда делал макрос. У меня много документов, использующих один и тот же шаблон, поэтому мой макрос сканирует один из них и выполняет некоторые действия в зависимости от заголовка (уровень и номер). Во всяком случае, это не имеет значения. Вот код

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 голосов
/ 05 июля 2018

Причина, по которой вы пытались не работать, заключается в том, что 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...