Обращение к элементу folders collection

Пытаюсь написать макрос VBA в Excel для вывода имени подпапки по пути основной папки. Не могу понять, почему не получается получить первый элемент folders collection по его индексу. Выдает ошибку invalid procedure call or argument.

Sub test()

Dim folderOS As Object 
Dim folder As Object 
Dim folderName As String 
Dim subFolder As Object


Set folderOS = CreateObject("Scripting.FileSystemObject") 
Set folder = folderOS.GetFolder("C:\Program Files")

MsgBox folder.SubFolders(1).name

End Sub

При этом если использовать перебор For Each, то все прекрасно работает.


Ответы (1 шт):

Автор решения: MarianD
  1. Простой ответ:

    Цикл For Each работает для всех коллекций.

    Но для некоторых коллекций метод .item() с параметром в виде индекса не работает, хотя в документации это не упоминают.

    • Почему не упоминают?
      Возможно потому, что метод .item() всегда работает.

      Но для некоторых коллекций только с параметром в виде прямого задания члена коллекции (напр. .item("Microsoft Office").

      Сверх того этот метод сделали имплицитным для всякой коллекции.

      (Имплицитный значит, что часть .item может выпущена, а использованы только скобки - так как это сделали вы, когда вместо полного SubFolders.item(1) использовали SubFolders(1)).

  1. Более точный ответ:

    Все коллекции являются объектами COM и в этом виде все имплементируют метод .item() в интерфейсе COM, чтобы разные программы / языки программирования могли этот метод использовать. Этот метод .item() — в отличие от метода .item() во VBA — использует в качестве параметра только порядковый номер члена в коллекции.

    Но кроме метода .item() в интерфейсе COM предлагают тоже специальное свойство COM - _NewEnum. Это более сложно, но вы можете представить себе его как код, который каждому члену коллекции определяет его имя, в вашем случае имя папки.

    Метод .item() в языке VBA использует обе, но не для всех коллекции. В некоторых использует только _NewEnum (т.е. имена членов коллекции), но это достаточно для того, чтобы было возможно применить цикл For Each.

    Потому в вашем случае For Each работает (и будет работать для всех коллекций), но .item(1) нет.

→ Ссылка