Make function private for another workbook in excel vba - vba

First of all, sorry about my English. I'm still learning....
I wanna know how can I make some function or modulus inaccessible for another workbook. In contrast I need these function public for all modulus inside workbook. I make myself clear?
For example:
I need to open two workbook that contains function with the same name but these functions perform things a little bit different.

See here for an answer http://www.cpearson.com/excel/scope.aspx
Here's a copied summary:
If you want a variable to be accessible from anywhere within the project, but not accessible from another project, you need to use Option Private Module as the first line in the module (above and outside of any variable declaration or procedure). This option makes everything in the module accessible only from within the project. This means also that if you do want some project variables to be accessible from other projects and other project variables to be inaccessible from other projects, you need to declare them in separate modules.

Related

What is "Compile Error Cannot define a Public user-defined type within an object module"? : VBA

Compile error:
Cannot define a Public user-defined type within an object module
What does the above compile error mean in Visual Basic for Applications (VBA)?
I would like to point out that the exact same code had no error in a separate empty Powerpoint file.
Thank you.
You need to understand the different types of code modules in VBA. Basically, you can have
A regular module - here you put in code like subs, functions, types
A userform - I guess you know what a userform is. It contains the layout of the form and the so called code behind - that is all the code that is glued to the form, like event triggers.
A class module. A class is an own, user defined type. Additionally to a simple UDT (user defined type), a class has it's own functions and subroutines (yes, I know, this is extremely simplified)
Depending on the environment, you can have build-in modules. In Excel, these are Workbook and Worksheet modules, in Word the Document module (as far as I know in Powerpoint, there are no build in modules).
Now, all of the above, except for a regular module, define classes (user forms, worksheets, workbooks, documents are special kind of classes). And a class cannot contain a public type (it is already a public type), as simple as that. It's similar to the fact that you cannot define a Type within a Type.
I assume that you have your type defined in a user form code. If you need the type only within that form, declare it as private. It is allowed to define types within a class, but they need to be private, with other words, the type in unknown in other modules of your project, and, as a consequence, you cannot have public variables of that type or public functions that return that type.
If you need the type in more than one module, you need to move the type definition into a regular module (this is what GSerg wrote in the comments)

Passing parameters vs public variables when calling method in dll (vb.net)

I am moving some code from my main project into a dll in order to make my application more dynamic (the dll can be exchanged for another one, sort of a plugin). Several subroutines in my main project have been bundled into one in the dll, and different pieces of code are run depending on a variable passed from the main project. This is in turn selected from a database which is updated by the dll as it is loaded, making it possible to add completely new functionality without having to install a new version of the app.
Now, except for arguments being passed from the calling code to the subroutine in the dll, the code in that sub also uses values of some publicly declared variables that keep track of things like the source path of input data, whether the user has made changes to some objects etc. Before moving the code, these were declared in a module of my main project. The values are now, however, needed by the sub in my dll.
I could pass all those variable values as arguments to the sub in the dll even though most of them are not used every time the call is made (since I only use one sub for everything that the dll does). This seems like the simplest solution. However, I know that having methods with like 10+ parameters is considered bad practice. Or I could move the public variables to an interface dll (which already exists), values of which both my main project and my dll can access and update the values there.
Which is best (or least bad) in terms of performance? Could one of the choices have unexpected consequences?
This gives me the impression that your methods might be shared. You should instead pass these configuration parameter to the constructor of the object and keep those value as class variable. Then, your method can easily get the values from the class.
Class SomeClass
Public Sub New(ByVal someParameter As String)
Me.SomeParameter = someParameter
End Sub
Public ReadOnly Property SomeParameter As String
Public Sub SomeMethod()
' Can use Me.SomeParameter here
End Sub
End Class

Calling Private Macros / UDFs From Another Workbook (Add-In)

