在VBA中,在Access 2003中,我需要
TableA
)和当前日期AID
中创建记录
TableC
中创建多条记录,将AID
中TableA
的新记录与来自BID
的多个外键(TableB
)相关联, QueryB
。 因此,如果QueryB
返回来自TableB
的{{1}} s 2,5,7,8的记录,那么我想在BID
中使用{{{ 1}}和TableA
然后让AID = 1
显示出来:
Date = 8/23/13
我该怎么做?完成第一件事情很顺利,直到我记得我需要第二场。现在我的代码是:
TableC
其中AID BID
---------
1 2
1 5
1 7
1 8
是打开表单中的控件(我不能将名称更改为有用的名称,否则它将不再控制表单其余部分显示的记录) 。但是,一旦我添加了Dim SQLstr As String
Dim db As DAO.Database
Set db = CurrentDb
SQLstr = "INSERT INTO TableA (FieldA, Date) "_
& "VALUES (list13.value, Date());"
db.Execute SQLstr
和List13
,我就会收到一条错误消息
参数太少。预计:1
我也不确定如何描述我想要使用新记录(在本例中为FieldA
)作为所有list13.value
记录关联的常量。经过大量的搜索,我想我想使用AID = 1
,但我不确定如何。
编辑:我最终得到以下代码以正确返回AID:
QueryB
我正在浏览here,并建议使用以下代码将INSERT INTO与字段数据和常量混合使用:
@@IDENTITY
所以我留下的是以下问题:
在我的第一个代码中使用“list13.value”有什么问题?
编辑:所以,我修正了:
Dim rs As DAO.Recordset
Dim AIDvar As Integer
Set rs = db.OpenRecordset("select @@identity")
AIDvar = rs(0)
但是当我把它与@@ IDENTITY代码放在一起时,我收到一个溢出错误。我如何绕过那个?
答案 0 :(得分:0)
也许不是实现您想要的最短路径,但它可能是最灵活的,因为您可以轻松修改您的操作(例如添加新字段),而无需过多地重新考虑您的代码:
Public Sub DoWork()
Dim db As DAO.Database
Dim rsA As DAO.Recordset
Dim newAID As Long
Set db = CurrentDb()
' First, add the new record in TableA ang get its ID '
Set rsA = db.OpenRecordset("TableA", dbOpenTable, dbFailOnError)
If Not (rsA Is Nothing) Then
With rsA
.AddNew
!FieldA = list13.Value
!ActionDate = Now
.Update
' Safe way to get the ID '
.Move 0, .LastModified
newAID = !ID
.Close
End With
Set rsA = Nothing
End If
Dim rsB As DAO.Recordset
Dim rsC As DAO.Recordset
' Second, open QueryB as a read-only recordset '
Set rsB = db.OpenRecordset("QueryB", dbOpenSnapshot)
If Not (rsB Is Nothing) Then
' Only proceed if QueryB returned some data '
If rsB.RecordCount > 0 Then
' Open TableC so we can insert the result of QueryB '
Set rsC = db.OpenRecordset("TableC", dbOpenTable, dbFailOnError)
With rsC
Do While Not rsB.EOF
.AddNew
!AID = newAID
!BID = rsB!ID
' whatever other fields from QueryB '
' that you need to insert in TableC '
.Update
Loop
.Close
End With
Set rsC = Nothing
End If
rsB.Close
Set rsB = Nothing
End If
Set db = Nothing
End Sub
您可以使用直接的SQL语句轻松替换所有这些代码,但我想展示如何使用纯记录集安全地执行此类操作。
使用手动SQL命令的较短替代方法如下:
Public Sub DoWork()
Dim sql As String
Dim newAID As Variant
' First, add the new record in TableA ang get its ID '
sql = sql & "INSERT INTO TableA (FieldA, ActionDate) "
sql = sql & "VALUES (" & List13.Value & ", " & CDec(Now()) & ")"
CurrentDb().Execute sql, dbFailOnError
newAID = CurrentDb().Execute("SELECT @@IDENTITY")(0)
' Second, insert QueryB into TableC '
sql = vbNullString
sql = sql & "INSERT INTO TableC (AID, BID) "
sql = sql & "SELECT " & newAID & ", QueryB.ID FROM QueryB"
CurrentDb().Execute sql, dbFailOnError
End Sub
如果您想充分利用本网站,请确保您对自己需要达到的目标有清晰的认识。事实上,你改变主意并需要添加新字段,这看起来你真的不知道你想去哪里。表格和字段的命名约定在同一问题中也不一致 先解决这个问题。目前看起来你正在黑暗中刺伤,希望能够回答你的问题 如果你对问题没有清晰的认识,没有人可以帮助你。
不要将Date
等保留字用于字段名称。这必然会引起混淆,它总会在某个时刻再次困扰你,造成奇怪的错误。
学习使用Recordsets
。它们不是所有问题的答案,但如果您需要插入或执行复杂的查询和更新,它们是必需的。
避免手工构建SQL字符串。尽可能多(除非查询真的很简单),使用参数化查询。永远不要手工构建一个包含用户在文本框中输入的数据的查询:在某个时刻,它将包含将破坏您的查询的字符(如引号'"
,换行符,特殊字符甚至{{3 }})。
SELECT @@IDENTITY
很有用,但在使用它时一定要小心:它必须在插入后直接运行,并且在某些情况下evil database commands你想要它。