当窗体上满足条件时,消息框仅显示一次,命令按钮在消息框出现时消失



>我有一张表格需要填写。但是,我为条件编写的代码似乎不能完全工作。即使满足条件,也不会显示消息框,当满足条件时,该框也不会消失。

我需要消息框出现一次,并且当满足使消息框出现的条件时,命令按钮不可见。

请帮忙。

Private Sub Worksheet_Change(ByVal Target As Range)                       
Application.ScreenUpdating = False
If Cells(12, 12) = "" Or Cells(14, 12) = "" Or Cells(16, 12) = "" Or Cells(18, 12) = "" Or Cells(20, 12) = "" Or Cells(22, 12) = "" Or Cells(24, 12) = "" Or Cells(26, 12) = "" Or Cells(28, 12) = "" Or Cells(30, 12) = "" Or Cells(47, 12) = "No" Then
Range("L11").Select
Me.CommandButton1.Visible = False
If Cells(12, 12) = "Yes" Or Cells(14, 12) = "Yes" Or Cells(16, 12) = "Yes" Or Cells(18, 12) = "Yes" Or Cells(20, 12) = "Yes" Or Cells(22, 12) = "Yes" Or Cells(24, 12) = "Yes" Or Cells(26, 12) = "Yes" Or Cells(28, 12) = "Yes" Or Cells(30, 12) = "Yes" Then
Me.CommandButton1.Visible = False
'Prompt Msg Box
MsgBox ("Please Fill In Box Below")
Exit Sub
End If
Else  
If Target.Range("$L$12") = "Yes" Or Target.Range("$L$14") = "Yes" Or Target.Range("$L$16") = "Yes" Or Target.Range("$L$18") = "Yes" Or Target.Range("$L$20") = "Yes" Or Target.Range("$L$22") = "Yes" Or Target.Range("$L$24") = "Yes" Or Target.Range("$L$26") = "Yes" Or Target.Range("$L$28") = "Yes" Or Target.Range("$L$30") = Yes And Range("B34").Characters.Count >= "5" Then
Range("B34").Select
Me.CommandButton1.Visible = True               
ElseIf Cells(5, 4) > "" Or Cells(6, 4) > "" Or Cells(7, 4) > "" Or Cells(8, 4) > "" Or Cells(12, 12) = "No" Or Cells(14, 12) = "No" Or Cells(16, 12) = "No" Or Cells(18, 12) = "No" Or Cells(20, 12) = "No" Or Cells(22, 12) = "No" Or Cells(24, 12) = "No" Or Cells(28, 12) = "No" Or Cells(30, 12) = "No" Or Cells(47, 12) = "" Or Cells(47, 12) = "Yes" And Cells(49, 3) > "" Then
Me.CommandButton1.Visible = True
Application.ScreenUpdating = True
Else
Me.CommandButton1.Visible = False
Application.ScreenUpdating = True
Exit Sub
End If
End If
End Sub

当 Range.B34 中的字符条件更长或等于 5 时,它不会再次出现

然后这个:

If Target.Range("$L$12") = "Yes" Or _
Target.Range("$L$14") = "Yes" Or  _
Target.Range("$L$16") = "Yes" Or _
Target.Range("$L$18") = "Yes" Or _
Target.Range("$L$20") = "Yes" Or _
Target.Range("$L$22") = "Yes" Or _
Target.Range("$L$24") = "Yes" Or _
Target.Range("$L$26") = "Yes" Or _
Target.Range("$L$28") = "Yes" Or _
Target.Range("$L$30") = Yes And _
Range("B34").Characters.Count >= "5" _
Then

由于这是一个Worksheet.Change处理程序,因此Target参数是对刚刚更改的单元格的引用。 那么Target.Range("$L$12")就没有什么意义了,因为这将相对于被修改的任何单元格,而不是$L$12的单元格。

不过Range("B34")看起来是正确的:它是隐式Me.Range("B34"),即该特定工作表上的单元格$B$34

