Вопрос по vba, excel – Нужен макрос для определения, если значение ячейки изменяется от текущего значения

3

Мне нужна помощь с макросом, чтобы уведомить меня (путем изменения цвета фона ячейки на красный), когда значение (всегда числовой формат) изменяется в любых ячейках в строке. Я хочу, чтобы фон ячейки E3 изменился на красный, если какие-либо значения в ячейках F3: AN3 изменятся по сравнению с их текущими значениями.

Числа в ячейках F3: AN3 будут введены вручную или посредством копирования и вставки строки, и никаких формул не будет. Аналогичным образом, если какие-либо значения в ячейках F4: AN4 будут изменены, я бы хотел, чтобы ячейка E4 перешла на красный фон и так далее для каждой строки в диаграмме. Не все строки всегда будут иметь значение, поэтому я буду искать изменения в & quot; & quot; к любому #, или от одного # к другому #, или от любого # до & quot ;. В идеале это макрос событий, который не нужно запускать вручную.

Ниже приведен код, с которым я начал работать:

Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Target, Range("F3:AN3")) Is Nothing Then KeyCellsChanged
End Sub


Private Sub KeyCellsChanged()

   Dim Cell As Object
     For Each Cell In Range("E3")
    Cell.Interior.ColorIndex = 3

   Next Cell

End Sub

Однако этот макрос, кажется, запускается независимо от того, изменяется ли число в ячейке, пока я нажимаю, введите его, выделите E3 красным.

Любая помощь высоко ценится!

Error: User Rate Limit Exceeded Jon Crowell
Error: User Rate Limit Exceeded Siddharth Rout
Error: User Rate Limit Exceeded Marc
Error: User Rate Limit Exceeded Siddharth Rout
Error: User Rate Limit Exceeded Tim Williams

Ваш Ответ

2   ответа
3

Option Explicit

Dim PrevVal As Variant

Private Sub Worksheet_Activate()
    If Selection.Rows.Count = 1 And Selection.Columns.Count = 1 Then
        PrevVal = Selection.Value
    Else
        PrevVal = Selection
    End If
End Sub

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    On Error GoTo ExitGraceFully
    If Selection.Rows.Count = 1 And Selection.Columns.Count = 1 Then
        PrevVal = Selection.Value
    Else
        PrevVal = Selection
    End If
ExitGraceFully:
End Sub

Private Sub Worksheet_Change(ByVal Target As Range)
    If Application.WorksheetFunction.CountA(Target) = 0 Then Exit Sub

    Dim aCell As Range, i As Long, j As Long

    On Error GoTo Whoa

    Application.EnableEvents = False

    If Not Intersect(Target, Columns("F:AN")) Is Nothing Then
        If Target.Rows.Count = 1 And Target.Columns.Count >= 1 Then
            Range("E" & Target.Row).Interior.ColorIndex = 3
        ElseIf Target.Rows.Count > 1 And Target.Columns.Count = 1 Then
            i = 1
            For Each aCell In Target
                If aCell.Value <> PrevVal(i, 1) Then
                    Range("E" & aCell.Row).Interior.ColorIndex = 3
                End If
                i = i + 1
            Next
        ElseIf Target.Rows.Count > 1 And Target.Columns.Count > 1 Then
            Dim pRow As Long

            i = 1: j = 1

            pRow = Target.Cells(1, 1).Row

            For Each aCell In Target
                If aCell.Row <> pRow Then
                    i = i + 1: pRow = aCell.Row
                    j = 1
                End If

                If aCell.Value <> PrevVal(i, j) Then
                    Range("E" & aCell.Row).Interior.ColorIndex = 3
                End If
                j = j + 1
            Next
        End If
    End If

LetsContinue:
    Application.EnableEvents = True
    Exit Sub
Whoa:
    Resume LetsContinue
End Sub

SNAPSHOTS

doesn't

enter image description here

NOTE

2

Create an exact copy of the range you're watching in hidden rows below the range the user sees. Add another section below that (also hidden) with formulas subtracting the user range with the hidden range with an if statement that sets the value to 1 if the difference is anything but 0. Use conditional formatting in the user range that changes the background color of the row if the corresponding change-detection row (or cell) is > 0.

If a user makes a change and then reverts back to the original value, the row is "smart enough" to know that nothing has changed. Code that runs any time a user changes something is a pain and can lead to problems. If you set up your change detection the way I'm describing, your code only fires when the sheet is initialized. The worksheet_change event is expensive, and also "may effectively turn off Excel’s Undo feature. Excel’s Undo stack is destroyed whenever an event procedure makes a change to the worksheet." (per John Walkenbach: Excel 2010 Power Programming) You can detect if the user is navigating away from the page and warn them that their changes will be lost.

Похожие вопросы