0

1) 誰かがこのコードで何が問題なのか教えてもらえますか?

2) ワークシートの更新時に実際にこのコードを実行する必要がありますが、ワークブックの初回ロード時に、Workbook_Openイベント ハンドラーを使用して更新を実行しています。これも私のWorksheet_Changeイベントをトリガーしませんか? これを回避する方法はありますか

Private Sub Worksheet_Change(ByVal Target As Range)

Dim ws As Worksheet
Dim rowCount As Integer

Set Worksheet = "datasheet"
Set rowCount = ws.Cells(Rows.Count, "A").End(xlUp)

If Not Intersect(Target, Range("M3:M" & CStr(rowCount))) Is Nothing Then
   MsgBox ("Hi")
End If
Else
If Not Intersect(Target, Range("T3:T" & CStr(rowCount))) Is Nothing Then
   MsgBox ("Hi")
End If
Else
If Not Intersect(Target, Range("X3:X" & CStr(rowCount))) Is Nothing Then
   MsgBox ("Hi")
End If
Else
If Not Intersect(Target, Range("AB3:AB" & CStr(rowCount))) Is Nothing Then
   MsgBox ("Hi")
End If
Else
If Not Intersect(Target, Range("AI3:AI" & CStr(rowCount))) Is Nothing Then
   MsgBox ("Hi")
End If

End Sub

このハンドラでデータを変更すると、「オブジェクトが必要です」というコンパイラ エラーが発生します。一方、行数を取得する代わりに値を指定すると、問題は発生しません。

4

2 に答える 2

1

使用するときは常にこれをお勧めしますWorksheet_Change

  1. シート名は必要ありません。以下のコメントでbrettdjが正しく述べているように、別のシート行を参照として使用しようとしない限り、コードは現在のシートで実行されることが理解されています。

  2. Worksheet_Changeイベントを扱っているときはいつでも。セルにデータを書き込む場合は、常にイベントをオフに切り替えます。これは、コードが無限ループに陥らないようにするために必要です。

  3. イベントをオフにするときはいつでもエラー処理を使用してください。そうしないと、エラーが発生した場合にコードが次回実行されなくなります。

ここに例があります

Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)
    On Error GoTo Whoa

    Application.EnableEvents = False

    '
    '~~> Rest of the code
    '

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

したがって、上記を使用すると、コードは (UNTESTED) になります

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim rowCount As Long

    On Error GoTo Whoa

    Application.EnableEvents = False

    With ActiveSheet
        rowCount = .Cells(.Rows.Count, "A").End(xlUp).Row
    End With


    If Not Intersect(Target, Range("M3:M" & rowCount)) Is Nothing Then
       MsgBox ("Hi")
    ElseIf Not Intersect(Target, Range("T3:T" & rowCount)) Is Nothing Then
       MsgBox ("Hi")
    ElseIf Not Intersect(Target, Range("X3:X" & rowCount)) Is Nothing Then
       MsgBox ("Hi")
    ElseIf Not Intersect(Target, Range("AB3:AB" & rowCount)) Is Nothing Then
       MsgBox ("Hi")
    ElseIf Not Intersect(Target, Range("AI3:AI" & rowCount)) Is Nothing Then
       MsgBox ("Hi")
    End If

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

編集

2番目の質問について。上記のコメントで述べたように、Public 変数を使用して、ブックを開いたことがワークシートの変更イベントの原因であるかどうかを確認できます。

このコードをモジュールに配置します。

Public WasWbOpened As Boolean

このコードをワークブックのコード領域に配置します

Option Explicit

Private Sub Workbook_Open()
    WasWbOpened = True
    '
    '~~> Rest of the code
    '
    WasWbOpened = False
End Sub

そして、ワークシートの変更イベントを

Private Sub Worksheet_Change(ByVal Target As Range)
    If WasWbOpened = True Then Exit Sub

    Dim rowCount As Long

    On Error GoTo Whoa

    Application.EnableEvents = False

    With ActiveSheet
        rowCount = .Cells(.Rows.Count, "A").End(xlUp).Row
    End With


    If Not Intersect(Target, Range("M3:M" & rowCount)) Is Nothing Then
       MsgBox ("Hi")
    ElseIf Not Intersect(Target, Range("T3:T" & rowCount)) Is Nothing Then
       MsgBox ("Hi")
    ElseIf Not Intersect(Target, Range("X3:X" & rowCount)) Is Nothing Then
       MsgBox ("Hi")
    ElseIf Not Intersect(Target, Range("AB3:AB" & rowCount)) Is Nothing Then
       MsgBox ("Hi")
    ElseIf Not Intersect(Target, Range("AI3:AI" & rowCount)) Is Nothing Then
       MsgBox ("Hi")
    End If

LetsContinue:
    Application.EnableEvents = True
    Exit Sub
Whoa:
    MsgBox Err.Description
    Resume LetsContinue
End Sub
于 2012-10-23T06:29:39.983 に答える
1

いくつかの問題があります

  1. シドのコメントに従って、使用する必要がありますrowCount = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
  2. Set ws = Sheets("datasheet")notを使用する必要がありますSet Worksheet = "datasheet"
  3. あなたのElseステートメントは孤立しているため、エラーが発生しています。テストを続行するのではなく、最初の "Hi" で終了したい場合は、次のようなことを試してください。

シドはあなたの他の点をカバーしました。Booleanこれには変数を使用できます

更新されたコード

これは、列M、T、X、AB、およびAIの行3から行までの交差をrowCount1行でテストします

Private Sub Worksheet_Change(ByVal Target As Range)

Dim ws As Worksheet
Dim rowCount As Long

Set ws = Sheets("datasheet")
rowCount = ws.Cells(Rows.Count, "A").End(xlUp).Row

If Not Intersect(Target, Range("M3:M" & CStr(rowCount) & ",T3:T" & CStr(rowCount) & ",X3:X" & CStr(rowCount) & ",AB3:AB" & CStr(rowCount) & ",AI3:AI" & CStr(rowCount))) Is Nothing Then MsgBox ("Hi")

End Sub
于 2012-10-23T06:20:27.153 に答える