VBA嵌套IF语句

3

我想在特定单元格中具有特定值时显示消息框。我是用以下代码实现的:

If Range("P8") = "Y" Then
        MsgBox "Message here"
End If

这是在Worksheet_Change子程序中,因此每次更改其他单元格的值时都会显示消息框。我尝试通过添加一个布尔变量来解决这个问题,当消息框第一次显示时将其设置为true;

If Range("P8") = "Y" Then
    If messageshown = False Then
        messageshown = True
        MsgBox "Message here"
    Else
    End If
Else
End If

然而,每次我更改工作表中的单元格时,消息框仍然会显示。我有一种感觉是由于我编写的嵌套if语句的方式,但我已经尝试过各种不同的放置elseend if的方式和顺序,但都没有成功。


你在类模块级别上声明了 messageshown,还是在子程序内部声明为 static 了吗? - GSerg
抱歉 - 我已经尝试在“Workbook_Activate”事件和“Workbook_Open”事件中声明“messageshown”。谢谢。 - Jonny Wright
1
你需要在顶部或独立的代码模块中声明它们为公共变量,以便再次使用,因此公共消息显示为布尔值。https://dev59.com/cHE85IYBdhLWcg3wikO- - Nathan_Sav
1
一个小提示:请注意,虽然Excel公式通常将"Y"和"y"视为相同的文本,在VBA中不总是如此。因此,您最好检查是否使用了"y",或者将LCase(Range("P8"))与"y"进行比较。此外,请参阅VBA帮助文件中的"option compare",或使用VBA函数StrComp。 - Carl Colijn
在 VBE 的 工具选项编辑器属性页中设置需要变量声明,将使每个新创建的代码表中都会放置**Option Explicit 语句。这将避免愚蠢的编码错误,如拼写错误和未声明的变量使用,同时影响您在声明中使用正确的变量类型。没有声明的即时创建的变量类型是所有变量类型中最常见的一种。使用Option Explicit**被广泛认为是“最佳实践”。 - user4039065
2个回答

6

请使用Target参数替代 - 它指的是实际发生变化的单元格,这正是您感兴趣的。检查Target的地址是否是所需的单元格,然后根据情况采取相应措施。这将防止在更改其他单元格时显示该消息。

Private Sub Worksheet_Change(ByVal Target As Range)
    With Target
        If .Address = "$P$8" And .Value = "Y" Then MsgBox "Message here"
    End With
End Sub

下投票者能否解释一下这个答案在哪方面不清晰或无帮助? - SierraOscar
事实上,我会的。我没有投反对票是因为它不清楚或无用,你知道的。你提供的答案在功能上与我一个小时前提供的答案完全相同。我理解并接受一个相当简单的问题可能同时被回答,但在我看来,这仅限于几分钟内的回答。我没有感觉到,但请证明我错了,你的答案添加了相关信息。 - SilentRevolution
1
我接受你的前提 - 但首先,这不是一个“先到先得”的网站,只有当答案不清楚或对OP没有用时才应该使用down vote。其次,你的答案使用了Target,然后仍然使用Range("P8"),这是多余的,因为你已经确定目标单元格是P8,从编码角度来看是低效的,因为你必须在多个位置更改地址。不过,我没有因此downvote你的答案,因为最终它仍然有助于OP。 - SierraOscar
1
@SilentRevolution 实际上,我已经点赞了你的回答,因为这就是投票系统的设计原则 - 如果有帮助,就点赞。如果错误或无用,就点踩。不要因为有人发布了类似于你的答案而进行点踩。 - SierraOscar
我知道这里不是先到先得的交易。我为我的投票下降(已经删除)道歉,那是本能反应。现在我明白了区别,我会很乐意给你点赞的。我想以这样的话来结束,如果您解释了差异,我就不会投票反对了,虽然我不是代码天才,但我正在学习。关于何时投票否决或不否决,我不想讨论,但我的观点与您不同。 - SilentRevolution
@SilentRevolution 没关系,不需要道歉,我尊重你拥有自己的观点,只是在这里没有评论就进行踩票似乎有点糟糕,最终的目标是帮助更广泛的受众,所以如果某个内容值得被踩票,原因应该明确——即使只是为了让其他人知道(即使被踩票的人在这方面表现不佳,这种情况也经常发生)。 - SierraOscar

4
尝试使用以下代码,它首先检查更改的单元格,如果不是 P8,则不会弹出消息框。
Private Sub Worksheet_Change(ByVal Target As Range)
    If Target.Address = "$P$8" Then
        If Range("P8") = "Y" Then
            MsgBox "This works"
        End If
    End If
End Sub

正如Macro Man所指出的那样,存在一种更加优化、更加高效的选择。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接