在我的数据库中,有一个表格可以显示通过缩写过滤的记录,您可以在组合框中选择缩写。现在在某些情况下,我想打开另一个具有与以前显示相同记录的表单,但是这次需要有两个额外的列,并且记录(特别是两个新列)必须是可编辑的。到目前为止,我的方法是这样的:我从以前的表单中获取数据,将其放入新的Recordset中并添加两列。看起来如下:
Dim cpRS As New ADODB.Recordset, RS As DAO.Recordset, cb As checkBox, addr As String
'Creating copy of previously displayed result table
Set cpRS = New ADODB.Recordset
With cpRS
'all the fields needed. I shortened this because it's too long and has no important information
.Fields.Append "some_value", adInteger
.Fields.Append "some_value", adInteger
.Fields.Append "some_value", adSmallInt, , adFldIsNullable
'new Fields for temporary purposes
.Fields.Append "first_new_field_checkbox", adBoolean
.Fields.Append "second_new_field_textbox", adVarChar, 50
.CursorLocation = adUseClient
.Open , , adOpenKeyset, adLockPessimistic, 8
End With
'get result set of previous window by applying filter to the same query used before
Dim argv() As String
Dim argRest As String
Dim qdef As DAO.QueryDef
Dim restrictedQuery As String
'When opening this form I hand over OpenArgs which i restore here
'took the code out but "argv" and "argRest" will be used later
'this is the query that is used in the previous form. i need an extra where clause though so i had to rewrite it.
restrictedQuery = "some very long SQL statement I feel I don't need to put here because it doesn't contribute to the problem." & _
"If I'm incorrect, please let me know and I will rewrite it to protect the data in it"
Set qdef = CurrentDb.CreateQueryDef("")
qdef.SQL = restrictedQuery
Set RS = qdef.OpenRecordset
Set RS = CurrentDb.OpenRecordset(restrictedQuery, dbOpenSnapshot)
RS.MoveLast
RS.MoveFirst
If RS.RecordCount = 0 Then
MsgBox "some error text", vbOKOnly, "error title"
DoCmd.Close acForm, Me.Name
Exit Sub
End If
'populate new recordset with data from table in previous form
Do Until RS.EOF
'putting the data from the "old" recordset into the new one, shortened again, you get the idea
cpRS.AddNew
cpRS.Fields("some_value") = RS("some_value")
cpRS.Fields("some_value2") = RS("some_value2")
cpRS.Fields("first_new_field_checkbox") = False
cpRS.Fields("second_new_field_textbox") = ""
cpRS.Update
RS.MoveNext
Loop
Set Me.Recordset = cpRS
RS.Close
Set RS = Nothing
'cpRS.Close - I removed this
Set cpRS = Nothing
'error here:
Me.RecordSource = cpRS
此问题是表单中的记录将为空。 (并非完全为空。确切地说,它在一行中的每个单元格中都显示#Name?
。)
我不太确定自己在做什么错。调试时,一切似乎都可以正常工作,我可以看到记录集中充满了以前表单中的数据。所以我的猜测是,我只是未能正确分配新的Recordset作为表单的来源。发生错误分配的地方可能是Set Me.Recordset = cpRS
行,但是如果那是(唯一的)问题,那我就不知道如何解决。
该问题的第二部分已移至another thread,以使结构更清晰。
答案 0 :(得分:1)
混合使用值和引用(存储在变量中)会导致您意外关闭Forms-Recordset。
Set cpRS = New ADODB.Recordset
创建一个记录集对象实例,并将实例的引用存储在变量cpRS
中。
Set Me.RecordSet = cpRS
将引用从cpRS
复制到Forms-RecordSet,这两个索引都指向Recordset-Object的相同实例。它不会创建对象的副本(例如ByRef
对面的功能参数中的ByVal
)!
现在cpRS.Close
关闭记录集,但这与Forms-Recordset相同,由于Forms-Recordset已关闭,因此它导致了一个空表格!
只需跳过cpRS.close
(您可以使用cpRS = Nothing
销毁变量,因为这只会销毁存储在cpRS
中的实例的引用,但是只有在没有引用的情况下实例才会被销毁指向它,但Me.Recordset
仍包含引用!)以填充您的表单(如果其余代码正确(我尚未测试!)。)
示例:
Private Sub CloseCopyOfRecordsetReference()
Dim rs1 As DAO.Recordset, rs2 As DAO.Recordset, rs3 As DAO.Recordset
With CurrentDb
Set rs1 = .OpenRecordset("SELECT * FROM MSysObjects")
Set rs2 = rs1 'copy Reference
Set rs3 = rs1 '2. copy Reference
Set rs1 = Nothing 'this does not affect rs2,rs3
Debug.Print "rs3.RecordCount: " & rs3.RecordCount
rs2.Close ' this closes rs3 too!
Debug.Print "rs3.RecordCount: " & rs3.RecordCount 'Error 3420 here as Recordset is closed
End With
End Sub