JackyD
JackyD

Reputation: 23

VBA Private Object Out Scope in Same Form

I'm trying to learn VBA by writing a simple game but I'm running into issues with the scope of my objects. When the main form is opened I want a new instance of the gameSession class to be initialized. Then, when the user clicks a button, I want to use that instance. But even though my object is declared at the top of the form it appears that it isn't included in the scope of the forms procedures. How do I get each procedure to recognize the same instance of the object?

Option Explicit

Private gameSession As clsGame

Private Sub btnWalk_Click()
   Call frmZombieRun.gameSession.Walk
End Sub

Private Sub UserForm_Initialize()
   Set frmZombieRun.gameSession = New clsGame
End Sub

If I put a watch on the variables I see that each instance of gameSession has a different context (frmZombieRun, frmZombieRun.btnWalk_Click, and frmZombieRun.UserForm_Initialize) and therefore is out of context when I reach the btnWalk routine.

I get a compile error: Method or data member not found.

Upvotes: 2

Views: 198

Answers (1)

Mathieu Guindon
Mathieu Guindon

Reputation: 71217

Because it's not in scope.

The gameSession field is Private, which means it's only accessible to this instance of the form.

If you made it Public, your code would compile and probably work, until you changed how the form is shown, from this:

frmZombieRun.Show ' off the default instance

to this:

With New frmZombieRun
    .Show ' not off the default instance
End With

Referring to the default instance in a form's code-behind will cause problems, sooner or later. Read more about it here (disclaimer: I wrote that article).

Use Me instead, to refer to the current instance:

[Call] Me.gameSession.Walk 'note: Call is redundant/deprecated/obsolete

But that breaks encapsulation, that field should probably be Private like you have it, i.e. not accessible from the form's public interface. So, drop the qualifier and access your private field directly:

[Call] gameSession.Walk

You'll also need to do the same for the initialization handler:

Private Sub UserForm_Initialize()
   Set gameSession = New clsGame
End Sub

Consider dropping the frm and cls pseudo-Hungarian prefixes, they're not buying you anything.

Upvotes: 2

Related Questions