首页 > 解决方案 > 只显示一次 MsgBox

问题描述

我有一个 VBA 脚本,内容如下:

1, it will run when particular sheet is selected

2、判断条件是否为真

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 显示每次用户来到工作表。

我究竟做错了什么?

标签: excelvba

解决方案


ByRef参数的分配Optional使机制相当脆弱,标志不应该是Public.

执行后,read用 初始化False,然后Activate处理程序最终运行;readValue没有为其可选参数指定默认值,因此第一次调用(Call readValue, ...注意这Call是多余的)弹出一个显示“False”的 msgbox,然后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在两个片段中都进行了条件计算,因为如果条件不正确,则不需要计算变量。


推荐阅读