模块的VBA错误:'找不到模块'

Sma*_*oli 0 ms-access vba

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

Dav*_*ton 5

我知道你已经弄明白了这个问题,但是你似乎并没有理解为什么它会以这种方式运作,也没有找到解决问题的最佳方法.

在所有版本的Access中,您始终使用多个集合:

  • TableDefs
  • QueryDefs
  • 形式
  • 报告

和其他不经常使用的:

  • 模块

前两个集合只能作为数据库的成员访问,因此您只能通过以下方式使用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****收集介绍.这些曾经是:

  • CurrentProject.AllDataAccessPages
  • CurrentProject.AllForms
  • CurrentProject.AllMacros
  • CurrentProject.AllModules
  • CurrentProject.AllReports

出于您的目的,最好的选择显然是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仅限于独立模块和类模块.