2

我正在创建一个 excel 2007 应用程序,它使用完全相同的 VBA 代码在 2 列中强制使用大写字母。此代码用于 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事件。这与工作表级事件的工作方式相同,只是每次更改工作簿中的任何工作表时都会触发它。它的参数还包括ShTarget以便您可以测试触发事件的工作表。假设您不希望工作簿中的每张工作表都触发事件,您会想要这样做。

这是我认为对您有用的一些代码。我也加强了你的逻辑。将其粘贴到工作簿的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 回答