如何在Excel的VBA中动态创建控件或如何使用Application.OnTime()?

时间:2016-06-22 19:25:15

标签: vba excel-vba events dynamic user-controls

我正在我的工作中使用Excel中的一个非常大的VBA项目。我们只有一行功能的1500行代码,还有十几个要添加的功能。因此,我一直在试图破坏所有内容,以便我可以在不同的地方保留每个功能的代码。 OOP糟透了...问题是这些控件必须触发事件。当然,动态创建控件时,某些事件(如TextBox_AfterUpdate事件)不可用。由于所发生的一切,这有点令人费解,所以我会尽我所能打破它:

我有一个类模块,表示多页控件的选项卡。当用户单击选项卡时,Userform会调用此类模块,并且我会动态创建控件。这样我就可以将代码保存在该类模块中。我有一个我认为是" AfterUpdate" sub并放置我需要在那里运行的代码。现在的问题是在适当的时候调用该子。

所以我做的是设置一个Timer of sort来检查" ActiveControl"是说文本框。如果不是,我们可以假设焦点已经离开,我们可以提出这个事件。以下是我使用的代码:

标签创建的缩写版本......

Private WithEvents cmbMarketplace As MSForms.ComboBox

Public Sub LoadTab(ByVal oPageTab As Object)
    If TabLoaded Then Exit Sub

    Set PageTab = oPageTab

    Dim tmp As Object

    Set tmp = PageTab.Add("Forms.Label.1")
    tmp.Top = 6: tmp.Left = 6: tmp.Width = 48
    tmp.Caption = "Marketplace:"

    Set cmbMarketplace = PageTab.Add("Forms.ComboBox.1", "cmbMarketplace")

    ' LOAD OTHER CONTROLS '

    TabLoaded = True
    Start_Timer
End Sub

然后Start_Timer:

Public Sub Start_Timer()
    TimerActive = True
    Application.OnTime Now() + TimeValue("00:00:01"), "Timer"
End Sub

要解雇的潜艇:

Public Sub Timer()
    If TimerActive Then
        ' DO SOME RANDOM THINGS '
        Application.OnTime Now() + TimeValue("00:00:01"), "Timer"
    End If
End Sub

这似乎是解决我面临的问题的合理方法吗?我愿意接受建议......

这是第一个问题。这似乎需要做很多工作才能完成。 (我正在努力获得视觉工作室,但我不知道这是否会发生)

以上代码可以使用,但是"定时器" sub根本不会被提升。如果我只是运行代码,我没有错误。一切都在创造,一切都按照我的希望运作。但是,如果我单步执行代码,我最终会收到以下错误:

Cannot run the macro "...xlsm!Timer".  The macro may not be available in this workbook or all macros may be disabled.

显然,这些建议都没有效果。宏已启用且子处于相同的darn类模块中。我试着公开,同样的问题。试过" ClassModule1!计时器"无济于事。在我的智慧结束时,我试图解决这个问题。想让人们在Userform中写下所有这些或只是放弃。

有人对如何有效分解大块代码有任何建议吗?并且是否有人知道为什么这个潜艇不能运行并且看起来无法找到?

我理解这是一个令人困惑的情况,所以如果您需要更多信息或代码示例或想知道为什么我按照我的方式设置了某些内容,请告诉我。

谢谢!

1 个答案:

答案 0 :(得分:4)

  

显然这些建议都没有效果。宏已启用且子项位于相同的类模块

问题在于:不能出现在类模块中。该消息完全正确:VBA无法看到Timer程序,因为它无法访问。

类模块是对象的蓝图,VBA(或任何OOP语言)无法对类模块执行任何操作,没有实例

您的计时器回调需要是标准模块中的Public Sub,以便可以直接调用作为宏。类模块的公共过程是方法,而不是

根据' DO SOME RANDOM THINGS '实际代表的含义,这可能需要也可能不需要重组。

1500衬里意大利面条代码可用任何语言BTW编写。