通过变量访问子控件

时间:2014-07-02 13:31:38

标签: vba

下面的代码是我正在尝试做的简化版本,包含在一个模块中,Set InputSheet = Sheets("Input") Public Sub Workbook_Open() ThisWorkbook中有Option Explicit Public InputSheet As Worksheet Public Sub Populate() InputSheet.ListBox2.AddItem "Test" 'doesnt work Sheets("Input").ListBox2.AddItem "Test2" 'works End Sub

Populate()

如评论所示,Method or data member not found中的第一行不起作用,第二行正常。我在第一行得到的错误是Dim InputSheet2 As Worksheet Set InputSheet2 = Sheets("Input") InputSheet2.ListBox2.AddItem "Test" 。有人能指出我正确的方向吗?它似乎与我使用全局变量的事实无关,因为如果我这样做:

{{1}}

它有同样的问题。

2 个答案:

答案 0 :(得分:2)

我可以确认它是按照你说的方式发生的。另外,我不知道为什么会这样,但我可以猜到。当您使用Sheets("Input")时,库将以一个通用的Sheet类开始,然后在更具体的Worksheet类中结束。但是对于InputSheet,您已经在Worksheet类中(当您设置变量时,您通过了Sheet,但现在没有)。

所以我的猜测是有一个错误/功能,其中ListBox自动实例化属性只是Sheet类的一部分,而不是Worksheet类的一部分。 ActiveX控件存在于工作表上方的层上,因此存在将工作表连接到ActiveX控件的管道,但它们不像UI中显示的那样严格绑定。

你有几个选择,其中没有一个是你想要的。第一,当然是使用你的第二行。否则你可以使用

Public InputSheet As Object

这将迫使VBA评估对象类型并通过Sheet类。或者你可以这样做。

InputSheet.OLEObjects("ListBox2").Object.AddItem "Test3"

在我看来,最好的方法是更改​​工作表的CodeName并使用它 - 自动实例化属性将使用它。但我意识到你已经简化了这一点,这可能不适合你。

答案 1 :(得分:0)

在第一个示例中,InputSheet尚未初始化并设置为 Nothing 。在您的InputSheet ... AddItem“Test”之前,包括:

Set InputSheet = Sheets("Input")

这也假设您有一张名为“输入”的工作表,而“输入”工作表有一个名为“ListBox2”的列表框

编辑: 不确定为什么Excel VBA以这种方式工作,但看起来你不能以这种方式引用子对象。我能够通过使用InputSheet.OLEObjects使它工作...为了使它更清洁,我将它分配给ListBox对象:

Public InputSheet As Worksheet

Private Sub Workbook_Open()
    Set InputSheet = Sheets("Sheet1")
End Sub

Public Sub Test()
    Dim MyBox As ListBox
    Set ListBox = InputSheet.OLEObjects("ListBox2").Object

    ListBox.AddItem Now()
End Sub

尽管我确实对全局变量感到有点邋..看来当我遇到错误时,InputSheet对象将休息回 Nothing 并且我必须关闭/重新打开工作簿才能重新分配该值。