我有一个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会在用户每次访问表单时显示。
我在做什么错了?
答案 0 :(得分:2)
ByRef
参数的分配使该机制变得轻而易举,并且标志不必是Optional
。
执行之后,Public
用read
初始化,然后False
处理程序最终运行; Activate
没有为其可选参数指定默认值,因此第一次调用(readValue
,...请注意,Call readValue
是多余的)会弹出一个显示为” False”的消息框,然后然后Call
的计算结果为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
的计算作为条件,因为如果条件一开始不是真的,则不需要计算变量。