Why should I not turn certain object references into an object variable? What are the guidelines?












1














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









share|improve this question




















  • 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
















1














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









share|improve this question




















  • 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














1












1








1







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









share|improve this question















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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














  • 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












1 Answer
1






active

oldest

votes


















2














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





share|improve this answer





















    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
    });


    }
    });














    draft saved

    draft discarded


















    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









    2














    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





    share|improve this answer


























      2














      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





      share|improve this answer
























        2












        2








        2






        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





        share|improve this answer












        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






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 21 '18 at 13:44









        Comintern

        18.4k42354




        18.4k42354






























            draft saved

            draft discarded




















































            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.




            draft saved


            draft discarded














            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





















































            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







            Popular posts from this blog

            Futebolista

            Feedback on college project

            Albești (Vaslui)