因此,我希望Target.Range(...) = "Yes"条件都不会评估为True

这使得And操作也永远不会评估为True


让我们清理一下。从 MatchesAny 函数开始:

Public Function MatchesAny(ByVal value, ParamArray values()) As Boolean
Dim i As Long
For i = LBound(values) To UBound(values)
If values(i) = value Then
MatchesAny = True
Exit Function
End If
Next
End Function

这将显着提高评估所有这些条件的效率:现在一旦知道结果,我们就会返回结果。另一方面,链接Or运算符会使If语句在 VBA 知道是否进入条件块之前得到完全评估。

条件变为:

If Me.Range("B34").Characters.Count >= 5 And _
MatchesAny("Yes", Me.Range("L12").Text, _
Me.Range("L14").Text, _
Me.Range("L16").Text, _
Me.Range("L18").Text, _
Me.Range("L20").Text, _
Me.Range("L22").Text, _
Me.Range("L24").Text, _
Me.Range("L26").Text, _ 
Me.Range("L28").Text, _
Me.Range("L30").Text) _
Then

请注意,这不是等效的:在您的版本中,B34 中的字符数仅在 L30 为"是"时才相关;在此版本中,无论其他单元格如何,B34 中的字符数都是相关的。这是因为逻辑运算符的工作方式:And的优先级高于Or,所以你的条件像foo Or (bar And baz),但我的条件像(foo Or bar) And baz,我相信这就是你的意图。此外,文字5不应该被"5",这是一个字符串文字 - 虽然它被隐式转换,但这种隐式转换使事情变得比它们需要的更混乱。

顶部的不合格Cells电话也令人困惑:为什么在一个地方将L12称为Range("$L$12"),而在另一个地方却称为Cells(12, 12)

If Cells(12, 12) = "" Or _
Cells(14, 12) = "" Or _
Cells(16, 12) = "" Or _
Cells(18, 12) = "" Or _
Cells(20, 12) = "" Or _
Cells(22, 12) = "" Or _
Cells(24, 12) = "" Or _
Cells(26, 12) = "" Or _
Cells(28, 12) = "" Or _
Cells(30, 12) = "" Or _
Cells(47, 12) = "No" _
Then

我会让它使用相同的寻址风格(两者都有效,但一致性很重要),并再次使用MatchesAny来缩短条件评估:

If Me.Range("L47").Text = "No" Or _
MatchesAny("", Me.Range("L12").Text, _
Me.Range("L14").Text, _
Me.Range("L16").Text, _
Me.Range("L18").Text, _
Me.Range("L20").Text, _
Me.Range("L22").Text, _
Me.Range("L24").Text, _
Me.Range("L26").Text, _ 
Me.Range("L28").Text, _
Me.Range("L30").Text) _
Then

现在很明显这两个条件重复了,我会想出一种方法来进一步简化它 - 假设我们将那堆特定的单元格称为InputCells,那么这样的事情是有道理的:

Private Function AnyInputCellMatches(ByVal matchValue As String) As Boolean
AnyInputCellMatches = MatchesAny(matchValue, _
Me.Range("L12").Text, _
Me.Range("L14").Text, _
Me.Range("L16").Text, _
Me.Range("L18").Text, _
Me.Range("L20").Text, _
Me.Range("L22").Text, _
Me.Range("L24").Text, _
Me.Range("L26").Text, _ 
Me.Range("L28").Text, _
Me.Range("L30").Text)
End Function

现在我们有这样的东西:

If AnyInputCellMatches("") Or Me.Range("L47").Text = "No" Then
Me.CommandButton1.Visible = False
ElseIf AnyInputCellMatches("Yes") And Me.Range("B34").Characters.Count >= 5 Then
Me.CommandButton1.Visible = True
End If

这使得判断某处是否存在问题变得更加容易,并且只有一个地方来维护需要检查的单元格列表。

最新更新