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

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

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

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

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

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

Я пытался скрыть комментарии некоторых авторов в Review | Показать разметку | Рецензенты на случай, если возникнет сбой (?), Когда 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

person hmm    schedule 04.05.2017    source источник
comment
Итак, Word вбивает себе в голову, что Last_Chosen - это имя, которое присутствует, но не выбрано, и, однажды убедившись, что не выбрано было выбрано, придерживается этого убеждения. Есть две возможные причины такого поведения. Во-первых, в Word есть ошибка, из-за которой свойство Name комментариев связано с неправильными комментариями. Это кажется маловероятным, потому что комментарии представляют собой коллекцию, и любое смешение свойств Name коллекций будет очевидно и в другом месте.   -  person Variatus    schedule 04.05.2017
comment
Другая возможная причина заключается в путанице в том, как переменной Last_Chosen присваивается ее значение. Эта возможность требует изучения всего вашего кода. Я говорю «целиком», потому что вы уже везде искали. Поэтому можно с уверенностью предположить, что такая ошибка скроется там, где вы не ожидали ее найти. Теперь, если вы предпочитаете думать, что первая причина - это причина, мы ничем вам не поможем. А если вы хотите рассмотреть вторую возможность, включите нашу помощь, добавив свой код в свой вопрос.   -  person Variatus    schedule 04.05.2017
comment
@Variatus - спасибо за ваши предложения - я скоро отправлю код   -  person hmm    schedule 04.05.2017
comment
@Variatus - Разместил код. Также заметили, что при 12-м запуске макроса Repeat_search_next () он имеет тенденцию идти не так ...   -  person hmm    schedule 05.05.2017
comment
@Variatus Спасибо за вашу помощь и предложения. Я внес некоторые изменения: - теперь в именах переменных нет пробелов - используйте общедоступную переменную Last_chosen при вызове вызываемой подпрограммы и в вызываемой подпрограмме - Chosen в разделе «Выбор случая» - это нормально? -сохраняет переменную 'Re_peat' в вызовах, но 'Repeat_nxt' в вызываемой подпрограмме - это нормально? Кроме того, я ищу не ‹words› в комментариях, а комментарии с конкретным ‹именем автора› с использованием 'Name: -Last_chosen' Спасибо!   -  person hmm    schedule 05.05.2017
comment
Согласно вашему коду, вы ищете дубликаты (сокращение от Duplicate параграфов) где угодно в комментариях. Вы уверены, что аргумент Name для поиска ограничивает поиск именем автора? Я исследовал этот момент и обнаружил, что MSDN не совсем ясно об этом. В любом случае, у вас осталась та же проблема после изменений? Можете ли вы подтвердить, что критерий поиска - имя или дубликат - нигде не встречается в тексте комментариев?   -  person Variatus    schedule 05.05.2017


Ответы (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)
person Variatus    schedule 05.05.2017
comment
спасибо за вашу помощь и предложения. Я внес некоторые изменения: - person hmm; 05.05.2017
comment
Вам не нужно передавать Last_Chosen в качестве аргумента подпрограммам. Поскольку это Public переменная, она доступна везде в этом модуле. - person Variatus; 05.05.2017
comment
Извините, меня прервал телефонный звонок. Очевидно, что если у вас есть один аргумент Last_Chosen и одна общедоступная переменная с тем же именем, VBA должно быть позволено восстать. Удалите аргумент и просто используйте переменную Last_chosen в подпрограмме. - person Variatus; 05.05.2017
comment
Спасибо за вашу помощь. В конце концов, я выбрал другой путь; вместо того, чтобы переходить от комментариев одного автора к другому, я использовал раскрывающийся список, чтобы пользователь мог отображать только комментарии одного автора за раз. Затем еще одна кнопка для перехода от одного комментария к другому (что отлично работает!). Но я собираюсь задать еще один вопрос ... - person hmm; 10.05.2017