Access 2003中的以下例程生成错误7961 - 我的数据库'找不到该模块.但它只在某些模块上实现.哪些模块失败是一致的.
怎么了?
Private Sub DoReplace()
Dim obj As AccessObject
For Each obj In CurrentProject.AllModules
Debug.Print ModuleType(obj.Name) & " " & obj.Name
Next obj
End Sub
Public Function ModuleType(ByVal ModuleName As String) As Variant
On Error GoTo errHandler
Dim mdl As Module
Set mdl = Modules(ModuleName)
ModuleType = mdl.Type
ModuleType = Switch(ModuleType = 0, "std ", ModuleType = 1, "class ")
Set mdl = Nothing
errExit: Exit Function
errHandler:
ModuleType = "Err " & Err.Number '7961
Resume errExit
End Function
Run Code Online (Sandbox Code Playgroud)
调试输出:
Err 7961 vba_28_Part_Asterisk class cls_22_mas90_Item2 Err 7961 vba_44_Part_WhereUsed2 Err 7961 cls_22_JobOps_BOM_WhereUsed_method2 Err 7961 vba_26_Part_misc std vba_44_Part_MRP std vba_99_TurnOffSubDataSheets Err 7961 vba_99_MasteringArraysByScott Err 7961 vba_44_Part_WhereUsed Err 7961 cls_22_JobOps_BOM_WhereUsed Err 7961 cls_22_mas90_Item class cls_22_mas90_Order class cls_23_HOMER_Item class cls_44_mrp_record
我知道你已经弄明白了这个问题,但是你似乎并没有理解为什么它会以这种方式运作,也没有找到解决问题的最佳方法.
在所有版本的Access中,您始终使用多个集合:
和其他不经常使用的:
前两个集合只能作为数据库的成员访问,因此您只能通过以下方式使用TableDefs或QueryDefs集合:
CurrentDB.TableDefs.Count
Run Code Online (Sandbox Code Playgroud)
这是因为TableDefs和QueryDefs是纯Jet对象,而不是Access对象.
其他集合是Access对象的集合,它们仅包含OPEN对象,如您执行此操作可以看到:
?Forms.Count
Run Code Online (Sandbox Code Playgroud)
...在即时窗口中,如果没有打开表单,则会得到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
Run Code Online (Sandbox Code Playgroud)
而且您还必须知道宏存储在一个名为"Scripts"的容器中.蛮丑的.
在Access 2000中,由于对存储Access项目的方式进行了更改(作为系统表中单个记录中的单个BLOB字段,而不是存储在多个记录中,每个对象一个),CurrentProject.All****收集介绍.这些曾经是:
出于您的目的,最好的选择显然是AllModules集合而不是Modules集合,因为这样您就不必担心模块是否打开.当然,容器/文档方法可行,但AllModules需要显着减少代码.
编辑:
使用AllModules的代码是:
Dim i As Integer
For i = 0 To CurrentProject.AllModules.Count - 1
Debug.Print CurrentProject.AllModules(i).name
Next i
Run Code Online (Sandbox Code Playgroud)
要么:
Dim obj As Object
For Each obj In CurrentProject.AllModules
Debug.Print obj.name
Next obj
Set obj = Nothing
Run Code Online (Sandbox Code Playgroud)
我总是喜欢在我的FOR循环中使用强类型对象,但只有一个通用对象变量在这里工作,所以我可能会使用计数器,因为它节省了必须清理最后的最后一个隐式对象指针.
另外,请记住,Modules集合(即开放模块)包括表单模块以及独立模块和类模块,而AllModules仅限于独立模块和类模块.