避免在此代码中使用activesheet

时间:2014-10-08 11:02:17

标签: excel vba excel-vba

我在这里收到了一些非常好的帮助,可以编写一个如下所示的短宏(完美无缺)。

我遇到的问题是我不明白如何在每一步都用ActiveSheet删除常量。理想情况下,我希望能够在具有不同名称的工作表上从我的个人宏工作簿中运行宏。

此外,关于我如何改善这一点的任何指示都会受到极大的欢迎,我不必经常这样做,但我仍然希望改进,而且几小时的网络搜索似乎让我感到高兴四处转转。

一如既往地感谢您花时间去看。

  Sub SheetFormat()

 Dim lr         As Long
 Dim cl         As Range
 Dim rng        As Range
 Dim mssg       As String

 Application.ScreenUpdating = False

    'cleans all non_printable characters from the data (excluding invoice_date, effective_date and spare_date)
    With ActiveSheet
        lr = .Range("A" & Rows.Count).End(xlUp).Row
        Set rng = Union(.Range("C2:AA" & lr), .Range("AM2:AM" & lr), .Range("AD2:AO" & lr))
        For Each cl In rng
        cl.Value = WorksheetFunction.Clean(cl.Value)

        Next cl
    End With

    'removes additional spaces from the client_name and comment field
    With ActiveSheet
        lr = .Range("A" & Rows.Count).End(xlUp).Row
        Set rng = Union(.Range("I2:I" & lr), .Range("AM2:AM" & lr))
        For Each cl In rng
        cl.Value = WorksheetFunction.Trim(cl.Value)

        Next cl
    End With

    'truncates comments field to 500 characters
    With ActiveSheet
        lr = .Range("A" & Rows.Count).End(xlUp).Row
        Set rng = .Range("AM2:AM" & lr)
        For Each cl In rng
        cl.Value = Left(cl.Value, 500)

        Next cl
    End With

    'format invoice_date, effective_date & spare_date to dd/mm/yyyy
    With ActiveSheet
        lr = .Range("A" & Rows.Count).End(xlUp).Row
        Set rng = Union(.Range("AB2:AB" & lr), .Range("AC2:AC" & lr), .Range("AP2:AP" & lr))
        For Each cl In rng
        cl.NumberFormat = "m/d/yyyy"

        Next cl
    End With

    'formats all numerical fields to "0.00"
    With ActiveSheet
        lr = .Range("A" & Rows.Count).End(xlUp).Row
        Set rng = Union(.Range("AD2:AL" & lr), .Range("AO2:AO" & lr))
        For Each cl In rng
        cl.NumberFormat = "0.00"

        Next cl
    End With

    'checks that only date values as present in the invoice_date, effective_date & spare_date
    With ActiveSheet
        lr = .Range("A" & Rows.Count).End(xlUp).Row
        Set rng = Union(.Range("AB2:AB" & lr), .Range("AC2:AC" & lr), .Range("AP2:AP" & lr))
        For Each cl In rng
            If Not IsDate(cl.Value) And Not IsEmpty(cl) Then _
                mssg = mssg & cl.Address(0, 0) & Space(4)
        Next cl
    End With
    If CBool(Len(mssg)) Then
        MsgBox ("There are invalid date value(s) in the following cells: " & Chr(10) & Chr(10) & _
          mssg & Chr(10) & Chr(10) & _
          "Please correct and re-run the macro")
    Else
        MsgBox "Statement Preperation Is Complete"
    End If

    Set rng = Nothing

    Application.ScreenUpdating = True

End Sub

1 个答案:

答案 0 :(得分:4)

你遇到的最大问题是循环应该保持在最低限度。这些操作中的许多操作可以嵌套在一起,这样单元只能循环一次而不是几次以进行单独的操作。其他人根本不需要循环。例如:

Sub SheetFormat()

    Dim lr         As Long
    Dim cl         As Range
    Dim rng        As Range
    Dim mssg       As String
    Dim ws         As Worksheet

    Application.ScreenUpdating = False
    Set ws = ActiveSheet    'could be activeworkbook.sheets("Sheet2") or something

    With ws
        'cleans all non_printable characters from the data (excluding invoice_date, effective_date and spare_date)
        'trim and truncate added here
        lr = .Range("A" & Rows.Count).End(xlUp).Row
        Set rng = Union(.Range("C2:AA" & lr), .Range("AD2:AO" & lr), .Range("AM2:AM" & lr))
        For Each cl In rng
            If cl.Column = 39 Then 'column AM gets Left() truncation as well
                cl = Left(WorksheetFunction.Trim(WorksheetFunction.Clean(cl.Value)), 500)
            Else
                cl = WorksheetFunction.Trim(WorksheetFunction.Clean(cl.Value))
            End If
        Next cl

        'format invoice_date, effective_date & spare_date to dd/mm/yyyy
        Union(.Range("AB2:AB" & lr), .Range("AC2:AC" & lr), .Range("AP2:AP" & lr)).NumberFormat = "m/d/yyyy"

        'formats all numerical fields to "0.00"
        Union(.Range("AD2:AL" & lr), .Range("AO2:AO" & lr)).NumberFormat = "0.00"

        'checks that only date values as present in the invoice_date, effective_date & spare_date
        Set rng = Union(.Range("AB2:AB" & lr), .Range("AC2:AC" & lr), .Range("AP2:AP" & lr))
        For Each cl In rng
            If Not IsDate(cl.Value) And Not IsEmpty(cl) Then _
                mssg = mssg & cl.Address(0, 0) & Space(4)
        Next cl
    End With

    If CBool(Len(mssg)) Then
        MsgBox ("There are invalid date value(s) in the following cells: " & Chr(10) & Chr(10) & _
          mssg & Chr(10) & Chr(10) & _
          "Please correct and re-run the macro")
    Else
        MsgBox "Statement Preparation Is Complete"
    End If

    Set rng = Nothing
    Set ws = Nothing
    Application.ScreenUpdating = True

End Sub

因此,其中一些循环操作能够被整体处理,而其他循环操作可以嵌套在一起,因此循环不会重复。像日期检查这样的其他操作确实需要逐个单元地进行,并且不管是什么。 lr 分配给最大行数只需要完成一次。