Class Module vs Module in VBA - vba

I am new and trying to understand VBA.
What is the different between modules and class modules? How come I can only have Macros inside Modules. (I think I am wrong here, but I don't know how to add a macro from Class modules)
In the end I'm having to add all my event handlers inside class modules and have all my macro code inside modules.

Modules are global through out the code. By default recorded Macros are saved in Modules, though you can cut the code and paste the Sub/Function into a class.
Mod1.DoSomething() ' Mod1 doesn't need to be instantiated, its global through the app, there is only one instane of it and that's called a Singleton pattern.
Classes are a concept where you need to instantiate them and their scope is limited.
Public globalScope as New Class0 ' <-- class0's methods are available in and outside a Module or Class.
Private memberScope as New Class1 ' <-- class1's methods are available inside the whole Module or Class.
Dim localScope as New Class2 ' <-- class2's methods are only available inside a Sub/Function.
You'll probably want to keep your event handlers in a Module as that's global. If you dispose a class with Events those events won't be available.
ps in .Net coding "Modules" are called Static Classes
Ps2 an fyi the difference between a Subroutine and a Function is; a Function returns a value where as a Subroutine just does something.

Related

How does VB.NET execute a non-shared method without an instance? [duplicate]

I'm just curious to know that there is the (Name) property, which represents the name of the Form class. This property is used within the namespace to uniquely identify the class that the Form is an instance of and, in the case of Visual Basic, is used to access the default instance of the form.
Now where this Default Instance come from, why can't C# have a equivalent method to this.
Also for example to show a form in C# we do something like this:
// Only method
Form1 frm = new Form1();
frm.Show();
But in VB.Net we have both ways to do it:
' First common method
Form1.Show()
' Second method
Dim frm As New Form1()
frm.Show()
My question comes from this first method. What is this Form1, is it an instance of Form1 or the Form1 class itself? Now as I mentioned above the Form name is the Default instance in VB.Net. But we also know that Form1 is a class defined in Designer so how can the names be same for both the Instance and class name?
If Form1 is a class then there is no (Static\Shared) method named Show().
So where does this method come from?
What difference they have in the generated IL?
And finally why can't C# have an equivalent of this?
This was added back to the language in the version of VB.NET that came with VS2005. By popular demand, VB6 programmers had a hard time with seeing the difference between a type and a reference to an object of that type. Form1 vs frm in your snippet. There's history for that, VB didn't get classes until VB4 while forms go all the way back to VB1. This is otherwise quite crippling to the programmer's mind, understanding that difference is very important to get a shot at writing effective object oriented code. A big part of the reason that C# doesn't have this.
You can get this back in C# as well, albeit that it won't be quite so clean because C# doesn't allow adding properties and methods to the global namespace like VB.NET does. You can add a bit of glue to your form code, like this:
public partial class Form2 : Form {
[ThreadStatic] private static Form2 instance;
public Form2() {
InitializeComponent();
instance = this;
}
public static Form2 Instance {
get {
if (instance == null) {
instance = new Form2();
instance.FormClosed += delegate { instance = null; };
}
return instance;
}
}
}
You can now use Form2.Instance in your code, just like you could use Form2 in VB.NET. The code in the if statement of the property getter should be moved into its own private method to make it efficient, I left it this way for clarity.
Incidentally, the [ThreadStatic] attribute in that snippet is what has made many VB.NET programmers give up threading in utter despair. A problem when the abstraction is leaky. You are really better off not doing this at all.
VB is adding a load of code into your project behind your back, basically.
The easiest way to see what's going on is to build a minimal project and look at it with Reflector. I've just created a new WinForms app with VB and added this class:
Public Class OtherClass
Public Sub Foo()
Form1.Show()
End Sub
End Class
The compiled code for Foo looks like this when decompiled as C#:
public void Foo()
{
MyProject.Forms.Form1.Show();
}
MyProject.Forms is a property in the generated MyProject class, of type MyForms. When you start diving into this you see quite large amounts of generated code in there.
C# could do all of this, of course - but it doesn't typically have a history of doing quite as much behind your back. It builds extra methods and types for things like anonymous types, iterator blocks, lambda expressions etc - but not in quite the same way that VB does here. All the code that C# builds corresponds to source code that you've written - just cleverly transformed.
There are arguments for both approaches, of course. Personally I prefer the C# approach, but that's probably no surprise. I don't see why there should be a way of accessing an instance of a form as if it was a singleton but only for forms... I like the language to work the same way whether I'm using GUI classes or anything else, basically.

Member of a .NET class is empty in the VB6 object browser

At the moment I´m trying tests on the interoperability of VB6 and .NET using COM.
I have followed this simple example to call a .NET component from COM.
https://msdn.microsoft.com/en-us/library/ms973802.aspx
The DLL is registered and the assembly was "succesfully added to the cache". However when I take a look into the object browser of VB6 I can only see methods of the interface and not of the actual class. COM is set on visible and the correct path for the KeyFile, are both in the AssemblyInfo.vb file. The .NET Class+Interface looks like this:
Public Interface iTemperature
'some properties and functions
End Interface
Public Class NET_Temperature
Implements iTemperature
'some implemented public properties and functions
End Class
When I try to run the following Code:
Set moTempClass = New PhysServer2.NET_Temperature
Set moTemp = moTempClass
I´m getting the well known 429-runtime error, saying that creating an object through an Active-X-component does not work. There is a lot of information on the internet regarding this error with unregistered DLL/TLB, but I´m more concerned about the fact that only the methods and properties of the interface are shown in the object browser and not the implemented methods/properties of the interface - the class. How can I fix this Error and make the methods in my class sort of visible to COM and the object browser?

RealProxy issues with compile time

I have a class MyProxy derived from RealProxy and implemented the bare minimum of Invoke to silence compile time errors. I inherit from MyProxy a custom class TabControl2 which itself wraps (ie: decorator) an TabControl.
I wish to call/intercept TabControl methods via the decorator - implementing everything myself as a learning exercize.
I understood the Invoke() of RealProxy would allow runtime interception of undefined methods in the decorator and call Invoke() with details of the invocation, such as method and arguments; thus allowing me to optionally invoke the original "decorated" object
I have googled for examples found many in C# and ported much of the code over to vb.
This particular bit of code is killing me:
Dim tabCtrlGeneric As TabControl = New TabControl()
Dim tabCtrlDecorator As TabControl = CType(New TabControlReorder(tabCtrlGeneric), TabControl)
Is giving me a compile time errors about type...not sure why?

Use global variables inside dlls in vb6

I have a dll where i would like to access the global variables of the Project.
How can this be done in VB6?
You can not access anything in a different project unless you explicitly pass it between the projects via COM.
While it is syntactically correct to use a global variable it is a very poor idea. Add either a module or a class file and encapsulate your variable inside a property. If you want to access your properties from within your project a bas file is fine. If you are describing making an ActiveX dll and accessing properties with another, separate project you should make a class module. You will need to set the class Instancing property to something other than private.
'myproject.bas code
Option Explicit
private mblnIsDirty as boolean
Public Property Let IsDirty(ByVal vIsDirty)
mblnIsDirty = vIsDirty
End Property
Public Property Get IsDirt() As Boolean
IsDirty = mblnIsDirty
End Property

VB: call a method without initiating class

ok so i have a bunch of methods in a class. How can i call those methods with out initiating it like:
Dim aa as new classname
aa.method
The reason i want to do so is so that i dont have to keep re initiating it to loose its variable data.
In php you can create a static method and then call that method without creating an instance of that class
how can we do this in vb?
The static equivalent in VB is Shared