我正在更新在许多电子表格中使用的宏,而且速度相当慢。在寻求加快速度的同时,我注意到它一度经历了这个循环:
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
,但现在我收到“找不到方法或数据成员”错误消息。
这样做的正确方法是什么?
答案 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}}
您可以使用这些方法中的任何一种来获取对标签的引用,而无需激活工作表。