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