This is a follow-up question for my previous question: How Can I Prevent The Suggestion of Custom VBA Functions When Writing Formulas in Excel?
I have implemented the suggestions made in the answer given in order to make my macros and UDFs private, in a way which allows them to be called within other modules in the same workbook but prevents them from being suggested when writing formulas.
I'm trying to produce an Add-In which contains reusable macros and UDFs, and in other VBA projects I am adding this Add-In as a reference (tools > references) so that I can call the functions directly rather than using Application.Run()
By doing this, projects using these reusable functions will be easier to write as the required / optional parameters can be seen at the point of writing the line, and will generally keep the code looking tidier.
By implementing the solution to my first question to make these functions private, the functions are accessible from within the same workbook, however are not accessible to other workbooks.
Does anyone know a solution to achieve this?
If it needs to be accessible beyond the project it's defined in, then it must be Public.
Make macros and UDFs public in a standard code module.
Implement the "utility" code in class modules, and make these classes PublicNotCreatable. Now export these classes and open the .cls file in Notepad.
Locate the VB_PredeclaredId attribute and switch it to True, save and reimport it back in - given class Utilities, a VBA project that references that addin can call the code without creating an instance of the class (it can't New it up anyway), but you can access its public members as you would a default instance of any UserForm class, by qualifying the method with the class name:
foo = Utilities.DoSomething(42)
This is because the PredeclaredId makes a global-scope instance of the class named after the class itself: now you can use that class as if it were a standard module (or a Shared class in VB.NET), and its members won't be available as macros or UDF's.

How Can I Prevent The Suggestion of Custom VBA Functions When Writing Formulas in Excel?

I am writing a range of VBA functions / subs that can be reused in a number of projects. The issue I have is that these functions are listed in the suggested formula functions when using sheets.
Making the functions private will prevent this, but what it will also do is remove the handy hints showing the parameters for the functions when called from a module other than where the function is stored.
Does anyone know of a way to prevent the suggestion of custom functions without making them private?
Parameterless Public members of a standard module are one of two things:
Sub procedures and they're exposed as macros.
Function procedures and they're exposed as UDF's.
Note that members are implicitly Public if no access modifier is specified.
A Sub that has parameters can't be executed as a macro, so it won't show up as an available macro.
A Function that has side-effects (e.g. mutates some module/global state, or changes other cells' value) is bad code, and a UDF can't change another cell's value anyway.
Making the functions private will prevent this, but what it will also do is remove the handy hints showing the parameters for the functions when called from a module other than where the function is stored.
Making it Private not only "removes the handy hints", it makes the function inaccessible to other modules, and your code won't compile.
If your code has UDF's, put them all in the same standard module, e.g. UserFunctions, and make them explicitly Public for readability's sake.
If your code has macros, put them all in the same standard module, e.g. Macros, and make them explicitly Public for readability's sake.
If your code has functions and procedures that need to be Public (e.g. they're accessed from UDF's and/or macros), make them explicitly Public for readability's sake, and put them in standard modules named appropriately (i.e. avoid Helper and Manager modules, they inevitably become a dumping bag of whatever doesn't quite fit anywhere, and grow to a mess).
Then put this at the top:
Option Explicit
Option Private Module
That option (Private Module) prevents all public/exposed members from being picked up as macros and UDF's. Option Explicit should just be there anyway.
Another way is to implement logic in class modules; members of a class module can't be accessed without an instance of that class (i.e. an object), and therefore won't be exposed as macros/UDF's.

Declaring Constants outside of a subroutine

This is more of varification, but i want to be sure before i start altering some old code to clean it up.
If you have private varibales declared inside a module but outside a subroutine, when are these actually created. For example, this is how a module is set up:
'Local objects.....
'Function Main.....
'Subroutines.......
Private Constants..
Private variables..
More Subroutines...
If those variables are only used in one subroutine, should they be declared inside that subroutine or in the local objects or right outside the subroutine as they are now?
Thanks!
The CLR has no support for modules or module variables so modules become static classes and module variables become static fields.
As a rule, variables should be declared as close to the point they are used as possible. Their scope should also be as constrained as possible.
Turning a variable into a field is a pretty bad coding practice for several reasons:
It is extremely easy to make a mistake and reuse the same field in another part of your module, creating unexpected conditions.
You increase the lifetime of the objects in the variable significantly. Typically, once you exit the method, the variable is available for garbage collection. By turning it into a static field, the object will stay alive until it's replaced or the application terminates
Multiple threads will be able to see and access the same static field, potentially creating race conditions. Given how many things work asynchrously nowadays, this can be a significant problem