Excel VBA - Scoping Const Variable to be Accessed only by Current Project Announcing the...

Can a new player join a group only when a new campaign starts?

Dating a Former Employee

How much damage would a cupful of neutron star matter do to the Earth?

An adverb for when you're not exaggerating

Is there hard evidence that the grant peer review system performs significantly better than random?

What would you call this weird metallic apparatus that allows you to lift people?

If Windows 7 doesn't support WSL, then what does Linux subsystem option mean?

Why is Nikon 1.4g better when Nikon 1.8g is sharper?

Is a ledger board required if the side of my house is wood?

Is grep documentation about ignoring case wrong, since it doesn't ignore case in filenames?

Is it possible for SQL statements to execute concurrently within a single session in SQL Server?

Generate an RGB colour grid

Selecting user stories during sprint planning

Project Euler #1 in C++

How can I reduce the gap between left and right of cdot with a macro?

Has negative voting ever been officially implemented in elections, or seriously proposed, or even studied?

Would the Life Transference spell be unbalanced if it ignored resistance and immunity?

What is the difference between globalisation and imperialism?

Time to Settle Down!

Is there any word for a place full of confusion?

How does light 'choose' between wave and particle behaviour?

How fail-safe is nr as stop bytes?

A term for a woman complaining about things/begging in a cute/childish way

Is there a kind of relay only consumes power when switching?



Excel VBA - Scoping Const Variable to be Accessed only by Current Project



Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 23, 2019 at 00:00UTC (8:00pm US/Eastern)How to bypass the VBA project password from ExcelExcel creates non-existent worksheets in VBA Project ExplorerAssigning a variable based on a formula in VBA ExcelMS Project Macro VBAExcel VBA Code, ON Variable GOTO AlternativesExcel userform VBAExcel - vba, assign formula value to variableHow to verify information is entered in cell only if adjacent cell is not blank. Excel VBAExcel VBA - Use string variable as input to Union MethodExcel VBA macros have disappeared





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







1















I have an Excel Add-in for storage of UDF's as well as a personal workbook for storage of subroutines.



Inside of the Add-in, I have a module for constants, where I have an entry for ideal gas constant:



Global Const r = 8.314 'Same result using Global or Public


This "global" constant can be accessed from all modules within the Excel Add-in and the personal workbook.



My issue is that I would like to be able to limit the scope of this variable to only the modules of the add-in and no other open projects. Otherwise, I need to keep track in all open projects as to what variables I'm declaring as Global. Eventually, I'll end up like NASA, getting my units confused...



Thanks all for your help in advance.










share|improve this question







New contributor




