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;
}
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
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.
add a comment |
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
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.
add a comment |
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
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
microsoft-excel vba visual-basic global
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.
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.
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
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
Newinstance 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
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 theVB_PredeclaredIdattribute 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'@PredeclaredIdat 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'@PredeclaredIdat 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
add a comment |
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
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 Moduleis the simplest solution - I always forget about that option. Note that the distinction betweenGlobalandPublicin this answer is rather misleading though. Consider editing it out.
– Mathieu Guindon
10 hours ago
add a comment |
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.
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%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
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
Newinstance 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
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 theVB_PredeclaredIdattribute 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'@PredeclaredIdat 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'@PredeclaredIdat 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
add a comment |
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
Newinstance 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
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 theVB_PredeclaredIdattribute 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'@PredeclaredIdat 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'@PredeclaredIdat 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
add a comment |
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
Newinstance 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
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
Newinstance 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
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 theVB_PredeclaredIdattribute 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'@PredeclaredIdat 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'@PredeclaredIdat 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
add a comment |
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 theVB_PredeclaredIdattribute 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'@PredeclaredIdat 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'@PredeclaredIdat 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
add a comment |
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
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 Moduleis the simplest solution - I always forget about that option. Note that the distinction betweenGlobalandPublicin this answer is rather misleading though. Consider editing it out.
– Mathieu Guindon
10 hours ago
add a comment |
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
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 Moduleis the simplest solution - I always forget about that option. Note that the distinction betweenGlobalandPublicin this answer is rather misleading though. Consider editing it out.
– Mathieu Guindon
10 hours ago
add a comment |
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
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
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.
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 Moduleis the simplest solution - I always forget about that option. Note that the distinction betweenGlobalandPublicin this answer is rather misleading though. Consider editing it out.
– Mathieu Guindon
10 hours ago
add a comment |
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 Moduleis the simplest solution - I always forget about that option. Note that the distinction betweenGlobalandPublicin 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
add a comment |
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.
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.
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%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
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