2

まったく同じ VBA コードを使用して大文字を 2 列に強制する Excel 2007 アプリケーションを作成しています。このコードは、8 つの異なるワークシートで使用されます。8 つのワークシートのそれぞれでサブルーチンを呼び出せるように、モジュールにサブルーチンを作成しようとしましたが、機能しません。

各ワークシートの下に次のコードを直接追加すると、機能しました。

Private Sub Worksheet_Change(ByVal Target As Range)
Dim TargetRowNumber  As Integer
Dim targetColumnNumber As Integer

If (Target.Row >= 6 And Target.Row <= 500) Then

    If (Not Intersect(Target, Range("F6:F500")) Is Nothing) Then
      If Target.Column = 6 Then
       Application.EnableEvents = False
       Range("$F" & Target.Row).Value = UCase(Range("$F" & Target.Row).Value)
       Application.EnableEvents = True
      End If
    End If

    If (Not Intersect(Target, Range("K6:K500")) Is Nothing) Then
      If Target.Column = 11 Then
        Application.EnableEvents = False
        Range("$K" & Target.Row).Value = UCase(Range("$K" & Target.Row).Value)
        Application.EnableEvents = True
      End If
    End If

end if

end sub

しかし、同じコードでモジュールを作成し、各ワークシートの下でサブルーチンを呼び出そうとすると、次のエラーが発生します。実行時エラー '424': オブジェクトが必要です。

モジュール内のコード:

Sub convert_upper()
Dim TargetRowNumber  As Integer
Dim targetColumnNumber As Integer

If (Target.Row >= 6 And Target.Row <= 500) Then

    If (Not Intersect(Target, Range("F6:F500")) Is Nothing) Then
      If Target.Column = 6 Then
       Application.EnableEvents = False
       Range("$F" & Target.Row).Value = UCase(Range("$F" & Target.Row).Value)
       Application.EnableEvents = True
      End If
    End If

    If (Not Intersect(Target, Range("K6:K500")) Is Nothing) Then
      If Target.Column = 11 Then
        Application.EnableEvents = False
        Range("$K" & Target.Row).Value = UCase(Range("$K" & Target.Row).Value)
        Application.EnableEvents = True
      End If
    End If

End If

End Sub

サブルーチンを呼び出す各ワークシートの下のコード:

Private Sub Worksheet_Change(ByVal Target As Range)

   convert_upper

End Sub

VBAでプログラミングするのは初めてです。オンラインで解決策を見つけようとしましたが、成功しませんでした。誰かが私を助けてくれたら本当にありがたいです。

どうもありがとう。

4

2 に答える 2

4

Chris は、個々のイベント サブルーチンを機能させるための良い答えを持っています。

ただし、より簡単な方法は、ワークブック レベルのSheetChangeイベントを使用することです。これは、ブック内のシートが変更されるたびにトリガーされることを除いて、シート レベルのイベントと同じように機能します。その引数にはShに加えて含まれTargetているため、どのシートがイベントをトリガーしたかをテストできます。ワークブック内のすべてのシートでイベントをトリガーしたくない場合は、これを行う必要があります。

ここにあなたのために働くと思ういくつかのコードがあります。また、あなたの論理をいくらか強化しました。ThisWorkbookワークブックのモジュールに貼り付けます。

Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
Dim RangeToUpper As Excel.Range
Dim AreaToUpper As Excel.Range

Select Case Sh.Name
Case "Sheet1", "Sheet2"
    If (Not Intersect(Target, Sh.Range("F6:F500")) Is Nothing) Or _
       Not Intersect(Target, Sh.Range("K6:K500")) Is Nothing Then
        Set RangeToUpper = Intersect(Target, Union(Sh.Range("F6:F500"), Sh.Range("K6:K500")))
        On Error GoTo Err_Handler
        Application.EnableEvents = False
        For Each AreaToUpper In RangeToUpper.Areas
            AreaToUpper.Value = UCase(AreaToUpper.Value)
        Next AreaToUpper
    End If
End Select

Err_Handler:
Application.EnableEvents = True
End Sub
于 2013-01-03T03:20:18.443 に答える
2

あなたは考える必要がありますVariable Scope

Sub宣言を次のように変更します

Sub convert_upper(Target as Range)

そしてそれを次のように呼び出します

convert_upper Target

Rangeまた、共通の参照を修飾する必要がありますSub(そうしないと、コードは を参照しますActiveSheet)。例 ( のすべての用途に適用Range)

With Target.Parent
    .Range("$F" & Target.Row).Value = UCase(.Range("$F" & Target.Row).Value)
End With
于 2013-01-03T03:09:45.743 に答える