VBA专用对象以相同形式超出作用域
我试图通过编写一个简单的游戏来学习VBA,但我遇到了对象范围方面的问题。当主窗体打开时,我希望初始化gameSession类的新实例。然后,当用户单击按钮时,我想使用该实例。但是,即使我的对象是在表单顶部声明的,但它似乎不包括在表单过程的范围内。如何让每个过程识别对象的同一实例VBA专用对象以相同形式超出作用域,vba,excel,scope,Vba,Excel,Scope,我试图通过编写一个简单的游戏来学习VBA,但我遇到了对象范围方面的问题。当主窗体打开时,我希望初始化gameSession类的新实例。然后,当用户单击按钮时,我想使用该实例。但是,即使我的对象是在表单顶部声明的,但它似乎不包括在表单过程的范围内。如何让每个过程识别对象的同一实例 Option Explicit Private gameSession As clsGame Private Sub btnWalk_Click() Call frmZombieRun.gameSession.
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
如果我观察变量,我会发现gameSession的每个实例都有不同的上下文(frmZombieRun、frmZombieRun.btnWalk_Click和frmZombieRun.UserForm_Initialize),因此当我到达btnWalk例程时,它们就脱离了上下文
我得到一个编译错误:找不到方法或数据成员。,因为它不在范围内
gameSession
字段是Private
,这意味着它只能被表单的这个实例访问
如果将其公开
,则在更改表单显示方式之前,您的代码将编译并可能工作,如下所示:
frmZombieRun.Show ' off the default instance
为此:
With New frmZombieRun
.Show ' not off the default instance
End With
在表单的代码隐藏中引用默认实例迟早会导致问题。阅读更多关于它的信息(免责声明:我写了那篇文章)
改用Me
引用当前实例:
但这破坏了封装,该字段可能应该是Private
,就像您拥有的那样,即不能从表单的公共接口访问。因此,删除限定符并直接访问您的私有字段:
[Call] gameSession.Walk
您还需要对初始化处理程序执行相同的操作:
Private Sub UserForm_Initialize()
Set gameSession = New clsGame
End Sub
考虑删除
frm
和cls
伪匈牙利前缀,它们不会给你买任何东西。删除限定符。您正试图通过类的公共接口访问私有字段,您应该使用Me
作为限定符,而不是表单的默认实例来访问私有字段-请丢掉这个习惯。clsGame
是否没有Walk
公共方法?当出现编译错误时,哪些代码会突出显示?FWIW编译错误和“当我监视变量时”不能在同一句话中:如果代码可以调试,那么它就会编译。如果它不编译,就无法调试。另外,你对上下文/范围所做的所有假设都是错误的,并且会分散对实际问题的注意力。这对我来说是一个愚蠢的疏忽,walk方法是私有的。谢谢你的帮助!(并指出我在如何调用我的表单方面的问题)。作为记录,像你那样编辑问题会使我的答案看起来像是在编代码……将其更改为public和/或删除限定符/使用我并没有明显的区别。我仍然收到上下文错误。@JackyD我假设代码在frmZombieRun
的代码后面。它是?“断章取义”错误到底是什么?这个答案涵盖了您提出的问题以及您提供的信息。如果缺少某些内容,请编辑您的问题以包含它。很抱歉,我指的是编译错误:找不到方法或数据成员。是的,这是frmZombieRun背后的代码。这就是问题所在。走路的方法是私人的,我完全忽略了。
Private Sub UserForm_Initialize()
Set gameSession = New clsGame
End Sub