访问 VBA QueryDef.Execute() 错误 3420



这里一个非常简单的代码片段提出了一个非常烦人的问题。这是一个更大的子例程的一部分,但唯一相关的信息应该在这里找到。

Dim db As DAO.Database
Set db = CurrentDb
' If the associated hospital is new, add it first
If newHName = True Then
    Dim qdfNewHospital As DAO.QueryDef
    Set qdfNewHospital = db.CreateQueryDef
    qdfNewHospital.SQL = "INSERT INTO tblHospital (HospitalName)" & _
        " VALUES ('" & hName & "')"
    qdfNewHospital.Execute dbFailOnError
    Dim iAffected As Integer
    iAffected = qdfNewHospital.RecordsAffected
    Debug.Print "Inserting hospital " & hName & " affected " & iAffected & " row(s)"
End If

我在此行收到错误 3420"对象无效或不再设置":

qdfNewHospital.Execute dbFailOnError

这似乎表明我知道 QueryDef 在哪里创建

这样的常见问题:
CurrentDb.CreateQueryDef

由于 CurrentDb 在内部的工作方式而过早处置。这个问题的常见解决方案显然是我在这里所做的,将"CurrentDb 快照"保存在变量中并从那里创建 QueryDef 以确保它不会被处理掉。一些其他细节:

  • 我已经验证了代码中其他地方没有命名冲突
  • 此模块中没有其他任何地方甚至引用 CurrentDb

我已经搜索了Stackoverflow和各种帮助论坛,试图找到这个看似简单的问题的解决方案,而与此类似的任何情况下的解决方案总是"不要直接调用CurrentDb,而是将其存储在变量中"。然而,我已经这样做了,问题仍然存在。对此的任何见解将不胜感激。

收到该错误是因为您创建的QueryDef对象没有 .Name 属性。通常,当我们创建一个临时QueryDef对象时,我们将 .Name 属性作为空字符串参数提供给 CreateQueryDef 方法:

Set qdfNewHospital = db.CreateQueryDef("")

或者,我想如果您愿意,可以分两步完成......

Set qdfNewHospital = db.CreateQueryDef
qdfNewHospital.Name = ""

。但第一种方法更为常见。

当您通过将.Name设置为空字符串来创建临时QueryDef对象时,该对象不会保存在 QueryDefs 集合中,因此您无需担心使用它后会"清理"。

(感谢@MaciejLos建议改进此答案。

使用 DAO,你也可以这样做:

Dim sqltext As String
qdfNewHospital As DAO.QueryDef
'  build the create querydef sql  string
sqltext = "INSERT INTO tblHospital (HospitalName)" & _
        " VALUES ('" & hName & "')" 
'  now create a reusable stored query def
On Error Resume Next  
With CurrentDb               
    'Delete the query if it exists
    .QueryDefs.Delete ("My_Query")
    'Now set up the querydef                                
    Set qdfNewHospital = .CreateQueryDef ("My_Query", sqltext)
    .Close
End With

简而言之,我遇到了同样的问题。

Dim db as DAO.Database
Dim q as DAO.queryDef
...
' This failed
Set q = db.CreateQueryDef(, strSQl)
q.Execute dbFailOnError
'This worked (queryDef needs a name even if its blank)
Set q = db.CreateQueryDef("", strSQl)
q.Execute dbFailOnError

最新更新