Я знаю, что вы выяснили проблему, но вы, похоже, не поняли, почему она работает таким образом, и не нашли лучший подход для решения вашей проблемы.
Во всех версиях Access есть несколько коллекций, которые вы используете постоянно:
- TableDefs
- QueryDefs
- Forms
- Отчеты
и другие, которые используются не так часто:
Первые две коллекции доступны только как члены базы данных, поэтому вы можете использовать коллекцию TableDefs или QueryDefs только через что-то вроде этого:
CurrentDB.TableDefs.Count
Это потому, что TableDefs и QueryDefs являются чисто объектами Jet, а не объектами Access.
Другие коллекции являются коллекциями объектов Access, и они включают только объекты OPEN, как вы можете увидеть, если вы сделаете это:
?Forms.Count
... в ближайшем окне вы получаете 0, если формы не открыты, независимо от того, сколько форм на самом деле имеется в вашей базе данных.
До Access 2000 вам приходилось использовать контейнер Documents, чтобы попасть в список сохраненных объектов Access, которые не были загружены. Это было довольно запутанно, и к различным типам объектов приходилось подходить по-разному. Для модулей вот код:
Dim db As DAO.Database
Dim cnt As Container
Dim doc As Document
Set db = CurrentDb
Set cnt = db.Containers!Modules
For Each doc In cnt.Documents
Debug.Print doc.Name
Next doc
Set doc = Nothing
Set cnt = Nothing
Set db = Nothing
И вам также нужно было знать, что макросы хранятся в контейнере под названием «Сценарии». Довольно некрасиво.
В Access 2000 из-за изменения способа хранения проекта Access (как одно поле BLOB в одной записи в системной таблице вместо хранения в нескольких записях, по одной на объект), CurrentProject. Все **** коллекции были представлены. Это были:
- CurrentProject.AllDataAccessPages
- CurrentProject.AllForms
- CurrentProject.AllMacros
- CurrentProject.AllModules
- CurrentProject.AllReports
Для ваших целей лучше всего выбрать коллекцию AllModules вместо коллекции Modules, потому что таким образом вам не нужно беспокоиться о том, открыты модули или нет. Конечно, подход Контейнеры / Документы работает, но AllModules требует значительно меньше кода.
EDIT:
Код для использования AllModules:
Dim i As Integer
For i = 0 To CurrentProject.AllModules.Count - 1
Debug.Print CurrentProject.AllModules(i).name
Next i
OR
Dim obj As Object
For Each obj In CurrentProject.AllModules
Debug.Print obj.name
Next obj
Set obj = Nothing
Я всегда предпочитаю использовать строго типизированные объекты для своих циклов FOR, но здесь работает только универсальная переменная объекта, поэтому я, вероятно, использовал бы счетчик, поскольку он избавляет от необходимости очищать последний неявный указатель объекта в конце.
Кроме того, имейте в виду, что коллекция модулей (то есть открытые модули) включает в себя модули формы, а также автономные и классовые модули, тогда как AllModules ограничен автономными и классовыми модулями.