避免。使用ActiveX窗体控件激活

时间:2015-12-09 22:29:39

标签: excel-vba vba excel

我正在更新在许多电子表格中使用的宏,而且速度相当慢。在寻求加快速度的同时,我注意到它一度经历了这个循环:

For each wsLoop in ThisWorkbook.Worksheets
        wsLoop.Activate
        With ActiveSheet.Status_Text
            If bStatus = True Then
                .ForeColor = &HC000&
                .Caption = "ONLINE"
            Else
                .ForeColor = &HFF&
                .Caption = "OFFLINE"
            End If
        End With
Next wsLoop

其中wsLoop是工作表,bStatus是布尔值,Status_Text是每个工作表上ActiveX标签表单控件的名称。 我知道使用.Activate是不好的做法,可以减慢速度,所以我删除了wsLoop.Activate并将下一行更改为With wsLoop.Status_Text,但现在我收到“找不到方法或数据成员”错误消息。 这样做的正确方法是什么?

1 个答案:

答案 0 :(得分:2)

有趣的问题似乎与Excel VBA的一些记录不清的功能有关。似乎表达式ActiveSheet.Status_Text可能作为控件的名称运行,点作为命名空间限定符,但在wsLoop.Status_Text VBA中将点解释为方法/属性访问运算符,并正确地给出错误消息,表明不存在此类方法或属性。为了重现这个问题,我在每张纸上创建了一个名为Status_Text的标签,然后运行

Sub test1()
    Dim ws As Worksheet
    For Each ws In Worksheets
        Debug.Print ws.Status_Text.Caption 'fails
    Next ws
End Sub

它会因您显示的错误而崩溃。一种解决方法(尽管为什么它的工作原理是神秘的)是将循环索引从Worksheet更改为Variant

Sub test2()
    Dim ws As Variant
    For Each ws In Worksheets
        Debug.Print ws.Status_Text.Caption 'succeeds
    Next ws
End Sub

关于最后一个示例的奇怪之处在于,如果您在for-each循环中添加行Debug.Print TypeName(ws),则会打印Worksheet,因此如果ws.Status_Text是变体ws,则ws有效它包含一个工作表,但如果ws实际上是一个工作表则不会。从某种意义上说,这个谜团已经加深了,但在另一种意义上,当您在调试器中单步执行此子程序时,会查看本地窗口。循环中Variant/Object/Sheet1的类型被描述为For-Next(在第一次循环中)。特定表格似乎是变量当前子类型的一部分。

另一种解决方法是使用For-Each循环而不是Sub test3() Dim i As Long For i = 1 To Worksheets.Count Debug.Print Worksheets(i).Status_Text.Caption 'succeeds Next i End Sub

{{1}}

您可以使用这些方法中的任何一种来获取对标签的引用,而无需激活工作表。