I've heard much about the understandable abhorrence of using .Select
in Excel VBA, but am unsure of how to avoid using it. I am finding that my code would be more re-usable if I were able to use variables instead of Select
functions. However, I am not sure how to refer to things (like the ActiveCell
etc.) if not using Select
.
I have found this article on ranges and this example on the benefits of not using select but can't find anything on how?
Avoiding
Select
andActivate
is the move that makes you a bit better VBA developer. In general,Select
andActivate
are used when a macro is recorded, thus theParent
worksheet or range is always considered the active one.This is how you may avoid
Select
andActivate
in the following cases:Adding a new Worksheet and copying a cell on it:
From (code generated with macro recorder):
To:
When you want to copy range between worksheets:
From:
To:
Using fancy named ranges
You may access them with
[]
. Which is really beautiful, compared to the other way. Check yourself:The example from above would look like this:
Not copying values, but taking them
Usually, if you are willing to
select
, most probably you are copying something. If you are only interested in the values, this is a good option to avoid select:Range("B1:B6").Value = Range("A1:A6").Value
Try always to refer the Worksheet as well
This is probably the most common mistake at the vba. Whenever you copy ranges, sometimes the worksheet is not referred and thus VBA considers the ActiveWorksheet.
Can I really never use
.Select
or.Activate
for anything?.Activate
and.Select
is when you want make sure, that a specific Worksheet is selected for visual reasons. E.g., that your Excel would always open with the cover worksheet selected first, disregading which which was the activesheet when the file was closed. Thus, something like the code below is absolutelyok:
This is an example that will clear the contents of cell "A1" (or more if the selection type is xllastcell, etc). All done without having to select the cells.
I hope this helps someone.
IMHO use of
.select
comes from people, who like me started learning VBA by necessity through recording macros and then modifying the code without realizing that.select
and subsequentselection
is just an unnecessary middle-men..select
can be avoided, as many posted already, by directly working with the already existing objects, which allows various indirect referencing like calculating i and j in a complex way and then editing cell(i,j), etc.Otherwise, there is nothing implicitly wrong with
.select
itself and you can find uses for this easily, e.g. I have a spreadsheet that I populate with date, activate macro that does some magic with it and exports it in an acceptable format on a separate sheet, which, however, requires some final manual (unpredictable) inputs into an adjacent cell. So here comes the moment for.select
that saves me that additional mouse movement and click.I'm going to give the short answer since everyone else gave the long one.
You'll get .select and .activate whenever you record macros and reuse them. When you .select a cell or sheet it just makes it active. From that point on whenever you use unqualified references like
Range.Value
they just use the active cell and sheet. This can also be problematic if you don't watch where your code is placed or a user clicks on the workbook.So, you can eliminate these issues by directly referencing your cells. Which goes:
Or you could
There are various combinations of these methods, but that would be the general idea expressed as shortly as possible for impatient people like me.
Always state the workbook, worksheet and the cell/range.
For example:
Because end users will always just click buttons and as soon as the focus moves off of the workbook the code wants to work with then things go completely wrong.
And never use the index of a workbook.
You don't know what other workbooks will be open when the user runs your code.
Please note that in the following I'm comparing the Select approach (the one that the OP wants to avoid), with the Range approach (and this is the answer to the question). So don't stop reading when you see the first Select.
It really depends on what you are trying to do. Anyway a simple example could be useful. Let's suppose that you want to set the value of the active cell to "foo". Using ActiveCell you would write something like this:
If you want to use it for a cell that is not the active one, for instance for "B2", you should select it first, like this:
Using Ranges you can write a more generic macro that can be used to set the value of any cell you want to whatever you want:
Then you can rewrite Macro2 as:
And Macro1 as:
Hope this helps to clear things up a little bit.