Почему я не могу получить свойства от участников этой коллекции? - PullRequest
2 голосов
/ 30 апреля 2010

Я добавил некоторые элементы управления формой в коллекцию и могу получить их свойства, когда ссылаюсь на элементы по индексу.

Однако, когда я пытаюсь использовать какие-либо свойства, ссылаясь на членов коллекции, я вижу ' Не удалось установить свойство ControlSource. Член не найден. 'ошибка в окне Locals.

Вот упрощенная версия кода:

'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 был объявлен как элемент управления, но я считаю, что если он объявлен как объект, то код работает.

Это, вероятно, решит мою проблему, но в интересах расширения моих знаний я буду благодарен за любое объяснение этого поведения, особенно в отношении различий в выполнении кода в различных типах модулей.

1 Ответ

4 голосов
/ 30 апреля 2010

Это действительно отличный вопрос. Ваше редактирование в конце поста многое показывает о том, как работает VBA и что здесь происходит. Я не на 100% понимаю, что происходит, но я объясню, что, по-моему, происходит.

A Collection в VBA (и в этом случае VB6; та же самая база кода) не является строго типизированной. Это означает, что все в коллекции технически является «объектом». В мире .NET (начиная с .NET 2.0) можно иметь строго типизированные коллекции, чтобы можно было сказать, что «все в этой коллекции является Control объектом». В VBA это невозможно с Collection.

На первой итерации, где вы ссылаетесь на элемент, проиндексированный в коллекции activeTabs, activeTabs(x + 1) ссылается на object. Когда вы говорите VBA искать .Caption этого объекта, он не знает, что является базовым типом (я думаю), поэтому он должен просто посмотреть, содержит ли базовый тип объекта свойство или метод с именем * 1012. *. Как видите, элементы управления Tab на самом деле содержат свойство с именем Caption.

Во втором случае, когда вы делаете цикл For Each, я думаю, проблема в том, что тип Control, вероятно, не имеет свойства, называемого Caption, хотя различные типы из элементов управления, вероятно, делают. Например, элемент управления с текстовым полем, вероятно, не имеет свойства Caption, тогда как элемент управления с меткой имеет свойство Caption.

У вас есть несколько вариантов исправить ваш второй цикл. 1) Вы можете объявить formTab как элемент управления Tab (я точно не знаю, как он называется). Элемент управления Tab должен иметь свойство Caption. 2) Если каждый элемент управления в activeTabs не является определенно элементом управления Tab (в этом случае вы, вероятно, должны называть его activeControls вместо activeTabs), вы можете проверить внутри цикла, чтобы увидеть, действительно ли formTab вкладка управления. Если это так, используйте его как элемент управления Tab, а затем вызовите .Caption. Пока вы не приведете его в качестве элемента управления Tab, VBA не будет знать, что у него есть свойство Caption, поскольку обычный объект Control не имеет свойства caption.

В конце вы можете избежать использования объектов, как в первом цикле, и позволить среде выполнения выяснить, что делать, но это может привести к очень плохой производительности. В общем, лучше работать с вашими конкретными типами на строго типизированном языке. Это также помогает показать в вашем коде, что вы точно знаете, с чем работаете, вместо того, чтобы оставить на время выполнения решение, с какими свойствами и методами вы можете работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...