Solved How to count the number of instances of a class? (1 Viewer)

Guus2005

AWF VIP
Local time
Today, 05:37
Joined
Jun 26, 2007
Messages
2,645
Howdy,

Some time ago i posted this. A class to turn the hourglass on and off again.
Code:
Option Explicit
'
' clsHourglass
'
' This class sets the hourglass on and off. Also when you forget to turn it off.
'
Private Sub Class_Terminate()
    HourGlassOff
End Sub

Public Sub HourGlassOn()
    DoCmd.Hourglass True
End Sub

Public Sub HourGlassOff()
    DoCmd.Hourglass False
End Sub
And some sample code how to use it:
Code:
Option Explicit

Public Sub StartMeUp()

    Dim cHourglass As New clsHourglass

    cHourglass.HourGlassOn
   
    StartMeNext
   
    cHourglass.HourGlassOff

End Sub

Private Sub StartMeNext()

    Dim cHourglass As New clsHourglass

    cHourglass.HourGlassOn
'
'Lots of code here
'
    cHourglass.HourGlassOff

End Sub
After the procedure StartMeNext the hourglass is already turned off.

I want to add a counter to the class which counts the number of instances of that class.
Only then the counter reaches 1 the hourglass must be disabled.

I tried to use a static variable in the class but the scope doesn't reach into the next instance of the class.
I know i could use a global variable but then the class wouldn't be standalone anymore.

I know i have seen the solution somewhere but i can't reproduce it.

Thanks for your time!
 
Last edited:

CJ_London

Super Moderator
Staff member
Local time
Today, 04:37
Joined
Feb 19, 2013
Messages
16,553
Perhaps storing a value in the db properties (rather than using a global variable) but a bit puzzled as to why you would want multiple instances of a class to control the hourglass since there is only one pointer/hourglass. What is the benefit?
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 00:37
Joined
May 21, 2018
Messages
8,463
If you want to see if a single instance exists then the Class could add to tempvars on the initialize event and remove on the terminate event.
If you have many instances running at once (I would have the same question as CJ) you need to manage this is a collection. This is how it is done with multiple form instances. You can find many examples of how to do this.
 

Guus2005

AWF VIP
Local time
Today, 05:37
Joined
Jun 26, 2007
Messages
2,645
When the StartMeUp procedure runs, the Hourglass is set to true.
The StartMeNext procedure is called. Again the Hourglass is set to true. So far no problems
At the end of StartMeNext the Hourglass is set to False. This is a problem because this is not the right place to reset the Hourglass.

The Hourglass must be disabled in the same procedure it was enabled.

That's why i want a counter.
When the counter = 1, then i can reset the hourglass.

Now you can suggest the following change:
Code:
Private Sub StartMeNext()
'
'Lots of code here
'
End Sub
Just remove the hourglass code in the second procedure.
Again, this is just an example. The code is much more complex with more than 2 procedures. In total it has 6K lines of code.

It is written in Excel so i can't use TempVars.

Perhaps at this time it is wise to mention that i didn't write it. I just have to support it.
 

Minty

AWF VIP
Local time
Today, 04:37
Joined
Jul 26, 2013
Messages
10,355
I might be missing a point here, but If all the code that could call this is in separate modules then just don't turn it off except in the original calling module? by all means try turning it on as often as you want, just don't turn it off.
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 00:37
Joined
May 21, 2018
Messages
8,463
I want to add a counter to the class which counts the number of instances of that class.
That is not possible. A class is a template and creates instances.
As I said you need to make a custom collection if you need to manage multiple class intances
ClsHourGlasses
 

Guus2005

AWF VIP
Local time
Today, 05:37
Joined
Jun 26, 2007
Messages
2,645
StartMeNext can be used separately. In that case i need that hourglass toggle.
 

Guus2005

AWF VIP
Local time
Today, 05:37
Joined
Jun 26, 2007
Messages
2,645
@MajP, think you are right. Can't be done without some external variable, collection or registry setting.

Well, thanks for your time!
 

Minty

AWF VIP
Local time
Today, 04:37
Joined
Jul 26, 2013
Messages
10,355
StartMeNext can be used separately. In that case i need that hourglass toggle.
I can see that, but you could still use a boolean flag If it's been set then turn off at the end if not then don't?
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 00:37
Joined
May 21, 2018
Messages
8,463
I do not totally follow this, but I think you can have multiple instances. Once they go out of scope they turn the hour glass off, but that should not happen if their are other instances open. I do believe a custom collection could handle this.
Usually all of Pearson stuff is great, but that example is lacking. This is better
You always initialize your instance through the collection. Then when the collection goes out of scope or your collection count is zero you turn off the hourglass in the hourGlasses collection class.

I will see if I can demo if I get time.
 

Guus2005

AWF VIP
Local time
Today, 05:37
Joined
Jun 26, 2007
Messages
2,645
@Minty You are right. But then i would be using an external variable and the point was to avoid that.
@MajP Yes i could use a collection, but that would feel like a lot of overkill. Like Minty said i could use a boolean.

Below is a similar class. Excel Only. It uses Application.EnableEvents which can be regarded as an external boolean.
Works as intended. Only the first call controls the action.
Code:
Option Explicit
'
' clsEvents (Excel Only)
'
' This class controls whether or not events are triggered.
' You can disable events and enable events after the code.
' Enabled when the class is terminated.
' Only when the property is true, the toggle functionality is active.
' When the property is false, the toggle is handled somewhere else.
'
' Even when this class is nested the toggle works only once.
'
'Typical usage:
'
'Sub DoSomething()
'
'    Dim cEvents As New clsEvents
'
'    cEvents.Disable
''
''Lots of code here
''
'    cEvents.Enable
'
'End Sub

Private mblnIsEnabled As Boolean

Private Sub Class_Initialize()
    mblnIsEnabled = Application.EnableEvents
End Sub

Private Sub Class_Terminate()
    Enable
End Sub

Public Sub Enable()
    If mblnIsEnabled Then
    'Setting was enabled originally so reenabling it is okay
        With Application
            .Calculation = xlCalculationAutomatic
            .ScreenUpdating = True
            .EnableEvents = True
        End With
    End If
End Sub

Public Sub Disable()
    If mblnIsEnabled Then
    'Setting was enabled originally so disabling it is okay
        With Application
            .Calculation = xlCalculationManual
            .ScreenUpdating = False
            .EnableEvents = False
        End With
    End If
End Sub
 

MajP

You've got your good things, and you've got mine.
Local time
Today, 00:37
Joined
May 21, 2018
Messages
8,463
@MajP Yes i could use a collection, but that would feel like a lot of overkill. Like Minty said i could use a boolean.
As I said, I do not fully grasp what you are attempting.
However I strongly recommend that if you are managing multiple instances of custom objects that you create a custom collection to manage them. This concept is incredibly useful. Like access and Excel many objects have the associated collection with them where you create the object through the collection interface.
controls, fields, tabledefs, worksheets, forms,
In these cases you often create the objects through the gui
tempvars, properties, etc you may create mainly through code.

This is especially useful if some action takes place when objects are added or removed especially the first and last.
 

Users who are viewing this thread

Top Bottom