2010-04-30 23 views
2

我已经将一些表单控件添加到集合中,并且可以在通过索引引用成员时检索它们的属性。为什么我无法从此集合的成员获取属性?

但是,当我尝试通过引用集合的成员来使用任何属性时,我看到'无法设置ControlSource属性。未找到会员。'在本地窗口中出现错误。

下面是代码的简化版本:

'Add controls to collection' 
For x = 0 To UBound(tabs) 
    activeTabs.Add Item:=Form.MultiPage.Pages(Val(tabs(x, 1))), _ 
     key:=Form.MultiPage.Pages(Val(tabs(x, 1))).Caption 
Next x 

'Check name using collection index' 
For x = 0 To UBound(tabs) 
    Debug.Print "Tab name from index: " & activeTabs(x + 1).Caption 
Next x 

'Check name using collection members' 
For Each formTab In activeTabs 
    Debug.Print "Tab name from collection: " & formTab.Caption 
Next formTab 

在即时窗口,结果是:

Tab name from index: Caption1 
Tab name from index: Caption2 
Tab name from collection: 
Tab name from collection: 

为什么一个方法的工作,其他的失败?

这是在一个标准的代码模块,但我有类似的代码在表单模块内工作得很好。这可能与它有什么关系?

编辑补充

formTab被宣布为控制,但我觉得,如果它被声明为一个对象,然后代码工作。

这可能会解决我的问题,但为了进一步提高我的知识水平,我将非常感谢任何有关此行为的解释,特别是关于在不同类型的模块中运行代码的差异。

回答

4

这是一个非常好的问题。您在文章末尾的编辑会揭示很多关于VBA如何工作和发生的事情。我不是100%这是怎么回事,但我会解释我的想法正在发生。

在VBA(和VB6,就此而言;相同的代码库)中的A Collection不是强类型。这意味着集合中的所有内容在技术上都是一个“对象”。在.NET世界中(从.NET 2.0开始),可以强类型化集合,这样就可以说“这个集合中的所有东西都是一个Control对象。”在VBA中,这是不可能的,Collection

在您的第一次迭代中,您指的是activeTabs集合中索引的项目,activeTabs(x + 1)指的是object。当您告诉VBA查找该对象的.Caption时,它不知道底层类型是什么(我认为),因此它只需查看底层对象类型是否包含名为Caption的属性或方法。如您所见,Tab控件实际上包含一个名为Caption的属性。

在你的第二个互为作用,你在哪里做For Each循环,我认为问题是,Control型可能不会有一个名为Caption财产,虽然不同类型的控件可能做到。例如,文本框控件可能没有Caption属性,而标签控件确实有Caption属性。

你有几个选项来修复你的第二个循环。 1)你可以声明formTab是一个Tab控件(我不确定它究竟是什么)。 Tab控件应该有一个Caption属性。2)如果activeTabs中的每个控件都不是特定的Tab控件(在这种情况下,您应该将它称为activeControls而不是activeTabs),那么可以在循环中检查formTab是否实际上是Tab控件。如果是,则将其转换为Tab控件,然后致电.Caption。在将其转换为Tab控件之前,VBA不会知道它具有Caption属性,因为常规Control对象没有标题属性。最后,您可以避免在第一个循环中使用对象,并让运行时找出要执行的操作,但这可能会导致非常糟糕的性能。一般来说,用强类型语言处理特定类型会更好。它还有助于在代码中显示您明确知道正在处理的内容,而不是将其留给运行时决定可以使用哪些属性和方法。

+0

谢谢,这很有道理。我将formTab声明为Page(控件的正确名称,我只是更喜欢将它们称为选项卡),并且您预测它可以正常工作。我也将代码复制到一个表单模块中,无论formTab是否声明为Control,Page或Object,它都可以工作。奇怪的。 – Lunatik 2010-04-30 12:17:26

+0

@Lunatik VB有时会跳过很多圈试图找出你想要做的事情。不幸的是,这并不总是导致良好的代码,并会让你不知道你的代码在做什么。我写了大量的代码,我不知道它在做什么,但VBA允许它工作:-)。 – 2010-04-30 12:21:52

相关问题