我有一个表单需要填写。但是,我为条件编写的代码似乎并不完整。即使满足条件,消息框也不会出现,满足条件时,消息框也不会消失。
当满足使消息框出现的条件时,我需要使消息框出现一次,并且命令按钮不可见。
请帮助。
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
答案 0 :(得分:0)
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
请注意,这并不等效:在您的版本中,仅当L30为“是”时,B34中的字符数才有意义。在此版本中,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
这样可以更轻松地判断某处是否存在问题,并且仅保留一个位置来维护需要检查的单元格列表。