Слово VBA найти следующий комментарий с конкретным автором - иногда находит комментарии других авторов

Надеюсь, кто-то может помочь.

У меня есть следующая строка в моем VBA:

    Selection.GoTo What:=wdGoToComment, Which:=wdGoToNext, Count:=1, Name:=Last_chosen

Last_chosen - это имя автора, взятое из выпадающего списка в пользовательской форме, и debug.print показывает, что оно правильно считывается в макрос.

Проблема в том, что find работает несколько раз, а затем по какой-то причине находит комментарий, принадлежащий другому автору. Даже если есть дальнейшие комментарии от автора Last_chosen далее по документу. И как только это происходит, он продолжает находить неправильные комментарии, иногда от нескольких авторов, даже если Last_chosen не изменился по сравнению с первоначальным требуемым автором.

Я пытался скрыть комментарии некоторых авторов в обзоре | Показать разметку | Рецензенты в случае, если есть сбой (?), Когда Word определяет автора, но VBA все еще иногда находит неправильный комментарий, предполагая, что нет никакого сбоя.

Спасибо всем.

Вот весь код.

Public Last_chosen As String
Public Form_chosen As Integer

'****************

Sub Next_chosen_comment()
'This is where the user first specifies a new author
'to search for their next comment

Dim Re_peat As String
'Dim Cho_sen As String
Re_peat = "N"
'Cho_sen = ""
Last_chosen = ""
Call Next_chosen(Re_peat, Last_chosen)
End Sub

'****************

Sub Repeat_search_next()
'This is where the user repeats the same search
'i.e. jumps to the next comment of the same author
'without having to choose again from the dropdown
'via the Next_chosen_comment() macro

Dim Re_peat As String
'Dim Cho_sen As String
Debug.Print Last_chosen
Re_peat = "Y"
'Cho_sen = Last_chosen
'Call Next_chosen(Re_peat, Cho_sen)
Call Next_chosen(Re_peat, Last_chosen)
Re_peat = "N"
End Sub

'****************

Sub Next_chosen(Repeat_nxt As String, Last_chosen As String)

If ActiveDocument.Comments.Count < 1 Then
    MsgBox "There are no comments.", vbOKOnly, "********NO COMMENTS********"
    Exit Sub
End If

Debug.Print "Repeat_nxt: " & Repeat_nxt

If Repeat_nxt = "Y" Then ' If this is a repeat search (called from Repeat_search_next() macro)
    GoTo Repeat_next
End If

Comment_dropdown.Show 'Not a repeat search
'so show the userform containing the 8 dropdown values

If Form_chosen = -1 Then 'Cancelled userform
    Exit Sub
End If

Select Case Form_chosen 'Set the author to look for
    Case 0
        Chosen = "Contractions"
    Case 1
        Chosen = log_words"
    Case 2
        Chosen = "US_to_UK"
    Case 3
        Chosen = "Other"
    Case 4
        Chosen = "Spaces"
    Case 5
        Chosen = "Ampersand"
    Case 6
        Chosen = "Duplicate"
    Case 7
        Chosen = "Style"
End Select

Last_chosen = Chosen 'Sets Last_chosen from the dropdown
'in case user wants to subsequently repeat the same find
'using the Repeat_search_next() macro

Repeat_next:

Debug.Print "Last_chosen: " & Last_chosen

    Selection.GoTo What:=wdGoToComment, Which:=wdGoToNext, Count:=1, Name:=Last_chosen
    Selection.Find.ClearFormatting
    With Selection.Find
        .Text = ""
        .Replacement.Text = ""
        .Forward = True
        .Wrap = wdFindContinue
        .Format = False
        .MatchCase = False
        .MatchWholeWord = False
        .MatchByte = False
        .MatchAllWordForms = False
        .MatchSoundsLike = False
        .MatchWildcards = False
        .MatchFuzzy = False
    End With
End Sub

'*****************Userform****************

Private Sub UserForm_Initialize()

With Drop_down
    .AddItem "Contractions"
    .AddItem "-log words"
    .AddItem "US to UK changes"
    .AddItem "Other changes"
    .AddItem "Multiple spaces"
    .AddItem "Ampersands"
    .AddItem "Duplicate paragraphs"
    .AddItem "Non-RFP styles"
End With
End Sub

'****************

Private Sub OK_btn_Click()
Form_chosen = Drop_down.ListIndex
Unload Me
End Sub

'****************

Private Sub Cancel_btn_Click()
Form_chosen = -1
Unload Me
End Sub

1 ответ

При первом рассмотрении вашего кода я обнаружил следующие недостатки.

  1. У вас есть публичная переменная Last_chosen который выровнен с частными переменными Cho_sen а также Chosen, Я не нашел, где они путаются, но вместо того, чтобы искать такую ​​точку, я бы исключил две частные переменные и работал бы только с общедоступной. Вы сохраняете много кода и исключаете возможность путаницы.
  2. У вас есть личная переменная с именем Repeat, "Повторить" - это ключевое слово, зарезервированное для использования VBA. Выберите "Повторить" и нажмите F1 для получения дополнительной информации. Опять же, я сомневаюсь, что это источник вашей проблемы, но использование зарезервированных слов в качестве имен переменных может вызвать неожиданные, кажущиеся не связанными и, как правило, неидентифицируемые ошибки. Лучше выбрать другое имя

Мое подозрение теперь падает на другой сценарий. Вы ищете определенные слова в комментариях. Что произойдет, если искомые слова найдены в тексте комментария другого автора? Другими словами, вам может понадобиться код, чтобы убедиться, что найденное совпадение действительно представляет имя автора.

Пожалуйста, исправьте два вышеуказанных пункта и прокомментируйте мое подозрение. Если после этого ошибка не исчезнет, ​​я разобью ваш код на более мелкие части.:-)

Между тем, я предлагаю вам внедрить следующие упрощения в свой код. Сначала создайте такую ​​функцию:

Function DD_Items(Optional ByVal Idx As Integer = -1) As Variant

    Dim Fun As Variant                      ' function return value
    Dim Items As String

    Items = "Contractions,-log words,US to UK changes,Other changes,Multiple spaces," & _
            "Ampersands,Duplicate paragraphs,Non-RFP styles"
    Fun = Split(Items, ",")

    If Idx >= 0 Then
        If Idx > UBound(Fun) Then Idx = 0   ' mistaken Idx
        Fun = Fun(Idx)
    End If
    DD_Items = Fun
End Function

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

Private Sub UserForm_Initialize()
    With Drop_down
        .List = DD_Items
        .ListIndex = 0
    End With
End Sub

Наконец, замените ваши операторы Select этим кодом.

Last_Chosen = DD_Items(Form_Chosen)
Другие вопросы по тегам