VBA_ Stop using useless Select, Activate, ActiveCell
인터넷에서 읽다가 좋아서 정리해 둔 것들인데 오래되서 몇 개는 소스출처가 없다.
Using useless Select, Activate, ActiveCell
url :: not found
Using Select, Activate and ActiveCell in VBA can bring problems. And shows problems. In general, if you use the macro-recorder and record a macro, then you would see lots of Select, Activate, ActiveCell and etc. And it would work. Then why is it a problem?
It is slow. All these .Activate and .Select actions take time.
It is not necessary – they could be avoided.
Consider this code (generated from a macro recorder):
1 | Sub Makro2() |
And compare it with a code, which actually does the same, but with declaring the variables, without using the active ones and depending on them:
1 | Sub TestMe() |
My adivece here is to consider .Select() and .Activate() as needless parts of the code and to refactor it until they are completely out. The only reason to leave them in the code is for aesthetics, e.g. at the end of the code, having a specific worksheet selected for display. This is a nice StackOverflow topic with some examples how to avoid them.
Stackoverflow _ GOOD
https://stackoverflow.com/questions/10714251/how-to-avoid-using-select-in-excel-vba
Some examples of how to avoid select
Use Dim’d variables
1 | Dim rng as Range |
Set the variable to the required range. There are many ways to refer to a single-cell range:
1 | Set rng = Range("A1") |
Or a multi-cell range:
1 | Set rng = Range("A1:B10") |
You can use the shortcut to the Evaluate method, but this is less efficient and should generally be avoided in production code.
1 | Set rng = [A1] |
All the above examples refer to cells on the active sheet. Unless you specifically want to work only with the active sheet, it is better to Dim a Worksheet variable too:
1 | Dim ws As Worksheet |
If you do want to work with the ActiveSheet, for clarity it’s best to be explicit. But take care, as some Worksheet methods change the active sheet.
1 | Set rng = ActiveSheet.Range("A1") |
Again, this refers to the active workbook. Unless you specifically want to work only with the ActiveWorkbook or ThisWorkbook, it is better to Dim a Workbook variable too.
1 | Dim wb As Workbook |
If you do want to work with the ActiveWorkbook, for clarity it’s best to be explicit. But take care, as many WorkBook methods change the active book.
1 | Set rng = ActiveWorkbook.Worksheets("Sheet1").Range("A1") |
You can also use the ThisWorkbook object to refer to the book containing the running code.
1 | Set rng = ThisWorkbook.Worksheets("Sheet1").Range("A1") |
A common (bad) piece of code is to open a book, get some data then close again
This is bad:
1 | Sub foo() |
And it would be better like:
1 | Sub foo() |
Pass ranges to your Subs and Functions as Range variables:
1 | Sub ClearRange(r as Range) |
You should also apply Methods (such as Find and Copy) to variables:
1 | Dim rng1 As Range |
If you are looping over a range of cells it is often better (faster) to copy the range values to a variant array first and loop over that:
1 | Dim dat As Variant |
This is a small taster for what’s possible.