访问VBA QueryDef.Execute()错误3420

时间:2015-01-15 20:13:51

标签: vba ms-access access-vba

这里有一段非常简单的代码,这是一个非常烦人的问题。这是一个较大的子程序的一部分,但应在此处找到唯一的相关信息。

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,存储它在一个变量而不是"。但我已经做到了,问题仍然存在。任何有关这方面的见解将不胜感激。

3 个答案:

答案 0 :(得分:7)

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

Set qdfNewHospital = db.CreateQueryDef("")

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

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

......但第一种方式更常见。

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

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

答案 1 :(得分:2)

使用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

答案 2 :(得分:1)

简而言之,我有同样的问题。

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