【问题标题】:Colour a cell if a certain number is entered如果输入了某个数字,则为单元格着色
【发布时间】:2018-12-12 13:18:26
【问题描述】:

我需要在 Excel 2016 中编写条件格式,而不使用现有的条件格式工具。

我想写这个,例如在私人潜艇中:

对于范围 A1:A100:
- 如果值 >=1,则颜色 = 绿色
- 如果值为

适用于范围 B1:B100
- 如果值 >=3,则颜色 = 绿色
- 如果值为 0,则颜色为黄色
- 如果值为 0 或 "" 红色

我的代码。当我保存它时,在我的第二个定义范围内没有任何反应,在重新打开 Excel 工作簿之后也是如此:

Private Sub Worksheet_Change(ByVal Target As Range)

Dim rngObserve As Range, rngCell As Range

Set rngObserve = Intersect(Target, Range("A1:A100"))

If rngObserve Is Nothing Then
    Exit Sub
End If

For Each rngCell In rngObserve.Cells
    If Not Intersect(rngCell, rngObserve) Is Nothing Then

        If rngCell.Value = vbNullString Then
            rngCell.Interior.Color = xlNone

        ElseIf rngCell.Value < 1 Then
            rngCell.Interior.ColorIndex = 3 'red

        ElseIf rngCell.Value >= 1 Then
            rngCell.Interior.ColorIndex = 4 'green

        Else
            rngCell.Interior.ColorIndex = 3
        End If
    End If
Next

Set rngObserve = Intersect(Target, Range("B1:B100"))

If rngObserve Is Nothing Then
    Exit Sub
End If

For Each rngCell In rngObserve.Cells

    If Not Intersect(rngCell, rngObserve) Is Nothing Then

        If rngCell.Value = vbNullString Then
            rngCell.Interior.Color = xlNone

        ElseIf rngCell.Value < 1& > 0 Then
            rngCell.Interior.ColorIndex = 6 'yellow

        ElseIf rngCell.Value >= 3 Then
            rngCell.Interior.ColorIndex = 4 'green

        Else
            rngCell.Interior.ColorIndex = 3

        End If
    End If
Next

End Sub

【问题讨论】:

  • 请注意 "does not work" 不是有用的错误描述。请edit您的问题并包括:您遇到哪个错误以及在哪里?此外,Range("A") 不是有效范围,如果您的意思是 A 列,它必须是 Range("A:A")Columns("A")MyPlage As Range 缺少 Dim。你也可以看看Select...Case Statement
  • 您的代码甚至无法编译,因为您缺少End If。如果要使用WorksheetChange,则不能更改名称,必须将其放在相关的工作表模块中。

标签: excel vba conditional-formatting


【解决方案1】:
  1. 您必须使用 Worksheet_Change 事件。您不能重命名该活动!
  2. 使用Intersect(Target, Target.Parent.Range("A:A")) 仅获取A 列中的单元格。
  3. 测试Target 中的每个单元格值是否是数字If IsNumeric(Cell.Value) Then,以确保它仅适用于数字值!

所以你最终会得到类似的东西:

Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim MyPlage  As Range
    Set MyPlage = Intersect(Target, Target.Parent.Range("A:A"))

    If Not MyPlage Is Nothing Then
        Dim Cell As Range
        For Each Cell In MyPlage
            If Cell.Value = vbNullString Then
                Cell.Interior.ColorIndex = 3 'red
            ElseIf IsNumeric(Cell.Value) Then
                If Cell.Value < 1 Then
                    Cell.Interior.ColorIndex = 3 'red
                Else
                    Cell.Interior.ColorIndex = 4 'green
                End If
            End If
        Next Cell
    End If
End Sub

【讨论】:

  • fwiw,一个空白单元格 IsNumeric,其值小于 1(视为零)。例如IsNumeric() 为真且 .value = 0.
  • @user10779473 完全正确,谢谢!我切换了If … ElseIf。尽管如此,我还是保留了IsNumeric,以确保它仅在数值上运行(如果不需要,可以轻松删除)。
【解决方案2】:

