Why should I not turn certain object references into an object variable? What are the guidelines?
Inside my loop (see code below), why should I NOT turn the ws.Cells.SpecialCells(xlCellTypeFormulas) reference into a Range object variable? (Based on good coding habits, are we not supposed to turn all Range, Worksheet, and Workbook object references into object variables? Regardless if they are used once or many times?)
I did try it with success but I have this feeling I shouldn't but I don't know exactly why which leads me to ask for specific reasons.
Sub FormatAllFormulas()
Dim ws As Worksheet
Dim wsc As Sheets
Set wsc = ActiveWorkbook.Worksheets
For Each ws In wsc
With ws.Cells.SpecialCells(xlCellTypeFormulas)
.Style = "Currency"
.Font.Bold = True
.Interior.Color = 4908260
End With
Next ws
End Sub
excel vba variables
add a comment |
Inside my loop (see code below), why should I NOT turn the ws.Cells.SpecialCells(xlCellTypeFormulas) reference into a Range object variable? (Based on good coding habits, are we not supposed to turn all Range, Worksheet, and Workbook object references into object variables? Regardless if they are used once or many times?)
I did try it with success but I have this feeling I shouldn't but I don't know exactly why which leads me to ask for specific reasons.
Sub FormatAllFormulas()
Dim ws As Worksheet
Dim wsc As Sheets
Set wsc = ActiveWorkbook.Worksheets
For Each ws In wsc
With ws.Cells.SpecialCells(xlCellTypeFormulas)
.Style = "Currency"
.Font.Bold = True
.Interior.Color = 4908260
End With
Next ws
End Sub
excel vba variables
3
This is entirely a matter of opinion. Though in this case you almost certainly should (IMO!) use an object variable because it will make the error handling cleaner.
– Rory
Nov 21 '18 at 12:55
2
The only difference it makes may be the readability of the code. Code that is easier to read is better maintainable and leads into less errors. Sometimes it's better to keep the code short. Sometimes it's better to write a bit more for better understanding. Depends on you.
– Pᴇʜ
Nov 21 '18 at 12:58
add a comment |
Inside my loop (see code below), why should I NOT turn the ws.Cells.SpecialCells(xlCellTypeFormulas) reference into a Range object variable? (Based on good coding habits, are we not supposed to turn all Range, Worksheet, and Workbook object references into object variables? Regardless if they are used once or many times?)
I did try it with success but I have this feeling I shouldn't but I don't know exactly why which leads me to ask for specific reasons.
Sub FormatAllFormulas()
Dim ws As Worksheet
Dim wsc As Sheets
Set wsc = ActiveWorkbook.Worksheets
For Each ws In wsc
With ws.Cells.SpecialCells(xlCellTypeFormulas)
.Style = "Currency"
.Font.Bold = True
.Interior.Color = 4908260
End With
Next ws
End Sub
excel vba variables
Inside my loop (see code below), why should I NOT turn the ws.Cells.SpecialCells(xlCellTypeFormulas) reference into a Range object variable? (Based on good coding habits, are we not supposed to turn all Range, Worksheet, and Workbook object references into object variables? Regardless if they are used once or many times?)
I did try it with success but I have this feeling I shouldn't but I don't know exactly why which leads me to ask for specific reasons.
Sub FormatAllFormulas()
Dim ws As Worksheet
Dim wsc As Sheets
Set wsc = ActiveWorkbook.Worksheets
For Each ws In wsc
With ws.Cells.SpecialCells(xlCellTypeFormulas)
.Style = "Currency"
.Font.Bold = True
.Interior.Color = 4908260
End With
Next ws
End Sub
excel vba variables
excel vba variables
edited Nov 21 '18 at 12:53
Pᴇʜ
20.2k42650
20.2k42650
asked Nov 21 '18 at 12:45
GeekyFreaky
1247
1247
3
This is entirely a matter of opinion. Though in this case you almost certainly should (IMO!) use an object variable because it will make the error handling cleaner.
– Rory
Nov 21 '18 at 12:55
2
The only difference it makes may be the readability of the code. Code that is easier to read is better maintainable and leads into less errors. Sometimes it's better to keep the code short. Sometimes it's better to write a bit more for better understanding. Depends on you.
– Pᴇʜ
Nov 21 '18 at 12:58
add a comment |
3
This is entirely a matter of opinion. Though in this case you almost certainly should (IMO!) use an object variable because it will make the error handling cleaner.
– Rory
Nov 21 '18 at 12:55
2
The only difference it makes may be the readability of the code. Code that is easier to read is better maintainable and leads into less errors. Sometimes it's better to keep the code short. Sometimes it's better to write a bit more for better understanding. Depends on you.
– Pᴇʜ
Nov 21 '18 at 12:58
3
3
This is entirely a matter of opinion. Though in this case you almost certainly should (IMO!) use an object variable because it will make the error handling cleaner.
– Rory
Nov 21 '18 at 12:55
This is entirely a matter of opinion. Though in this case you almost certainly should (IMO!) use an object variable because it will make the error handling cleaner.
– Rory
Nov 21 '18 at 12:55
2
2
The only difference it makes may be the readability of the code. Code that is easier to read is better maintainable and leads into less errors. Sometimes it's better to keep the code short. Sometimes it's better to write a bit more for better understanding. Depends on you.
– Pᴇʜ
Nov 21 '18 at 12:58
The only difference it makes may be the readability of the code. Code that is easier to read is better maintainable and leads into less errors. Sometimes it's better to keep the code short. Sometimes it's better to write a bit more for better understanding. Depends on you.
– Pᴇʜ
Nov 21 '18 at 12:58
add a comment |
1 Answer
1
active
oldest
votes
You are getting a reference to a Range variable - it is just held by the With block itself. 5.4.2.21 of the language specification explains:
The With block variable is classified as a variable and has the same
declared type as <expression>.
At runtime, this is what happens:
If the value type of the evaluated expression is a class, it is
Set-assigned to an anonymous With block variable. Then,
<statement-block> is executed. After <statement-block> executes,
Nothing is assigned to the anonymous With block variable.
Functionally, this code from your example...
For Each ws In wsc
With ws.Cells.SpecialCells(xlCellTypeFormulas)
.Style = "Currency"
.Font.Bold = True
.Interior.Color = 4908260
End With
Next ws
...is exactly the same as this:
For Each ws In wsc
Dim WithBlockVariable As Range
Set WithBlockVariable = ws.Cells.SpecialCells(xlCellTypeFormulas)
WithBlockVariable.Style = "Currency"
WithBlockVariable.Font.Bold = True
WithBlockVariable.Interior.Color = 4908260
Set WithBlockVariable = Nothing
Next ws
As far as which you should use, that's pretty much a judgement call. As pointed out in the comments, the With block can be much more readable that a local variable. The other consideration is that since the reference is implicit, you can't accidentally use it after the With block exits. This can be important in your example specifically, because declared variables always have procedure scope. That means in the expanded example, you could use WithBlockVariable outside the loop. So, if you don't intend to use it outside the block, you might as well make it impossible to use outside the block.
One last thing to note (and this is where people can get into performance problems) is that With blocks can save de-referencing operations if you find yourself repeatedly using more than one . in expressions. For example, if you're setting more than one of the properties on the Font:
With ws.Cells(1, 1)
.Font.Bold = True
.Font.Color = vbRed
.Font.Italic = True
End With
In this case, there's absolutely no reason to get an explicit reference to the Font, but notice that you're repeatedly calling the Range.Font property. This is always better:
With ws.Cells(1, 1).Font
.Bold = True
.Color = vbRed
.Italic = True
End With
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53412341%2fwhy-should-i-not-turn-certain-object-references-into-an-object-variable-what-ar%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
You are getting a reference to a Range variable - it is just held by the With block itself. 5.4.2.21 of the language specification explains:
The With block variable is classified as a variable and has the same
declared type as <expression>.
At runtime, this is what happens:
If the value type of the evaluated expression is a class, it is
Set-assigned to an anonymous With block variable. Then,
<statement-block> is executed. After <statement-block> executes,
Nothing is assigned to the anonymous With block variable.
Functionally, this code from your example...
For Each ws In wsc
With ws.Cells.SpecialCells(xlCellTypeFormulas)
.Style = "Currency"
.Font.Bold = True
.Interior.Color = 4908260
End With
Next ws
...is exactly the same as this:
For Each ws In wsc
Dim WithBlockVariable As Range
Set WithBlockVariable = ws.Cells.SpecialCells(xlCellTypeFormulas)
WithBlockVariable.Style = "Currency"
WithBlockVariable.Font.Bold = True
WithBlockVariable.Interior.Color = 4908260
Set WithBlockVariable = Nothing
Next ws
As far as which you should use, that's pretty much a judgement call. As pointed out in the comments, the With block can be much more readable that a local variable. The other consideration is that since the reference is implicit, you can't accidentally use it after the With block exits. This can be important in your example specifically, because declared variables always have procedure scope. That means in the expanded example, you could use WithBlockVariable outside the loop. So, if you don't intend to use it outside the block, you might as well make it impossible to use outside the block.
One last thing to note (and this is where people can get into performance problems) is that With blocks can save de-referencing operations if you find yourself repeatedly using more than one . in expressions. For example, if you're setting more than one of the properties on the Font:
With ws.Cells(1, 1)
.Font.Bold = True
.Font.Color = vbRed
.Font.Italic = True
End With
In this case, there's absolutely no reason to get an explicit reference to the Font, but notice that you're repeatedly calling the Range.Font property. This is always better:
With ws.Cells(1, 1).Font
.Bold = True
.Color = vbRed
.Italic = True
End With
add a comment |
You are getting a reference to a Range variable - it is just held by the With block itself. 5.4.2.21 of the language specification explains:
The With block variable is classified as a variable and has the same
declared type as <expression>.
At runtime, this is what happens:
If the value type of the evaluated expression is a class, it is
Set-assigned to an anonymous With block variable. Then,
<statement-block> is executed. After <statement-block> executes,
Nothing is assigned to the anonymous With block variable.
Functionally, this code from your example...
For Each ws In wsc
With ws.Cells.SpecialCells(xlCellTypeFormulas)
.Style = "Currency"
.Font.Bold = True
.Interior.Color = 4908260
End With
Next ws
...is exactly the same as this:
For Each ws In wsc
Dim WithBlockVariable As Range
Set WithBlockVariable = ws.Cells.SpecialCells(xlCellTypeFormulas)
WithBlockVariable.Style = "Currency"
WithBlockVariable.Font.Bold = True
WithBlockVariable.Interior.Color = 4908260
Set WithBlockVariable = Nothing
Next ws
As far as which you should use, that's pretty much a judgement call. As pointed out in the comments, the With block can be much more readable that a local variable. The other consideration is that since the reference is implicit, you can't accidentally use it after the With block exits. This can be important in your example specifically, because declared variables always have procedure scope. That means in the expanded example, you could use WithBlockVariable outside the loop. So, if you don't intend to use it outside the block, you might as well make it impossible to use outside the block.
One last thing to note (and this is where people can get into performance problems) is that With blocks can save de-referencing operations if you find yourself repeatedly using more than one . in expressions. For example, if you're setting more than one of the properties on the Font:
With ws.Cells(1, 1)
.Font.Bold = True
.Font.Color = vbRed
.Font.Italic = True
End With
In this case, there's absolutely no reason to get an explicit reference to the Font, but notice that you're repeatedly calling the Range.Font property. This is always better:
With ws.Cells(1, 1).Font
.Bold = True
.Color = vbRed
.Italic = True
End With
add a comment |
You are getting a reference to a Range variable - it is just held by the With block itself. 5.4.2.21 of the language specification explains:
The With block variable is classified as a variable and has the same
declared type as <expression>.
At runtime, this is what happens:
If the value type of the evaluated expression is a class, it is
Set-assigned to an anonymous With block variable. Then,
<statement-block> is executed. After <statement-block> executes,
Nothing is assigned to the anonymous With block variable.
Functionally, this code from your example...
For Each ws In wsc
With ws.Cells.SpecialCells(xlCellTypeFormulas)
.Style = "Currency"
.Font.Bold = True
.Interior.Color = 4908260
End With
Next ws
...is exactly the same as this:
For Each ws In wsc
Dim WithBlockVariable As Range
Set WithBlockVariable = ws.Cells.SpecialCells(xlCellTypeFormulas)
WithBlockVariable.Style = "Currency"
WithBlockVariable.Font.Bold = True
WithBlockVariable.Interior.Color = 4908260
Set WithBlockVariable = Nothing
Next ws
As far as which you should use, that's pretty much a judgement call. As pointed out in the comments, the With block can be much more readable that a local variable. The other consideration is that since the reference is implicit, you can't accidentally use it after the With block exits. This can be important in your example specifically, because declared variables always have procedure scope. That means in the expanded example, you could use WithBlockVariable outside the loop. So, if you don't intend to use it outside the block, you might as well make it impossible to use outside the block.
One last thing to note (and this is where people can get into performance problems) is that With blocks can save de-referencing operations if you find yourself repeatedly using more than one . in expressions. For example, if you're setting more than one of the properties on the Font:
With ws.Cells(1, 1)
.Font.Bold = True
.Font.Color = vbRed
.Font.Italic = True
End With
In this case, there's absolutely no reason to get an explicit reference to the Font, but notice that you're repeatedly calling the Range.Font property. This is always better:
With ws.Cells(1, 1).Font
.Bold = True
.Color = vbRed
.Italic = True
End With
You are getting a reference to a Range variable - it is just held by the With block itself. 5.4.2.21 of the language specification explains:
The With block variable is classified as a variable and has the same
declared type as <expression>.
At runtime, this is what happens:
If the value type of the evaluated expression is a class, it is
Set-assigned to an anonymous With block variable. Then,
<statement-block> is executed. After <statement-block> executes,
Nothing is assigned to the anonymous With block variable.
Functionally, this code from your example...
For Each ws In wsc
With ws.Cells.SpecialCells(xlCellTypeFormulas)
.Style = "Currency"
.Font.Bold = True
.Interior.Color = 4908260
End With
Next ws
...is exactly the same as this:
For Each ws In wsc
Dim WithBlockVariable As Range
Set WithBlockVariable = ws.Cells.SpecialCells(xlCellTypeFormulas)
WithBlockVariable.Style = "Currency"
WithBlockVariable.Font.Bold = True
WithBlockVariable.Interior.Color = 4908260
Set WithBlockVariable = Nothing
Next ws
As far as which you should use, that's pretty much a judgement call. As pointed out in the comments, the With block can be much more readable that a local variable. The other consideration is that since the reference is implicit, you can't accidentally use it after the With block exits. This can be important in your example specifically, because declared variables always have procedure scope. That means in the expanded example, you could use WithBlockVariable outside the loop. So, if you don't intend to use it outside the block, you might as well make it impossible to use outside the block.
One last thing to note (and this is where people can get into performance problems) is that With blocks can save de-referencing operations if you find yourself repeatedly using more than one . in expressions. For example, if you're setting more than one of the properties on the Font:
With ws.Cells(1, 1)
.Font.Bold = True
.Font.Color = vbRed
.Font.Italic = True
End With
In this case, there's absolutely no reason to get an explicit reference to the Font, but notice that you're repeatedly calling the Range.Font property. This is always better:
With ws.Cells(1, 1).Font
.Bold = True
.Color = vbRed
.Italic = True
End With
answered Nov 21 '18 at 13:44
Comintern
18.4k42354
18.4k42354
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53412341%2fwhy-should-i-not-turn-certain-object-references-into-an-object-variable-what-ar%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
3
This is entirely a matter of opinion. Though in this case you almost certainly should (IMO!) use an object variable because it will make the error handling cleaner.
– Rory
Nov 21 '18 at 12:55
2
The only difference it makes may be the readability of the code. Code that is easier to read is better maintainable and leads into less errors. Sometimes it's better to keep the code short. Sometimes it's better to write a bit more for better understanding. Depends on you.
– Pᴇʜ
Nov 21 '18 at 12:58