Ms access 访问VBA QueryDef.Execute()错误3420

Ms access 访问VBA QueryDef.Execute()错误3420,ms-access,vba,Ms 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.CreateQu

这里有一个非常简单的代码片段,它带来了一个非常恼人的问题。这是一个较大的子例程的一部分,但此处应找到唯一相关的信息

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 snapshot”保存在一个变量中,然后从那里创建QueryDef,以确保它不会被处理。其他一些细节:

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

我搜索了Stackoverflow和各种帮助论坛,试图找到解决这个看似简单的问题的方法,在任何类似的情况下,解决方法都是“不要直接调用CurrentDb,而是将其存储在变量中”。但我已经做到了,问题依然存在。如果您能深入了解这一点,我们将不胜感激。

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

设置qdfNewHospital=db.CreateQueryDef(“”)
或者,如果你愿意,我想你可以分两步做

设置qdfNewHospital=db.CreateQueryDef
qdfnewwhospital.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

不要用刀!改用ADO。MS Access的哪个版本?@MaciejLos re:“不要使用DAO!改用ADO。”-错误。绝对错误。@MaciejLos DAO仍然是在Access本身中与VBA项目中的Access数据库对象交互的首选方法。这就是为什么一个新的Access VBA项目已经定义了DAO引用。(几年前,微软曾试图迫使Access开发者采用ADO,但这一努力失败了,微软又重新将DAO作为默认参考。)@MaciejLos re:“DAO真的很旧。”-ACE DAO已经更新,以比OLEDB或ODBC更全面地处理新的Access功能。例如,从Access数据库中的
附件
字段插入和提取文档的唯一可靠方法是通过ACE DAO
字段2
对象。此外,从MaciejLos链接的页面,虽然ADO本来是要取代DAO的,但微软后来改变了这一立场,使DAO成为受欢迎的数据访问库。此外,微软还祝福ADO.NET,它是一个完全不同的数据访问库,除了三个字母之外,与ADO几乎没有什么共同之处。因此,ADO不太可能得到任何积极的开发。“因此,任何人都可以自由地拒绝DAO,理由是它“非常旧”,但Microsoft没有拒绝它。如果数据库中已经存在同名查询,该怎么办?您应该删除现有查询,然后再创建它。@MaciejLos Temporary QueryDef objects(名称为空字符串)未保存在QueryDefs集合中。@现在,答案已完成;)顺便说一句:我知道;)对于我的select查询,setting.name=“”在传递查询中抛出“无效的连接字符串”“.我已经把密码放进了。。。End@user1175126请包括您的问题的相关详细信息,包括您尝试使用的代码。