vba - 避免在此代码中使用 with activesheet

标签 vba excel

我在这里得到了一些非常好的帮助,编写了一个简短的宏,如下所示(效果完美)。

我遇到的问题是我不明白如何在每一步中使用 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

最佳答案

您遇到的最大问题是循环,应将其保持在最低限度。其中许多操作可以嵌套在一起,以便单元格仅循环一次,而不是针对各个操作多次。其他的则根本不需要循环。例如:

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 到最大行数的分配只需要完成一次。

关于vba - 避免在此代码中使用 with activesheet,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26255332/

相关文章:

excel - 返回值的 Sub

excel - 1004错误:未找到任何单元格,容易解决吗?

vba - 删除列中所有有错误的行

excel - 将单个项目从范围插入 ListBox

ms-access - 用于关闭除自身之外的所有 Excel 实例的 VBA 脚本

vba - 条件格式,虽然应用但没有出现格式

arrays - 防止重新计算命名范围中使用的用户定义函数

sql - VBA:使用两个参数调用 SQL Server 存储过程

excel - 自动过滤/隐藏不包含数组中单词的单元格行

c# - 在特定工作表上打开 Excel 文件