首页 > 解决方案 > VBA代码根据单元格范围内的单元格值显示消息

问题描述

我对 VBA 很陌生。我正在尝试创建一个宏,它将根据不同工作表上一系列单元格的单元格值显示一条消息。我已经有一个本质上是 ctlr + F 的宏,目标是当输入该 ID 号时新宏将显示所需的消息。

这就是我所拥有的,你可以告诉我我很新,可能甚至不接近我需要的:

Sub Worksheet_Calculate()
    If Worksheets("worksheet").range("B2:B200") > 0 Then
        MsgBox "message needed"
    Else
        MsgBox "other message needed"
        Exit Sub
    End If
End Sub

理论上,如果从第一个宏的单元格范围中搜索到的单元格中有一个 0,那么它将显示一条消息,否则它将显示一条替代消息。

标签: excelvba

解决方案


每次在该工作表上计算任何内容时,Worksheet_Calculate处理程序(应该是Private)都会执行。

目标是当输入该 ID 号时,这个新宏将...

为此使用Worksheet_Change处理程序。你会得到一个ByVal Target As Range参数,告诉你哪些单元格被修改了;您可以使用它Application.Intersect来确定是否Target与特定范围的单元格相交,并采取相应的行动——这个网站上有很多例子。

现在,这段代码:

If Worksheets("BLD Id List To Be Searched").Range("B2:B200") > 0 Then

隐式采用Value多单元Range对象的 ,这是一个 2D 变体数组 - 然后将其与0. 这是一个有保证的类型不匹配运行时错误,因为您无法将整个数组与这样的单个值进行比较。

在这里接受@BigBen 的建议:

If Application.WorksheetFunction.CountIf([ActiveWorkbook.]Worksheets("name").Range("B2:B200"), ">0") > 0 Then

请注意,如果您打算使用ThisWorkbook(即包含 VBA 代码的 Excel 文档),并且工作表“要搜索的 BLD ID 列表”在编译时存在ThisWorkbook,那么代码将更加健壮/用户证明如果您使用了工作表的代码名称,而不是Worksheets使用其用户可修改的“选项卡名称”从当时恰好处于活动状态的任何工作簿的集合中取消引用它。

将工作表模块的(Name)属性更改为 eg BLDListSheet,然后您可以这样做:

If Application.WorksheetFunction.CountIf(BLDListSheet.Range("B2:B200"), ">0") > 0 Then

并且永远不需要担心保持代码与工作表的“选项卡名称”同步。

现在,如果宏在每次修改单元格时运行,那么显示消息并忽略修改了哪个特定单元格没有多大意义,不是吗?

Private Sub Worksheet_Change(ByVal Target As Range)
    If Application.Intersect(BLDListSheet.Range("B2:B200"), Target) Is Nothing Then Exit Sub
    If IsNumeric(Target.Value) Then
        If Target.Value > 0 Then
            ' modified cell has a new value greater than 0
        Else
            ' modified cell has a new value less than or equal to 0
        End If
    Else
        ' Target.Value may not be safe to compare with anything here.
        If IsError(Target.Value) Then Debug.Print Target.Address & " contains an error!"
    End If
End Sub

推荐阅读