如何使用应用程序级事件更新 GUI/UserForm 元素?

How to Update GUI/UserForm elements with Application Level Events?

提问人:vbanoob 提问时间:10/13/2023 最后编辑:vbanoob 更新时间:10/13/2023 访问量:57

问:

问题:

我想在打开工作簿或单击其他工作簿中的单元格时更新 ComboBox/TextBox。 我开始想将一个函数传递给类来执行。因为这似乎是最合理的方式。VBA真的让我感到困惑。

为什么?我正在编写一个带有 GUI 的宏,该宏需要打开一个信息工作簿 (Info-WB) 才能在另一个工作簿 (S-WB) 中汇总选定的工作表范围。我想实时显示 Info-WB 是否打开,然后 GUI 元素应该像使用移液器工具一样对选择 S-WB 中的工作表(和其中的单元格)做出反应。

我尝试过:

我读了这个,这似乎是一个解决方案,但我不太明白:https://stackoverflow.com/questions/53123046/implementing-a-change-event-to-check-for-changes-to-textbox-values-and-enabling

我认为这就是我需要的:https://stackoverflow.com/questions/19860901/update-form-with-events https://bettersolutions.com/vba/events/excel-application-level-events.htm,我得到我需要将事件粘合到类上:

Public WithEvents oProgressFormClassInstance As clsProgressForm
'The WithEvents here implies that whenever the specific object referenced by this variable
'throws an event, it will trigger the event handler for that event in this class (form)

但是,当我使用 IDE 构建菜单时,我如何实际使用带有事件的类,就像 VBA 为我创建的类一样?

我还在这个网站上发现了一个问题,指出我在具有事件处理程序的类中使用 Application.Run。 所以最后,我考虑将 UI 元素和函数名称保存为该类中的变量,并以这种方式将其传递给事件。但是我学习编程的方式(使用 lua)似乎太混淆和笨拙了。

updater 类:

Public WithEvents appevent As Application

'Implements ComboBox '...one can dream

Public funtionName As String
Public uiElement As Variant

Private Sub appevent_WorkbookOpen(ByVal Wb As Workbook)
    Application.Run updateSomeIUStuff
End Sub

Private Sub Class_Initialize()

    Set Me.appevent = Application
End Sub

编辑:将“设置”添加到“Me.appevent = 应用程序”

用户窗体中的代码:

Private Sub UserForm_Initialize()
    
    Dim uUpdater As Variant
    Set uUpdater = New updater

End Sub

Sub updateSomeIUStuff()
    
    MsgBox "If Mommy's Purse Didn't Belong In The Microwave, Why Did It Fit?"
    'ComboBox.doStuff()

End Sub

现在由于某种原因,VBA sais:未定义对象变量或With块变量 并将我指向“Me.appevent = Application”

除了不起作用之外,这对我来说看起来是错误的。为什么 Microsoft 要这样对我?

VBA 事件 用户窗体 Excel-2016

评论

0赞 Storax 10/13/2023
但是,在运行事件处理程序之前,必须将类模块中声明的对象连接到 Application 对象。bettersolutions.com/vba/events/......这就是你必须做的。在类本身的情况下,您无法这样做。initialize
0赞 vbanoob 10/13/2023
我不是在更新程序类的 init 函数中这样做的吗?这也是引发错误的 lince:未定义对象变量或 With-block-variable 的 lince。我只是不明白为什么,因为 Me 是在类中定义的,而 appevent 也在这个类中定义,那么为什么 me.appevent 会给出错误?
0赞 vbanoob 10/13/2023
如果我在用户表单初始化中执行 uUpdater.appevent = Application,它会给出相同的错误
0赞 Storax 10/13/2023
因为对象在那个时候。PS:-(啊,我现在明白了。你忘了NothingSetMe.appevent = Application
1赞 lorenz albert 10/13/2023
在UserForm_Initialize中声明 uUpdater。当 Sub 退出时,该对象将被销毁。您需要将 uUpdater 声明为用户表单的成员。私有 uUpdater 作为变体。

答:

1赞 lorenz albert 10/13/2023 #1

您需要的最小示例。

这是 .我在 UI 中添加了一个 TextBox()。侦听器或 uUpdater 是 UserForm1 的成员/字段。在 UserForm1 的 Initialize 子中,您只需实例化侦听器/uUpdater。UserForm1TextBox1

Private listener As EventListener

Private Sub UserForm_Initialize()
    Set listener = New EventListener
End Sub


Public Sub UpdateSomeStuff()
    MsgBox "Some Info"
End Sub

这是里面的代码。您不需要使用 .您可以简单地调用该函数,如我的示例所示。EventListenerApplication.Run

Public WithEvents appevent As Application


Private Sub appevent_WorkbookOpen(ByVal Wb As Workbook)
    UserForm1.UpdateSomeStuff
End Sub

Private Sub Class_Initialize()
    Set appevent = Application
End Sub

实际上,如果您只想听事件,则不需要单独的课程

在此示例中,UserForm1 侦听应用程序事件。

Private WithEvents app As Application

Private Sub app_WorkbookOpen(ByVal Wb As Workbook)
    UpdateSomeStuff
End Sub

Private Sub UserForm_Initialize()
    Set app = Application
End Sub


Public Sub UpdateSomeStuff()
    MsgBox "Some Info"
End Sub

评论

0赞 vbanoob 10/13/2023
我从未像现在这样高兴地看到拉尔夫的一句话。非常感谢!