您可以使用以下宏。它必须放在相应的工作表中(不是工作簿,也不是模块)。此外,您可以通过定义 rngObserve 来定义要观察的范围)。我猜你不想检查整个工作表...

Private Sub Worksheet_Change(ByVal Target As Range)

Dim rngObserve As Range, rngCell As Range

Set rngObserve = Intersect(Target, Range("A1:C5"))

If rngObserve Is Nothing Then
    Exit Sub
End If
For Each rngCell In rngObserve.Cells
    If Not Intersect(rngCell, rngObserve) Is Nothing Then
        If rngCell.Value = vbNullString Then
            rngCell.Interior.Color = xlNone
        ElseIf rngCell.Value < 1 Then
            rngCell.Interior.ColorIndex = 3
        ElseIf rngCell.Value >= 1 Then
            rngCell.Interior.ColorIndex = 4
        Else
            rngCell.Interior.ColorIndex = 3
        End If
    End If
Next

结束子

【讨论】:

  • 空单元格的值不是为零(小于1)吗?
  • 是的。如果 emil7 不希望空单元格被标记为红色,他可以调整格式模式。
  • 您可以使用Set rngObserve = Intersect(Target, Range("A1:C5"))For Each rngCell In rngObserve,这样您就只有一个Intersect,它应该会加快速度。当然在Set之后测试If rngObserve Is Nothing Then Exit Sub
  • 非常感谢!如何添加第二个范围(例如 A1:B10 和 K18:K30)?提前谢谢!!!
  • 您可以定义更复杂的范围,方法是用逗号分隔它们。例如。 "A1:B10,K18:K30"
【解决方案3】:

您需要Range("A:A"),但如果将其缩减到工作表的 UsedRange 属性中的单元格会更好。此外,空白单元格的值被视为零,因此应首先检查条件。

dim MyPlage As Range, cell as range

Set MyPlage = intersect(activesheet.Range("A:A"), activesheet.UsedRange)

For Each Cell In MyPlage

    If isempty(cell) then
        Cell.Interior.ColorIndex = 3 'red
    elseIf Cell.Value < 1 Then
        Cell.Interior.ColorIndex = 3 'red
    ElseIf Cell.Value >= 1 Then
        Cell.Interior.ColorIndex = 4 'green
    end if

Next cell

我已将空单元格和值小于 1 的单元格分开,因为尽管它们的所有意图和目的都是相同的,但将来您可能希望为其中一个选择不同的颜色。

将 all 设置为 vbRed 然后选择性地将大于或等于 1 的值设置为 vbGreeen 可能更容易。

dim MyPlage As Range, cell as range

Set MyPlage = intersect(activesheet.Range("A:A"), activesheet.UsedRange)

MyPlage.Interior.ColorIndex = 3 'red 

For Each Cell In MyPlage

    If  Cell.Value >= 1 Then
        Cell.Interior.ColorIndex = 4 'green
    end if

Next cell

【讨论】:

  • 请注意,在Worksheet_Change 事件中使用ActiveSheet 是危险的。 ActiveSheet 不是触发事件的工作表,而是代码运行时位于顶部的工作表。如果事件例如。由 Range("A1").Value = 5 之类的 VBA 语句触发,那么 ActiveSheet 可能是完全不同的工作表。
  • 非常正确,这不是一种值得提倡的做法。我的回应不是修复 Worksheet_Change 事件子,而是要在活动工作表上运行的公共或私有子。
  • 只是想提及它以避免 OP 将它与Worksheet_Change 结合使用。请注意,您的第二个代码还将字符串变为红色,通常不是&lt;1
  • 关于字符串的要点。我曾假设 OP 只想处理数字和空格(每个原始代码),但这是错误的。事实上,那些"" 可能是公式留下的零长度字符串,在这种情况下它们不被认为是“空”的。此外,很好地提到了在触发的子过程中依赖 ActiveSheet 的谬误。
猜你喜欢
  • 2015-03-13
  • 2022-06-23
  • 1970-01-01
  • 2021-02-17
  • 1970-01-01
  • 1970-01-01
  • 2021-10-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多