Michael James is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.



























    1















    I have an Excel Add-in for storage of UDF's as well as a personal workbook for storage of subroutines.



    Inside of the Add-in, I have a module for constants, where I have an entry for ideal gas constant:



    Global Const r = 8.314 'Same result using Global or Public


    This "global" constant can be accessed from all modules within the Excel Add-in and the personal workbook.



    My issue is that I would like to be able to limit the scope of this variable to only the modules of the add-in and no other open projects. Otherwise, I need to keep track in all open projects as to what variables I'm declaring as Global. Eventually, I'll end up like NASA, getting my units confused...



    Thanks all for your help in advance.










    share|improve this question







    New contributor




    Michael James is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.























      1












      1








      1








      I have an Excel Add-in for storage of UDF's as well as a personal workbook for storage of subroutines.



      Inside of the Add-in, I have a module for constants, where I have an entry for ideal gas constant:



      Global Const r = 8.314 'Same result using Global or Public


      This "global" constant can be accessed from all modules within the Excel Add-in and the personal workbook.



      My issue is that I would like to be able to limit the scope of this variable to only the modules of the add-in and no other open projects. Otherwise, I need to keep track in all open projects as to what variables I'm declaring as Global. Eventually, I'll end up like NASA, getting my units confused...



      Thanks all for your help in advance.










      share|improve this question







      New contributor




      Michael James is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.












      I have an Excel Add-in for storage of UDF's as well as a personal workbook for storage of subroutines.



      Inside of the Add-in, I have a module for constants, where I have an entry for ideal gas constant:



      Global Const r = 8.314 'Same result using Global or Public


      This "global" constant can be accessed from all modules within the Excel Add-in and the personal workbook.



      My issue is that I would like to be able to limit the scope of this variable to only the modules of the add-in and no other open projects. Otherwise, I need to keep track in all open projects as to what variables I'm declaring as Global. Eventually, I'll end up like NASA, getting my units confused...



      Thanks all for your help in advance.







      microsoft-excel vba visual-basic global






      share|improve this question







      New contributor




      Michael James is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      share|improve this question







      New contributor




      Michael James is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      share|improve this question




      share|improve this question






      New contributor




      Michael James is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      asked 10 hours ago









      Michael JamesMichael James

      82




      82




      New contributor




      Michael James is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.





      New contributor





      Michael James is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      Michael James is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






















          2 Answers
          2






          active

          oldest

          votes


















          0














          Global is an obsolete keyword; the only difference between Global and Public is that you can't use Global in a class module. Prefer Public for consistency.



          Use the little-known Friend access modifier to make a member accessible everywhere inside the project it's declared in, but only within that project.



          The caveat is that it's only usable in a class module, and only for procedures - you can't make a Friend Const.



          A work-around could be to leverage the hidden VB_PredeclaredId class attribute and set it to True - create a new text file in Notepad, with this content:



          VERSION 1.0 CLASS
          BEGIN
          MultiUse = -1 'True
          END
          Attribute VB_Name = "StaticClass1"
          Attribute VB_GlobalNameSpace = False
          Attribute VB_Creatable = False
          Attribute VB_PredeclaredId = True
          Attribute VB_Exposed = False
          Option Explicit


          Save the file with a .cls extension, then import it into your project.



          Then you can rename it to something more meaningful, and expose a Friend Property Get member:



          Friend Property Get R() As Single
          R = 8.314
          End Property


          And now you can use that value, but only within the project that contains this class. Because of the PredeclaredId attribute, you don't need to create a New instance:



          Debug.Print StaticClass1.R ' 8.314


          Sadly (?) the VB_GlobalNamespace attribute has no effect in VBA user classes, so the qualifying object (the predeclared class instance has the same name as the class module itself - that's exactly how UserForm1.Show can work) is required.




          Caution: it can be tempting to store instance state (e.g. private module-level variables) on a default instance (especially in forms), but it should be avoided whenever possible. If you need to store state, consider working with a New instance of the class instead. Stateful default instances are more prone to bugs, notably because the object's lifetime is managed by the VBA run-time, not by user code. If the default instance is recycled/recreated, any state previously held is reset to whatever the design-time defaults are.




          Note that class modules are private by default, which already makes them invisible to other referencing projects. You can change the Instancing property of the class to make it PublicNotCreatable, which will change the value of it VB_Exposed attribute to True:



          Attribute VB_Creatable = False
          Attribute VB_PredeclaredId = True
          Attribute VB_Exposed = True


          Public classes can be accessed from outside the project, but can't be created directly with the New keyword (changing the value of the VB_Creatable attribute has no effect in VBA). With a public/exposed class, referencing projects will be able to invoke the Public members, but not the Friend ones:



          Public Property Get UseMeAnywhere() As Long
          UseMeAnywhere = 42
          End Property

          Friend Property Get YouOnlySeeMeInThisProject() As Long
          YouOnlySeeMeInThisProject = 42
          End Property





          share|improve this answer


























          • Thank you, this works so well! I've set the scope of the new Class to "PublicNotCreatable", which I'm surmising negated the creation of the class from notepad. If I do want to use this constant outside of the current project, I still need to point the calling project to the appropriate project identifier and class name, e.g. "mjFunctions.Constants.R". I'm assuming there's no other way to access this class property from outside of the "mjFunctions" add-in.

            – Michael James
            10 hours ago








          • 1





            In addition, even accessing this property from within "mjFunctions" requires me to specify the "Constants" class, which should greatly prevent against confusion.

            – Michael James
            9 hours ago











          • @MichaelJames Yes! Explicit qualifiers are always a very good thing! IMO the VB_PredeclaredId attribute is the single most useful hidden VBA gem. With it you can expose a public parameterized factory method that creates & returns an initialized new instance of the class, so you can then do e.g. Set coord = GridCoord.Create(4, 2). Note that Rubberduck surfaces these attributes with special annotation comments, and automatically synchronizes hidden attributes with the annotations, so '@PredeclaredId at the top, synchronize, and done!

            – Mathieu Guindon
            9 hours ago











          • Is there any way to access the Class Attributes without creating the class in notepad and importing?

            – Michael James
            9 hours ago











          • @MichaelJames yes, with the Rubberduck add-in (an open-source project I contribute to) you can just add '@PredeclaredId at the top, and/or '@ModuleDescription("This module contains important stuff"), and a bunch of others. Desynchronized attributes/annotations show up under "Rubberduck Opportunities" in the inspection results toolwindow, and then a quick-fix can automatically synchronize them.

            – Mathieu Guindon
            9 hours ago





















          1














          If you want to limit the scope of a constant or variable to that specific project (workbook, add-in, etc.) you would want to use the Public identifier instead of Global.



          Public limits the scope of a constant or variable, or sub to just that project.



          After a comment that this didn't fix the problem, I think the next step would then to be also adding an Option Private statement to the declaration section of the module.
          This will limit the scope to only the project that the module sits within, not any open project. Link included below from Microsoft Docs for how to do this specifically.



          For more information on scope and visibility see the link below from the Microsoft Docs:



          https://docs.microsoft.com/en-us/office/vba/language/concepts/getting-started/understanding-scope-and-visibility



          https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/option-private-statement






          share|improve this answer










          New contributor




          DataNinja is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.





















          • Thanks for the quick reply. Unfortunately, I've tested both Global and Public. Both allow access to the variable from all open projects. In case this is version-related, this issue is being seen in VBA for Excel 2016.

            – Michael James
            10 hours ago













          • Option Private Module is the simplest solution - I always forget about that option. Note that the distinction between Global and Public in this answer is rather misleading though. Consider editing it out.

            – Mathieu Guindon
            10 hours ago














          Your Answer








          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "3"
          };
          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
          });


          }
          });






          Michael James is a new contributor. Be nice, and check out our Code of Conduct.










          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsuperuser.com%2fquestions%2f1427030%2fexcel-vba-scoping-const-variable-to-be-accessed-only-by-current-project%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          0














          Global is an obsolete keyword; the only difference between Global and Public is that you can't use Global in a class module. Prefer Public for consistency.



          Use the little-known Friend access modifier to make a member accessible everywhere inside the project it's declared in, but only within that project.



          The caveat is that it's only usable in a class module, and only for procedures - you can't make a Friend Const.



          A work-around could be to leverage the hidden VB_PredeclaredId class attribute and set it to True - create a new text file in Notepad, with this content:



          VERSION 1.0 CLASS
          BEGIN
          MultiUse = -1 'True
          END
          Attribute VB_Name = "StaticClass1"
          Attribute VB_GlobalNameSpace = False
          Attribute VB_Creatable = False
          Attribute VB_PredeclaredId = True
          Attribute VB_Exposed = False
          Option Explicit


          Save the file with a .cls extension, then import it into your project.



          Then you can rename it to something more meaningful, and expose a Friend Property Get member:



          Friend Property Get R() As Single
          R = 8.314
          End Property


          And now you can use that value, but only within the project that contains this class. Because of the PredeclaredId attribute, you don't need to create a New instance:



          Debug.Print StaticClass1.R ' 8.314


          Sadly (?) the VB_GlobalNamespace attribute has no effect in VBA user classes, so the qualifying object (the predeclared class instance has the same name as the class module itself - that's exactly how UserForm1.Show can work) is required.




          Caution: it can be tempting to store instance state (e.g. private module-level variables) on a default instance (especially in forms), but it should be avoided whenever possible. If you need to store state, consider working with a New instance of the class instead. Stateful default instances are more prone to bugs, notably because the object's lifetime is managed by the VBA run-time, not by user code. If the default instance is recycled/recreated, any state previously held is reset to whatever the design-time defaults are.




          Note that class modules are private by default, which already makes them invisible to other referencing projects. You can change the Instancing property of the class to make it PublicNotCreatable, which will change the value of it VB_Exposed attribute to True:



          Attribute VB_Creatable = False
          Attribute VB_PredeclaredId = True
          Attribute VB_Exposed = True


          Public classes can be accessed from outside the project, but can't be created directly with the New keyword (changing the value of the VB_Creatable attribute has no effect in VBA). With a public/exposed class, referencing projects will be able to invoke the Public members, but not the Friend ones:



          Public Property Get UseMeAnywhere() As Long
          UseMeAnywhere = 42
          End Property

          Friend Property Get YouOnlySeeMeInThisProject() As Long
          YouOnlySeeMeInThisProject = 42
          End Property





          share|improve this answer


























          • Thank you, this works so well! I've set the scope of the new Class to "PublicNotCreatable", which I'm surmising negated the creation of the class from notepad. If I do want to use this constant outside of the current project, I still need to point the calling project to the appropriate project identifier and class name, e.g. "mjFunctions.Constants.R". I'm assuming there's no other way to access this class property from outside of the "mjFunctions" add-in.

            – Michael James
            10 hours ago








          • 1





            In addition, even accessing this property from within "mjFunctions" requires me to specify the "Constants" class, which should greatly prevent against confusion.

            – Michael James
            9 hours ago











          • @MichaelJames Yes! Explicit qualifiers are always a very good thing! IMO the VB_PredeclaredId attribute is the single most useful hidden VBA gem. With it you can expose a public parameterized factory method that creates & returns an initialized new instance of the class, so you can then do e.g. Set coord = GridCoord.Create(4, 2). Note that Rubberduck surfaces these attributes with special annotation comments, and automatically synchronizes hidden attributes with the annotations, so '@PredeclaredId at the top, synchronize, and done!

            – Mathieu Guindon
            9 hours ago











          • Is there any way to access the Class Attributes without creating the class in notepad and importing?

            – Michael James
            9 hours ago











          • @MichaelJames yes, with the Rubberduck add-in (an open-source project I contribute to) you can just add '@PredeclaredId at the top, and/or '@ModuleDescription("This module contains important stuff"), and a bunch of others. Desynchronized attributes/annotations show up under "Rubberduck Opportunities" in the inspection results toolwindow, and then a quick-fix can automatically synchronize them.

            – Mathieu Guindon
            9 hours ago


















          0














          Global is an obsolete keyword; the only difference between Global and Public is that you can't use Global in a class module. Prefer Public for consistency.



          Use the little-known Friend access modifier to make a member accessible everywhere inside the project it's declared in, but only within that project.



          The caveat is that it's only usable in a class module, and only for procedures - you can't make a Friend Const.



          A work-around could be to leverage the hidden VB_PredeclaredId class attribute and set it to True - create a new text file in Notepad, with this content:



          VERSION 1.0 CLASS
          BEGIN
          MultiUse = -1 'True
          END
          Attribute VB_Name = "StaticClass1"
          Attribute VB_GlobalNameSpace = False
          Attribute VB_Creatable = False
          Attribute VB_PredeclaredId = True
          Attribute VB_Exposed = False
          Option Explicit


          Save the file with a .cls extension, then import it into your project.



          Then you can rename it to something more meaningful, and expose a Friend Property Get member:



          Friend Property Get R() As Single
          R = 8.314
          End Property


          And now you can use that value, but only within the project that contains this class. Because of the PredeclaredId attribute, you don't need to create a New instance:



          Debug.Print StaticClass1.R ' 8.314


          Sadly (?) the VB_GlobalNamespace attribute has no effect in VBA user classes, so the qualifying object (the predeclared class instance has the same name as the class module itself - that's exactly how UserForm1.Show can work) is required.




          Caution: it can be tempting to store instance state (e.g. private module-level variables) on a default instance (especially in forms), but it should be avoided whenever possible. If you need to store state, consider working with a New instance of the class instead. Stateful default instances are more prone to bugs, notably because the object's lifetime is managed by the VBA run-time, not by user code. If the default instance is recycled/recreated, any state previously held is reset to whatever the design-time defaults are.




          Note that class modules are private by default, which already makes them invisible to other referencing projects. You can change the Instancing property of the class to make it PublicNotCreatable, which will change the value of it VB_Exposed attribute to True:



          Attribute VB_Creatable = False
          Attribute VB_PredeclaredId = True
          Attribute VB_Exposed = True


          Public classes can be accessed from outside the project, but can't be created directly with the New keyword (changing the value of the VB_Creatable attribute has no effect in VBA). With a public/exposed class, referencing projects will be able to invoke the Public members, but not the Friend ones:



          Public Property Get UseMeAnywhere() As Long
          UseMeAnywhere = 42
          End Property

          Friend Property Get YouOnlySeeMeInThisProject() As Long
          YouOnlySeeMeInThisProject = 42
          End Property





          share|improve this answer


























          • Thank you, this works so well! I've set the scope of the new Class to "PublicNotCreatable", which I'm surmising negated the creation of the class from notepad. If I do want to use this constant outside of the current project, I still need to point the calling project to the appropriate project identifier and class name, e.g. "mjFunctions.Constants.R". I'm assuming there's no other way to access this class property from outside of the "mjFunctions" add-in.

            – Michael James
            10 hours ago








          • 1





            In addition, even accessing this property from within "mjFunctions" requires me to specify the "Constants" class, which should greatly prevent against confusion.

            – Michael James
            9 hours ago











          • @MichaelJames Yes! Explicit qualifiers are always a very good thing! IMO the VB_PredeclaredId attribute is the single most useful hidden VBA gem. With it you can expose a public parameterized factory method that creates & returns an initialized new instance of the class, so you can then do e.g. Set coord = GridCoord.Create(4, 2). Note that Rubberduck surfaces these attributes with special annotation comments, and automatically synchronizes hidden attributes with the annotations, so '@PredeclaredId at the top, synchronize, and done!

            – Mathieu Guindon
            9 hours ago











          • Is there any way to access the Class Attributes without creating the class in notepad and importing?

            – Michael James
            9 hours ago











          • @MichaelJames yes, with the Rubberduck add-in (an open-source project I contribute to) you can just add '@PredeclaredId at the top, and/or '@ModuleDescription("This module contains important stuff"), and a bunch of others. Desynchronized attributes/annotations show up under "Rubberduck Opportunities" in the inspection results toolwindow, and then a quick-fix can automatically synchronize them.

            – Mathieu Guindon
            9 hours ago
















          0












          0








          0







          Global is an obsolete keyword; the only difference between Global and Public is that you can't use Global in a class module. Prefer Public for consistency.



          Use the little-known Friend access modifier to make a member accessible everywhere inside the project it's declared in, but only within that project.



          The caveat is that it's only usable in a class module, and only for procedures - you can't make a Friend Const.



          A work-around could be to leverage the hidden VB_PredeclaredId class attribute and set it to True - create a new text file in Notepad, with this content:



          VERSION 1.0 CLASS
          BEGIN
          MultiUse = -1 'True
          END
          Attribute VB_Name = "StaticClass1"
          Attribute VB_GlobalNameSpace = False
          Attribute VB_Creatable = False
          Attribute VB_PredeclaredId = True
          Attribute VB_Exposed = False
          Option Explicit


          Save the file with a .cls extension, then import it into your project.



          Then you can rename it to something more meaningful, and expose a Friend Property Get member:



          Friend Property Get R() As Single
          R = 8.314
          End Property


          And now you can use that value, but only within the project that contains this class. Because of the PredeclaredId attribute, you don't need to create a New instance:



          Debug.Print StaticClass1.R ' 8.314


          Sadly (?) the VB_GlobalNamespace attribute has no effect in VBA user classes, so the qualifying object (the predeclared class instance has the same name as the class module itself - that's exactly how UserForm1.Show can work) is required.




          Caution: it can be tempting to store instance state (e.g. private module-level variables) on a default instance (especially in forms), but it should be avoided whenever possible. If you need to store state, consider working with a New instance of the class instead. Stateful default instances are more prone to bugs, notably because the object's lifetime is managed by the VBA run-time, not by user code. If the default instance is recycled/recreated, any state previously held is reset to whatever the design-time defaults are.




          Note that class modules are private by default, which already makes them invisible to other referencing projects. You can change the Instancing property of the class to make it PublicNotCreatable, which will change the value of it VB_Exposed attribute to True:



          Attribute VB_Creatable = False
          Attribute VB_PredeclaredId = True
          Attribute VB_Exposed = True


          Public classes can be accessed from outside the project, but can't be created directly with the New keyword (changing the value of the VB_Creatable attribute has no effect in VBA). With a public/exposed class, referencing projects will be able to invoke the Public members, but not the Friend ones:



          Public Property Get UseMeAnywhere() As Long
          UseMeAnywhere = 42
          End Property

          Friend Property Get YouOnlySeeMeInThisProject() As Long
          YouOnlySeeMeInThisProject = 42
          End Property





          share|improve this answer















          Global is an obsolete keyword; the only difference between Global and Public is that you can't use Global in a class module. Prefer Public for consistency.



          Use the little-known Friend access modifier to make a member accessible everywhere inside the project it's declared in, but only within that project.



          The caveat is that it's only usable in a class module, and only for procedures - you can't make a Friend Const.



          A work-around could be to leverage the hidden VB_PredeclaredId class attribute and set it to True - create a new text file in Notepad, with this content:



          VERSION 1.0 CLASS
          BEGIN
          MultiUse = -1 'True
          END
          Attribute VB_Name = "StaticClass1"
          Attribute VB_GlobalNameSpace = False
          Attribute VB_Creatable = False
          Attribute VB_PredeclaredId = True
          Attribute VB_Exposed = False
          Option Explicit


          Save the file with a .cls extension, then import it into your project.



          Then you can rename it to something more meaningful, and expose a Friend Property Get member:



          Friend Property Get R() As Single
          R = 8.314
          End Property


          And now you can use that value, but only within the project that contains this class. Because of the PredeclaredId attribute, you don't need to create a New instance:



          Debug.Print StaticClass1.R ' 8.314


          Sadly (?) the VB_GlobalNamespace attribute has no effect in VBA user classes, so the qualifying object (the predeclared class instance has the same name as the class module itself - that's exactly how UserForm1.Show can work) is required.




          Caution: it can be tempting to store instance state (e.g. private module-level variables) on a default instance (especially in forms), but it should be avoided whenever possible. If you need to store state, consider working with a New instance of the class instead. Stateful default instances are more prone to bugs, notably because the object's lifetime is managed by the VBA run-time, not by user code. If the default instance is recycled/recreated, any state previously held is reset to whatever the design-time defaults are.




          Note that class modules are private by default, which already makes them invisible to other referencing projects. You can change the Instancing property of the class to make it PublicNotCreatable, which will change the value of it VB_Exposed attribute to True:



          Attribute VB_Creatable = False
          Attribute VB_PredeclaredId = True
          Attribute VB_Exposed = True


          Public classes can be accessed from outside the project, but can't be created directly with the New keyword (changing the value of the VB_Creatable attribute has no effect in VBA). With a public/exposed class, referencing projects will be able to invoke the Public members, but not the Friend ones:



          Public Property Get UseMeAnywhere() As Long
          UseMeAnywhere = 42
          End Property

          Friend Property Get YouOnlySeeMeInThisProject() As Long
          YouOnlySeeMeInThisProject = 42
          End Property






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 10 hours ago

























          answered 10 hours ago









          Mathieu GuindonMathieu Guindon

          649311




          649311













          • Thank you, this works so well! I've set the scope of the new Class to "PublicNotCreatable", which I'm surmising negated the creation of the class from notepad. If I do want to use this constant outside of the current project, I still need to point the calling project to the appropriate project identifier and class name, e.g. "mjFunctions.Constants.R". I'm assuming there's no other way to access this class property from outside of the "mjFunctions" add-in.

            – Michael James
            10 hours ago








          • 1





            In addition, even accessing this property from within "mjFunctions" requires me to specify the "Constants" class, which should greatly prevent against confusion.

            – Michael James
            9 hours ago











          • @MichaelJames Yes! Explicit qualifiers are always a very good thing! IMO the VB_PredeclaredId attribute is the single most useful hidden VBA gem. With it you can expose a public parameterized factory method that creates & returns an initialized new instance of the class, so you can then do e.g. Set coord = GridCoord.Create(4, 2). Note that Rubberduck surfaces these attributes with special annotation comments, and automatically synchronizes hidden attributes with the annotations, so '@PredeclaredId at the top, synchronize, and done!

            – Mathieu Guindon
            9 hours ago











          • Is there any way to access the Class Attributes without creating the class in notepad and importing?

            – Michael James
            9 hours ago











          • @MichaelJames yes, with the Rubberduck add-in (an open-source project I contribute to) you can just add '@PredeclaredId at the top, and/or '@ModuleDescription("This module contains important stuff"), and a bunch of others. Desynchronized attributes/annotations show up under "Rubberduck Opportunities" in the inspection results toolwindow, and then a quick-fix can automatically synchronize them.

            – Mathieu Guindon
            9 hours ago





















          • Thank you, this works so well! I've set the scope of the new Class to "PublicNotCreatable", which I'm surmising negated the creation of the class from notepad. If I do want to use this constant outside of the current project, I still need to point the calling project to the appropriate project identifier and class name, e.g. "mjFunctions.Constants.R". I'm assuming there's no other way to access this class property from outside of the "mjFunctions" add-in.

            – Michael James
            10 hours ago








          • 1





            In addition, even accessing this property from within "mjFunctions" requires me to specify the "Constants" class, which should greatly prevent against confusion.

            – Michael James
            9 hours ago











          • @MichaelJames Yes! Explicit qualifiers are always a very good thing! IMO the VB_PredeclaredId attribute is the single most useful hidden VBA gem. With it you can expose a public parameterized factory method that creates & returns an initialized new instance of the class, so you can then do e.g. Set coord = GridCoord.Create(4, 2). Note that Rubberduck surfaces these attributes with special annotation comments, and automatically synchronizes hidden attributes with the annotations, so '@PredeclaredId at the top, synchronize, and done!

            – Mathieu Guindon
            9 hours ago











          • Is there any way to access the Class Attributes without creating the class in notepad and importing?

            – Michael James
            9 hours ago











          • @MichaelJames yes, with the Rubberduck add-in (an open-source project I contribute to) you can just add '@PredeclaredId at the top, and/or '@ModuleDescription("This module contains important stuff"), and a bunch of others. Desynchronized attributes/annotations show up under "Rubberduck Opportunities" in the inspection results toolwindow, and then a quick-fix can automatically synchronize them.

            – Mathieu Guindon
            9 hours ago



















          Thank you, this works so well! I've set the scope of the new Class to "PublicNotCreatable", which I'm surmising negated the creation of the class from notepad. If I do want to use this constant outside of the current project, I still need to point the calling project to the appropriate project identifier and class name, e.g. "mjFunctions.Constants.R". I'm assuming there's no other way to access this class property from outside of the "mjFunctions" add-in.

          – Michael James
          10 hours ago







          Thank you, this works so well! I've set the scope of the new Class to "PublicNotCreatable", which I'm surmising negated the creation of the class from notepad. If I do want to use this constant outside of the current project, I still need to point the calling project to the appropriate project identifier and class name, e.g. "mjFunctions.Constants.R". I'm assuming there's no other way to access this class property from outside of the "mjFunctions" add-in.

          – Michael James
          10 hours ago






          1




          1





          In addition, even accessing this property from within "mjFunctions" requires me to specify the "Constants" class, which should greatly prevent against confusion.

          – Michael James
          9 hours ago





          In addition, even accessing this property from within "mjFunctions" requires me to specify the "Constants" class, which should greatly prevent against confusion.

          – Michael James
          9 hours ago













          @MichaelJames Yes! Explicit qualifiers are always a very good thing! IMO the VB_PredeclaredId attribute is the single most useful hidden VBA gem. With it you can expose a public parameterized factory method that creates & returns an initialized new instance of the class, so you can then do e.g. Set coord = GridCoord.Create(4, 2). Note that Rubberduck surfaces these attributes with special annotation comments, and automatically synchronizes hidden attributes with the annotations, so '@PredeclaredId at the top, synchronize, and done!

          – Mathieu Guindon
          9 hours ago





          @MichaelJames Yes! Explicit qualifiers are always a very good thing! IMO the VB_PredeclaredId attribute is the single most useful hidden VBA gem. With it you can expose a public parameterized factory method that creates & returns an initialized new instance of the class, so you can then do e.g. Set coord = GridCoord.Create(4, 2). Note that Rubberduck surfaces these attributes with special annotation comments, and automatically synchronizes hidden attributes with the annotations, so '@PredeclaredId at the top, synchronize, and done!

          – Mathieu Guindon
          9 hours ago













          Is there any way to access the Class Attributes without creating the class in notepad and importing?

          – Michael James
          9 hours ago





          Is there any way to access the Class Attributes without creating the class in notepad and importing?

          – Michael James
          9 hours ago













          @MichaelJames yes, with the Rubberduck add-in (an open-source project I contribute to) you can just add '@PredeclaredId at the top, and/or '@ModuleDescription("This module contains important stuff"), and a bunch of others. Desynchronized attributes/annotations show up under "Rubberduck Opportunities" in the inspection results toolwindow, and then a quick-fix can automatically synchronize them.

          – Mathieu Guindon
          9 hours ago







          @MichaelJames yes, with the Rubberduck add-in (an open-source project I contribute to) you can just add '@PredeclaredId at the top, and/or '@ModuleDescription("This module contains important stuff"), and a bunch of others. Desynchronized attributes/annotations show up under "Rubberduck Opportunities" in the inspection results toolwindow, and then a quick-fix can automatically synchronize them.

          – Mathieu Guindon
          9 hours ago















          1














          If you want to limit the scope of a constant or variable to that specific project (workbook, add-in, etc.) you would want to use the Public identifier instead of Global.



          Public limits the scope of a constant or variable, or sub to just that project.



          After a comment that this didn't fix the problem, I think the next step would then to be also adding an Option Private statement to the declaration section of the module.
          This will limit the scope to only the project that the module sits within, not any open project. Link included below from Microsoft Docs for how to do this specifically.



          For more information on scope and visibility see the link below from the Microsoft Docs:



          https://docs.microsoft.com/en-us/office/vba/language/concepts/getting-started/understanding-scope-and-visibility



          https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/option-private-statement






          share|improve this answer










          New contributor




          DataNinja is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.





















          • Thanks for the quick reply. Unfortunately, I've tested both Global and Public. Both allow access to the variable from all open projects. In case this is version-related, this issue is being seen in VBA for Excel 2016.

            – Michael James
            10 hours ago













          • Option Private Module is the simplest solution - I always forget about that option. Note that the distinction between Global and Public in this answer is rather misleading though. Consider editing it out.

            – Mathieu Guindon
            10 hours ago


















          1














          If you want to limit the scope of a constant or variable to that specific project (workbook, add-in, etc.) you would want to use the Public identifier instead of Global.



          Public limits the scope of a constant or variable, or sub to just that project.



          After a comment that this didn't fix the problem, I think the next step would then to be also adding an Option Private statement to the declaration section of the module.
          This will limit the scope to only the project that the module sits within, not any open project. Link included below from Microsoft Docs for how to do this specifically.



          For more information on scope and visibility see the link below from the Microsoft Docs:



          https://docs.microsoft.com/en-us/office/vba/language/concepts/getting-started/understanding-scope-and-visibility



          https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/option-private-statement






          share|improve this answer










          New contributor




          DataNinja is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.





















          • Thanks for the quick reply. Unfortunately, I've tested both Global and Public. Both allow access to the variable from all open projects. In case this is version-related, this issue is being seen in VBA for Excel 2016.

            – Michael James
            10 hours ago













          • Option Private Module is the simplest solution - I always forget about that option. Note that the distinction between Global and Public in this answer is rather misleading though. Consider editing it out.

            – Mathieu Guindon
            10 hours ago
















          1












          1








          1







          If you want to limit the scope of a constant or variable to that specific project (workbook, add-in, etc.) you would want to use the Public identifier instead of Global.



          Public limits the scope of a constant or variable, or sub to just that project.



          After a comment that this didn't fix the problem, I think the next step would then to be also adding an Option Private statement to the declaration section of the module.
          This will limit the scope to only the project that the module sits within, not any open project. Link included below from Microsoft Docs for how to do this specifically.



          For more information on scope and visibility see the link below from the Microsoft Docs:



          https://docs.microsoft.com/en-us/office/vba/language/concepts/getting-started/understanding-scope-and-visibility



          https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/option-private-statement






          share|improve this answer










          New contributor




          DataNinja is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.










          If you want to limit the scope of a constant or variable to that specific project (workbook, add-in, etc.) you would want to use the Public identifier instead of Global.



          Public limits the scope of a constant or variable, or sub to just that project.



          After a comment that this didn't fix the problem, I think the next step would then to be also adding an Option Private statement to the declaration section of the module.
          This will limit the scope to only the project that the module sits within, not any open project. Link included below from Microsoft Docs for how to do this specifically.



          For more information on scope and visibility see the link below from the Microsoft Docs:



          https://docs.microsoft.com/en-us/office/vba/language/concepts/getting-started/understanding-scope-and-visibility



          https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/option-private-statement







          share|improve this answer










          New contributor




          DataNinja is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.









          share|improve this answer



          share|improve this answer








          edited 10 hours ago





















          New contributor




          DataNinja is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.









          answered 10 hours ago









          DataNinjaDataNinja

          214




          214




          New contributor




          DataNinja is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.





          New contributor





          DataNinja is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.






          DataNinja is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.













          • Thanks for the quick reply. Unfortunately, I've tested both Global and Public. Both allow access to the variable from all open projects. In case this is version-related, this issue is being seen in VBA for Excel 2016.

            – Michael James
            10 hours ago













          • Option Private Module is the simplest solution - I always forget about that option. Note that the distinction between Global and Public in this answer is rather misleading though. Consider editing it out.

            – Mathieu Guindon
            10 hours ago





















          • Thanks for the quick reply. Unfortunately, I've tested both Global and Public. Both allow access to the variable from all open projects. In case this is version-related, this issue is being seen in VBA for Excel 2016.

            – Michael James
            10 hours ago













          • Option Private Module is the simplest solution - I always forget about that option. Note that the distinction between Global and Public in this answer is rather misleading though. Consider editing it out.

            – Mathieu Guindon
            10 hours ago



















          Thanks for the quick reply. Unfortunately, I've tested both Global and Public. Both allow access to the variable from all open projects. In case this is version-related, this issue is being seen in VBA for Excel 2016.

          – Michael James
          10 hours ago







          Thanks for the quick reply. Unfortunately, I've tested both Global and Public. Both allow access to the variable from all open projects. In case this is version-related, this issue is being seen in VBA for Excel 2016.

          – Michael James
          10 hours ago















          Option Private Module is the simplest solution - I always forget about that option. Note that the distinction between Global and Public in this answer is rather misleading though. Consider editing it out.

          – Mathieu Guindon
          10 hours ago







          Option Private Module is the simplest solution - I always forget about that option. Note that the distinction between Global and Public in this answer is rather misleading though. Consider editing it out.

          – Mathieu Guindon
          10 hours ago












          Michael James is a new contributor. Be nice, and check out our Code of Conduct.










          draft saved

          draft discarded


















          Michael James is a new contributor. Be nice, and check out our Code of Conduct.













          Michael James is a new contributor. Be nice, and check out our Code of Conduct.












          Michael James is a new contributor. Be nice, and check out our Code of Conduct.
















          Thanks for contributing an answer to Super User!


          • 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%2fsuperuser.com%2fquestions%2f1427030%2fexcel-vba-scoping-const-variable-to-be-accessed-only-by-current-project%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

          Cannot install PyQt5 The Next CEO of Stack OverflowCannot install tcpreplay 3.4.4cannot...

          Kapp-Putsch Acontecimentos | Outros artigos | Menu de navegação

          Why did early computer designers eschew integers? The Next CEO of Stack OverflowWhat register...