0

我在 Access 2010 中使用动态传递查询从后端数据库中检索一条或多条记录。经过多次试验和错误,我剽窃了足够多的正确代码来检索适当的记录,并在 OnLoad 事件期间将它们分配给我的数据表表单上的未绑定文本框。剩下的唯一问题是显示多条记录。我已经验证我正在检索多条记录,但是每条记录的字段的内容会覆盖存储到表单文本框控件的先前值,所以当我希望从任何地方看到时,我总是在数据表中只显示一条记录一到十。

我确定这是一个简单的解决方案。有人可以向我指出吗?

Private Sub Form_Load()
    Dim sqlString As String
    sqlString = "SELECT Transmitter_ID, Receiver_ID, UTC_Date, Local_Date from Detections"
    If Not IsNull(Me.OpenArgs) Then
        sqlString = sqlString & " where " & OpenArgs
    End If

    Dim cnn As New ADODB.Connection
    Dim cmd As New ADODB.Command
    Dim rst As ADODB.Recordset

    'Define and open connection
    cnn.ConnectionString = "DRIVER={SQLite3 ODBC Driver};Database=z:\EWAMP\EWAMP_be_dev.sqlite"
    cnn.Open

    'Define ADO command
    cmd.ActiveConnection = cnn
    cmd.CommandText = sqlString

    'Populate and enumerate through recordset
    Set rst = cmd.Execute
    If rst.EOF Then
       MsgBox "Nothing found...", vbInformation + vbOKOnly
       Exit Sub
    Else
        Do While Not rst.EOF
            '// I'm guessing the problem is with my control assignments, here.
            Me.cntl_Receiver_ID.Value = rst("Receiver_ID")
            Me.cntl_Transmitter_ID.Value = rst("Transmitter_ID")
            Me.cntl_UTC_Date.Value = rst("UTC_Date")
            Me.cntl_Local_Date.Value = rst("Local_Date")
            Debug.Print {Show me the four control values}
            rst.MoveNext
        Loop
    End If

End Sub

干杯!

杜德利

4

2 回答 2

0

另一个论坛的一位读者向我指出了一个类似于 HK1 提出的解决方案,即Set Me.Recordset = rst. 这解决了我原来的问题,但又产生了另一个问题。

首先,我在未绑定的表单上重新绑定了四个文本框控件,然后使用http://msdn.microsoft.com/en-us/library/ff835419.aspx中的示例对代码进行了重大修改。修改后的代码如下所示:

Private Sub Form_Load()
   Dim sqlString As String
   sqlString = "SELECT Transmitter_ID, Receiver_ID, UTC_Date, Local_Date from Detections"
   If Not IsNull(Me.OpenArgs) Then
      sqlString = sqlString & " where " & OpenArgs
   End If

   Dim cn As ADODB.Connection
   Dim rs As ADODB.Recordset

   'Define and open connection
   Set cn = New ADODB.Connection
   cn.ConnectionString = "DRIVER={SQLite3 ODBC Driver};Database=z:\EWAMP\EWAMP_be_dev.sqlite;"
   cn.Open

   'Create an instance of the ADO Recordset class,
   'and set its properties
   Set rs = New ADODB.Recordset
   With rs
       Set .ActiveConnection = cn
       .Source = sqlString
       '// .LockType = adLockOptimistic
       .LockType = adLockReadOnly
       .CursorType = adOpenKeyset
       '// .CursorType = adOpenStatic
       .Open
   End With

   'Set the form's Recordset property to the ADO recordset
   Set Me.Recordset = rs

   Set cn = Nothing
   Set rs = Nothing
End Sub

该表单现在显示 4 行返回的 4 条记录,20 行 20 条记录,以及至少 256k 行(由我的参数集指定)。唯一剩下的小问题是,对于四个或更多记录,如果我按下“最后一行”导航按钮 (>|),本地光标会将焦点设置到一个或多个中间行,并且控件的属性表会大力刷新(每秒多次)。如果我的表单行数超过屏幕上显示的行数,我无法导航或光标到最后一行。就好像记录集在不断更新。

如您所见,我使用了 RecordSet LockType 和 CursorType 属性(包括 adOpenDynamic 和 adOpenForwardOnly,这两者都会导致 Set Me.Recordset 语句出现运行时错误)。在 adLockOptimistic 和 AdLockReadOnly 之间切换 LockType 以及在 adOpenKeyset 和 adOpenStatic 之间切换 CursorType 对检索性能(现在非常快!)或明显的刷新率(不幸的是,它甚至更快)没有影响。

或许值得一提的是,sqlString 从中“选择”的“检测”表包含约 4M 条记录。我在之前尝试使用绑定到该表的直通查询的数据源的表单时感到沮丧,因为无论我传递给表单的过滤器/WhereClause/OpenArgs 参数如何,查询总是将整个 4M 记录返回给客户端. 如果只有我可以关闭连接(我已经尝试过)或者在我调用过一次后将 RecordSet 静默,那么上面显示的解决方案将是完美的。

于 2012-05-22T06:54:51.630 回答
0

我不相信数据表视图中的表单可以用作未绑定的表单。但是您可以将 ADO 记录集用作表单记录集。

Set Me.Recordset = rst

然后注意不要在表单关闭之前关闭名为 rst 的变量。

另一种替代解决方案是使用内存中的、制造的、断开连接的 ADO 记录集。基本上,您最终会创建一个新记录集,将字段附加到它以匹配您现有的记录集,然后将所有数据移动到您的新记录集中。但是,如果您已经有一个有效的、已填充的 ADO 记录集,我真的看不出这样做的意义。

如果您确实需要/想要在未绑定的表单中显示多条记录,我认为您将不得不使用 ActiveX 控件,例如 GridView、ListView、TreeView 或 MSFlexGrid。我注意到大多数熟练、专业的 Access 开发人员都尽可能远离 ActiveX 控件。如果并且当他们确实使用它们时,他们通常将其限制为仅 TreeView 和 ListView,我认为因为它们是唯一的 ActiveX 控件,它们增加了足够的价值,值得忍受它们可能引入的任何问题。

我建议你看看这篇关于 DAO 和 ADO 的区别的文章。 http://www.utteraccess.com/wiki/index.php/Choosing_between_DAO_and_ADO

于 2012-05-22T04:47:13.907 回答