我有一个表格在表格A
上执行搜索查询,该表格会在同一表格的子表单上输出结果。
我想要做的是添加一个按钮,将子窗体上的选定记录移动到表B
中,删除表A
中的记录(我假设原则上类似于我想在下面做什么),然后重新查询搜索,我认为这可以通过me.requery
这样简单的事情来完成。
strID = Me.Form1_subform.Form.ID.Value
strSQL = "INSERT INTO B ([a], [b], [c]) "
strSQL = strSQL + "SELECT [a], [b], [c] "
strSQL = strSQL + "From A"
strSQL = strSQL + "WHERE [ID] = " & strID
DoCmd.RunSQL strSQL
以上是我尝试将A
的记录插入B
。现在,上面的代码只对许多选定记录中的第一个执行操作(它按预期工作,但我似乎无法找到如何让Access识别正在选择其他记录)。有没有一种简单的方法在Access中执行上述代码的循环?我目前只能使用最顶层的选定记录访问Access,这不是我真正可以使用的东西。
此外,上面的代码在移入表B
时会保留主键值(ID)。有办法防止这种情况吗?
答案 0 :(得分:0)
如果表A
和B
具有相同的记录过滤列,则可以使用WHERE
子句来搜索A
表中的行。但在某些情况下,可能很难,特别是如果用户能够手动过滤子表单。在这种情况下,您可以像这样创建WHERE子句:
WHERE [ID] in (1,3,5,7....)
如果子窗体中有很多行,则此SQL可能会超出SQL字符串长度限制,因此将移动分成几个块是合理的:
Dim lngCounter As Long
Dim rst As DAO.Recordset
Dim strWhere As String
Dim strSQL As String
Const lngChunkSize = 100
Set rst = Me.RecordsetClone
If rst.RecordCount > 0 Then
rst.MoveFirst
Do Until rst.EOF
lngCounter = lngCounter + 1
'Collect keys
strWhere = strWhere & rst!ID & ","
rst.MoveNext
If lngCounter Mod lngChunkSize = 0 Or rst.EOF Then
'chunk is full or end operations, move rows
strWhere = Left(strWhere, Len(strWhere) - 1) 'remove last coma
strSQL = "INSERT INTO B ([a], [b], [c]) " & _
"SELECT [a], [b], [c] From A where ID in (" & strWhere & ")"
'use ADO, it supports longer strings
CurrentProject.Connection.Execute strSQL
strSQL = "DELETE * From A where ID in (" & strWhere & ")"
CurrentProject.Connection.Execute strSQL
strWhere = ""
End If
Loop
End If
这种方式比通过记录集逐个循环的速度快得多。速度类似于使用" normal" WHERE子句包含所有条件。
在我的情况下,块大小= 100是最佳性能,您可以尝试不同的块大小,并找到最适合您的表的大小。