Показывать MsgBox только один раз - PullRequest
1 голос
/ 08 ноября 2019

У меня есть сценарий VBA, который выглядит следующим образом:

1, он будет запускаться, когда выбран конкретный лист

2, он будет проверять, является ли условие True

3, если это так, показать MsgBox

Private Sub Worksheet_Activate()
Dim current As Double
current = Round(((Range("AJ9").Value / Range("AG9").Value) * 100), 1)
If Range("AJ9").Value / Range("AG9").Value < 0.15 Then
    MsgBox "Here is some message and some value: " & current & "%."
End If
End Sub

Я хочу показывать этот MsgBox только первый раз, когда пользователь заходит на лист. Теперь он появляется каждый раз, когда пользователь попадает на лист. Я попытался использовать переменную из другого Sub, но кажется, что он не работает.

Public read As Boolean
Sub readValue(Optional readArg As Boolean)
   MsgBox readArg 
   read = (readArg Or False)
End Sub

, а затем я изменил первый Sub, как это:

Private Sub Worksheet_Activate()
Dim current As Double
current = Round(((Range("AJ9").Value / Range("AG9").Value) * 100), 1)
Call readValue
If read = False Then
    If Range("AJ9").Value / Range("AG9").Value < 0.15 Then
        MsgBox "Here is some message and some value: " & current & "%."
        readValue read = True
    End If
End If

Но MsgBox readArg всегда говорит False. Это похоже на то, что оно не посылает ценности вообще. Поэтому MsgBox показывает каждый раз, когда пользователь приходит на лист.

Что я делаю не так?

1 Ответ

2 голосов
/ 08 ноября 2019

ByRef назначение параметра Optional делает механизм довольно ненадежным, и флаг не должен быть Public.

После выполнения read инициализируется с Falseи затем обработчик Activate в конце концов запускается;readValue не указывает значение по умолчанию для своего необязательного параметра, поэтому при первом вызове (Call readValue, ... обратите внимание, что Call является избыточным) появляется окно с сообщением "False", а затем read = (readArg Or False) оценивается какFalse ... и есть ошибка, потому что в этот момент вам нужно, чтобы флаг был True - безоговорочно .

Вы на правильном пути, ноэто может быть намного проще, чем это:

Option Explicit
Private alreadyPrompted As Boolean

Private Sub Worksheet_Activate()

    If alreadyPrompted Then Exit Sub

    If Range("AJ9").Value / Range("AG9").Value < 0.15 Then
        Dim current As Double
        current = Round(((Range("AJ9").Value / Range("AG9").Value) * 100), 1)

        MsgBox "Here is some message and some value: " & current & "%."
        alreadyPrompted = True

    End If
End Sub

Другим способом было бы сделать флаг Static локальным;такие объявления сохраняют свое значение между вызовами процедур - будьте осторожны, чтобы не злоупотреблять им, потому что это может легко запутаться:

Option Explicit

Private Sub Worksheet_Activate()
    Static alreadyPrompted As Boolean
    If alreadyPrompted Then Exit Sub

    If Range("AJ9").Value / Range("AG9").Value < 0.15 Then
        Dim current As Double
        current = Round(((Range("AJ9").Value / Range("AG9").Value) * 100), 1)

        MsgBox "Here is some message and some value: " & current & "%."
        alreadyPrompted = True

    End If
End Sub

Обратите внимание, что я сделал вычисление current условным в обоих фрагментах,потому что переменная не должна быть вычислена, если условие не истинно во-первых.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...