11

Worksheet_Changeセルの値が変更されたときにトリガーされます(これは私が望むものです)が、セルを編集するように入力したときにもトリガーされますが、実際にはセルの値は変更されません(これは私が望んでいないことです) )。

値が変更されたセルに陰影を追加したいとします。だから私はこれをコーディングします:

Private Sub Worksheet_Change(ByVal Target As Range)
    Target.Interior.ColorIndex = 36
End Sub

次に、作業をテストします。セルA1を変更すると、セルが強調表示されます。それが望ましい振る舞いです。ここまでは順調ですね。次に、B1をダブルクリックしますが、値を変更しないで、C1をクリックします。B1が強調表示されていることに気付くでしょう!そして、これは望ましい動作ではありません。

ここで説明した古い値を取得する方法を実行してから、セルを強調表示する前に古い値と新しい値を比較する必要がありますか?私は確かに私が欠けている何かがあることを願っています。

4

5 に答える 5

4

変更されたセルの値と比較するために、シートの「ミラーコピー」を別のシートに自動的に保持することをお勧めします。

@brettdjと@JohnLBevanは基本的に同じことを提案しますが、セルの値をそれぞれコメントまたは辞書に格納します(実際、これらのアイデアの場合は+1)。ただし、他のオブジェクト(特に、ユーザーまたはユーザーが他の目的で使用する可能性のあるコメント)ではなく、セル内のセルをバックアップする方が概念的にはるかに簡単だと思います。

つまり、Sheet1ユーザーが変更できるセルがあるとします。私はこの別のシートを作成Sheet1_Mirrorしました(これはで作成できWorkbook_Open、必要に応じて非表示に設定できます-あなた次第です)。まず、の内容はの内容Sheet1_Mirrorと同じになりSheet1ます(ここでも、でこれを強制できますWorkbook_Open)。

がトリガーされるたびに、コードはSheet1Worksheet_Change「変更された」セルの値Sheet1が実際にの値と異なるかどうかをチェックしSheet1_Mirrorます。もしそうなら、それはあなたが望む行動をし、ミラーシートを更新します。そうでない場合は、何もしません。

これにより、正しい方向に進むはずです。

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim r As Range
    For Each r In Target.Cells
        'Has the value actually changed?
        If r.Value <> Sheet1_Mirror.Range(r.Address).Value Then
            'Yes it has. Do whatever needs to be done.
            MsgBox "Value of cell " & r.Address & " was changed. " & vbCrLf _
                & "Was: " & vbTab & Sheet1_Mirror.Range(r.Address).Value & vbCrLf _
                & "Is now: " & vbTab & r.Value
            'Mirror this new value.
            Sheet1_Mirror.Range(r.Address).Value = r.Value
        Else
            'It hasn't really changed. Do nothing.
        End If
    Next
End Sub
于 2012-08-22T07:52:44.087 に答える
2

このコードを試してください。範囲を入力すると、元のセル値がディクショナリオブジェクトに保存されます。ワークシートの変更がトリガーされると、保存されている値が実際の値と比較され、変更があれば強調表示されます。
注意:効率を向上させるために、Microsoftスクリプティングランタイムを参照し、AsObjectをAsScripting.Dictionaryに置き換え、CreateObject(" Scripting.Dictionary")NewScripting.Dictionary置き換えます。

Option Explicit

Private previousRange As Object 'reference microsoft scripting runtime & use scripting.dictionary for better performance
                                'I've gone with late binding to avoid references from confusing the example


Private Sub Worksheet_Change(ByVal Target As Range)

    Dim cell As Variant

    For Each cell In Target
        If previousRange.Exists(cell.Address) Then
            If previousRange.Item(cell.Address) <> cell.FormulaR1C1 Then
                cell.Interior.ColorIndex = 36
            End If
        End If
    Next

End Sub

Private Sub Worksheet_SelectionChange(ByVal Target As Range)

    Dim cell As Variant

    Set previousRange = Nothing 'not really needed but I like to kill off old references
    Set previousRange = CreateObject("Scripting.Dictionary")

    For Each cell In Target.Cells
        previousRange.Add cell.Address, cell.FormulaR1C1
    Next

End Sub

ps。セルを更新するためのvbaコード(色だけでも)は、Excelの元に戻す機能が機能しなくなります!これを回避するには、元に戻す機能を再プログラムできますが、メモリを大量に消費する可能性があります。サンプルソリューション:http ://www.jkp-ads.com/Articles/UndoWithVBA00.asp / http://www.j-walk.com/ss/excel/tips/tip23.htm

于 2012-08-22T00:07:33.550 に答える
2

このコードはコメントを使用して前の値を格納します(他の目的でコメントが必要な場合は、このメソッドによってコメントが削除されることに注意してください)

  1. 値のないセルの色はにリセットされますxlNone
  2. セルに入力された最初の値は青です(ColorIndex 34)
  3. 値を変更すると、セルは青から黄色に変わります

ここに画像の説明を入力してください

通常のモジュール-コメントの表示をオフにします

    Sub SetCom()
      Application.DisplayCommentIndicator = xlNoIndicator
    End Sub

変更をキャプチャするためのシートコード

    Private Sub Worksheet_Change(ByVal Target As Range)
    Dim rng1 As Range
    Dim shCmt As Comment
    For Each rng1 In Target.Cells

    If Len(rng1.Value) = 0 Then
    rng1.Interior.ColorIndex = xlNone
    On Error Resume Next
    rng1.Comment.Delete
    On Error GoTo 0
    Else

    On Error Resume Next
    Set shCmt = rng1.Comment
    On Error GoTo 0

    If shCmt Is Nothing Then
        Set shCmt = rng1.AddComment
        shCmt.Text Text:=CStr(rng1.Value)
         rng1.Interior.ColorIndex = 34
    Else
        If shCmt.Text <> rng1.Value Then
            rng1.Interior.ColorIndex = 36
            shCmt.Text Text:=CStr(rng1.Value)
        End If
    End If
    End If
    Next
    End Sub
于 2012-08-22T00:08:54.390 に答える
1

これは古いスレッドですが、「セルA1を変更すると、セルが強調表示されます。それが期待どおりです。B1をダブルクリックしますが、値を変更せずにC1をクリックします。」とまったく同じ問題が発生しました。 B1が強調表示されていることに気付くでしょう!」

セルがダブルクリックされただけで、内部に値がない場合は、セルを強調表示したくありませんでした。

私は簡単な方法で解決しました。多分それは将来誰かを助けるでしょう。

イベントの開始時にこれを追加しました:

 If Target.Value = "" Then
      Exit Sub
 End If
于 2015-12-03T14:38:51.143 に答える
0

古い値をキャプチャする方法を提供するこの別のスレッドを見つけたので、それを「新しい」値と比較して、それらが単に何もしないようにすることができます。

Excel VBAで変更されたセルの古い値を取得するにはどうすればよいですか?

于 2021-03-31T15:02:59.883 に答える