在这个代码中避免使用activesheet

我在这里收到了一些非常棒的帮助,用于编写如下所示的一个简短的macros(它完美地工作)。

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

另外,任何关于如何改善这个问题的指针都会被大大接受,我不需要经常这样做,但是我仍然想要改进,而且在这个networking上search几个小时似乎让我感到好奇。圆圈。

一如既往地感谢您抽出宝贵的时间。

  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 

因此,这些循环操作中的一部分可以集中处理,而另一些可以嵌套在一起,因此循环不会重复。 像date检查等其他操作确实需要逐个单元地进行,并且被单独留下。 将lr分配给最大行数只需要完成一次。