在vba模块中使用target.row时出错

时间:2013-01-03 02:53:39

标签: excel excel-vba vba

我正在创建一个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中编程。我试图在线找到解决方案但没有成功。如果有人能帮助我,我将非常感激。

非常感谢你。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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