我已经看到很多帖子试图描述这个错误,但是他们没有正确地描述该问题以便重现...或者未按照我使用通用技术体验该错误的方式来设置场景
将表单的记录集设置为虚拟记录集,然后由DAO recordsetclone语句引用该错误时,会发生该错误。而不是通过克隆将记录集设置为表单的记录集,而是显示“选择数据源”对话框。
我们最常用的方法是在详细信息表单中添加复选框控件,以便用户选择一个或多个记录以进行进一步处理。我已经在许多应用程序中多次使用了此技术,但现在失败了。
注意:我已经确认此代码在Access 2010中可以正常工作。
我正在使用32位Office安装的Windows 10 Pro
要进行设置并重现该错误,请执行以下操作:
创建一个新的ACCDB数据库 将以下引用添加到默认引用: Microsoft ActiveX数据对象6.1库 Microsoft ADO Ext。 2.8用于DDL和安全性
创建测试表: TestId,自动编号,PK TestText,短文本
在表上追加大约10行。
使用3个控件创建一个未绑定的表单: 复选框,名称:选中,控件来源:选中 文本框,名称:TestId,控件源:TestId 文本框,名称:TestText,控件源:TextText
在表单的标题中添加一个命令按钮:名称:cmdTest,标题:Test 设置表单默认视图:连续
在Form_Open调用中,子SetRecordsource创建了一个记录集,并添加了“ Selected”列供用户检查所需记录。
命令按钮cmdTest将尝试引用表单的记录源。在尝试引用表单的记录时,会发生错误。代替参考,弹出“选择数据源”对话框。
完整表格的VBA代码:
Option Compare Database
Option Explicit
Private Sub cmdTest_Click()
On Error GoTo errHandler
Dim rs As DAO.Recordset
Set rs = Me.RecordsetClone
' Using an ADODB recordset works but is an ugly solution
' To test comment out the Dim DAO and Set rs statements above and uncomment the next 2 lines.
' Dim rs As ADODB.Recordset
' Set rs = Me.Recordset
rs.MoveFirst
With rs
Do While Not .EOF
Debug.Print .Fields("Selected"), .Fields("TestId"), .Fields("TestText")
.MoveNext
Loop
End With
Set rs = Nothing
ExitSub:
Exit Sub
errHandler:
MsgBox "Error in " & Me.Name & ".SetRecordsource " & Err.Number & " - " & Err.Description
Resume ExitSub
End Sub
Private Sub SetRecordsource()
Dim rs As ADODB.Recordset 'the virtual recordset to hold the source data plus the boolean Selected field
Dim rsSource As DAO.Recordset 'dim the source recordset
Set rs = New ADODB.Recordset
With rs
.Fields.Append "Selected", adboolean
.Fields.Append "TestId", adInteger, , adFldKeyColumn
.Fields.Append "TestText", adVarChar, 80
.CursorLocation = adUseClient
.LockType = adLockOptimistic
.CursorType = adOpenKeyset
.Open
Set rsSource = CurrentDb.OpenRecordset("Select TestId, TestText from Test", dbOpenDynaset)
rsSource.MoveFirst
Do Until rsSource.EOF
.AddNew
.Fields("Selected") = 0 'set the checkboxes to unchecked
.Fields("TestId") = rsSource.Fields(0)
.Fields("TestText") = rsSource.Fields(1)
.Update
rsSource.MoveNext
Loop
End With
Set Me.Recordset = rs 'Set the form's recordset = to our virtual recordset
Set rsSource = Nothing
Set rs = Nothing
ExitSub:
Exit Sub
err_handler:
MsgBox "Error in " & Me.Name & ".SetRecordsource " & Err.Number & " - " & Err.Description
Resume ExitSub
End Sub 'SetRecordsource
打开表单,然后单击“测试”命令按钮以重现错误。
提出的一种解决方案是使用ADODB记录集并将其设置为Me.Recordset而不是Me.Recordsetclone。尽管这确实可行,但是这是一个丑陋的解决方案,因为您现在正在处理表单的记录源,并且在遍历记录以查找其中Selected = True的行在表单上移动当前记录时。不仅当前记录指针会移动,而且如果可以显示的行数更多,则用户会看到表单的记录滚动。
任何帮助,确认或建议将不胜感激。
谢谢!
答案 0 :(得分:0)
您的代码无法正常工作,因为您尝试将ADODB.Recordset(Form.Recordset
中的一个)分配给DAO.Recordset,即声明的那样。
如果Recordset-Type可以变化,则可以使rs as Object
变暗,然后它会得到Form.Recordset
的类型(通过Form Property RecordsetClone,这也令人惊讶地适用于ADODB:Recordsets)。您可以通过以下方式查询类型:
If TypeOf Me.RecordSet Is ADODB.Recordset Then
'ADODB
Else
'DAO
End If
如果您需要未绑定的CheckBox
,则可以使用SelectRecordsV2中的clsCCRecordSelect
-Class。
clsCCRecordSelect
被我使用了多年,我不想没有它!
答案 1 :(得分:0)
在另一个论坛上,解决此问题的方法是使用ADODB记录集,然后通过Recordset.Clone将表单克隆到它。在上面的代码中,它引用了一个“丑陋”的解决方案:
'使用ADODB记录集是可行的,但这是一个丑陋的解决方案 '要测试注释掉上面的Dim DAO和Set rs语句,并取消注释接下来的两行。
'Dim rs as ADODB.Recordset
'设置rs = Me.Recordset
设置rs = Me.Recordset将在表格上运行(不需要)。
但是使用ADODB记录集,然后 设置rs = Me.Recordset.Clone可以工作,无法在表单上操作,并且不会弹出“数据源”对话框。
2016年发生了一些变化,但这确实可行,并且可能会帮助其他人。 您可能还需要阅读:Create In-Memory ADO Recordsets at Database Journal