Access 2016 - 使用虚拟记录集构建的表单上的RecordsetClone错误打开“选择数据源”对话框

问题描述 投票:0回答:2

我已经看过很多帖子试图描述这个错误,但是他们没有正确地解决这个问题需要重现...或者没有按照我使用常用​​技术经历过bug的方式设置方案。

当表单的记录集设置为虚拟记录集,然后由DAO recordsetclone语句引用时,会发生该错误。而不是将记录集设置为表单的记录集(通过克隆),而是显示“选择数据源”对话框。

我们最常使用此选项将复选框控件添加到详细信息表单,以供用户选择一个或多个记录以供进一步处理。我在许多应用程序中多次使用过这种技术,但现在它失败了。

注意:我已确认此代码在Access 2010中正常运行。

我正在使用Windows 10 Pro和32位Office安装

要设置它并重现错误:

创建新的ACCDB数据库将以下引用添加到默认引用:Microsoft ActiveX Data Objects 6.1 Library Microsoft ADO Ext。 2.8用于DDL和安全

创建一个测试表:TestId,AutoNumber,PK TestText,Short Text

在表中附加大约10行。

使用3个控件创建一个未绑定的表单:复选框,名称:已选中,控件来源:选定的文本框,名称:TestId,控件来源:TestId文本框,名称:TestText,控件来源:TextText

在表单的标题中添加一个命令按钮:名称:cmdTest,标题:测试设置表单默认视图:连续

在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的行移动表单上的当前记录。当前记录指针不仅会移动,而且如果有更多行可以显示,则用户会看到表单的记录滚动。

任何帮助,确认或建议将不胜感激。

提前致谢!

vba dao adodb ms-access-2016
2个回答
0
投票

从另一个论坛,解决方案是使用ADODB记录集,然后通过Recordset.Clone将表单克隆到它。在上面的代码中,它引用了一个“丑陋”的解决方案:

'使用ADODB记录集可以工作,但这是一个难看的解决方案'要测试注释掉上面的Dim DAO和Set rs语句并取消注释接下来的2行。

'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


0
投票

您的代码无法正常工作,因为您尝试将ADODB.Recordset(Form.Recordset中的那个)分配给DAO.Recordset,`因为它已声明。

如果Recordset-Type可以变化,你可以dimrs as Objectt它得到Form.Recordset的类型(通过Form Property RecordsetClone,这令人惊讶地适用于ADODB:Recordsets)。您可以使用以下方式查询类型:

If TypeOf Me.RecordSet Is ADODB.Recordset Then
   'ADODB
 Else
   'DAO
 End If

如果你需要一个unboundCheckBox,你可以使用clsCCRecordSelect中的SelectRecordsV2-Class。

我使用了多年的TheclsCCRecordSelectis,我不想没有!

© www.soinside.com 2019 - 2024. All rights reserved.