可以移动记录集中的单个记录吗?

Posted

技术标签:

【中文标题】可以移动记录集中的单个记录吗?【英文标题】:Can an individual record in a recordset be moved? 【发布时间】:2017-07-26 17:33:29 【问题描述】:

我有一个表格子表单,其中包含要完成的作业。我正在 VBA 中创建一种算法,以最有效的顺序组织作业。

有没有办法移动记录集中的单个记录,还是我被 OrderBy 卡住了?

编辑: 为了增加一些清晰度,我希望能够将记录移动到同一个表中的任何其他索引。我打算运行我的算法,它将记录移动到它们要完成的顺序。然后设置每条记录的“处理日期”字段以跟踪订单。

【问题讨论】:

否,不能在记录集中“移动”记录。表格不是电子表格。 Order By 提供了用户可能需要的几乎所有排序,您可以向表中添加一个新列,该排序将在不移动记录的情况下为您提供所需的内容。在表单中,你当然不会看到列数据 在您的问题中添加更多信息会很有用。如果您想按特定顺序组织作业,您打算如何存储该订单 - 您是否已经有一个用于保存订单的字段? June7 在技术上是正确的,但 Ibo 的答案可以扩展以提供完整、有用的答案。老实说,不要想着被 OrderBy “卡住”,而是学习和应用正确的数据库/记录集概念。 从哪里搬到哪里? ...不同的表? 【参考方案1】:

简短的回答是“否”,记录集中的记录索引不能直接更新。只能通过设置不同的 ORDER BY 子句并重新查询数据库,或者通过设置 Recordset.Sort 属性或 Form.OrderBy 属性(当绑定到表单时)来更改记录集中的行顺序。


让我们假设有一个名为 [JobOrder] 的可更新 记录集字段。 SQL 源查询可以包括像... ORDER BY [JobOrder] ASC 这样的排序顺序,它在从数据库中检索数据时首先对数据进行排序。作为基本数据库概念的问题,应该假设如果没有指定 ORDER BY 子句,则数据库可以以随机顺序返回数据。 (实际上通常情况并非如此。默认情况下它会按某个索引主键排序,但如果顺序很重要,则不应假定。)

可以设置和更改表单(或子表单)的排序顺序,而无需再次从数据库中重新查询数据。这是通过设置 OrderBy 属性并确保 OrderByOn = True 来完成的。 (仅供参考:除非您采取措施隐藏默认工具功能区(即工具栏)和快捷菜单,否则用户可以更改此排序顺序。)

现在您的 VBA 代码可以使用各种技术来设置 JobOrder 值。您也许可以使用Me.RecordsetClone 方法来枚举和更新使用记录集对象的值。使用 RecordsetClone 将避免更新绑定的主记录集的某些副作用。最后,以下假设所有记录都已经具有有效的、唯一的 JobOrder 值,但它假设 JobOrder 不需要是唯一的(因为交换技术临时将两行设置为相同的值)。您可以自行编写巧妙的实现,以确保 JobOrder 值保持有效且唯一。

Private Sub MoveCurrentUp()
  Dim rs As Recordset2

  Dim thisID As Long
  Dim thisSort As Long
  Dim previousID As Long
  Dim previousSort As Long

  On Error Resume Next
  '* Error handling to avoid cases where recordset is empty
  '* and/or the current record is not valid (i.e. new record)

  If Not IsNull(Me.ID.Value) Then
    thisID = Me.ID.Value
    If Err.Number = 0 Then

      On Error GoTo Catch
      '* Any errors from this point should be
      '* handled specifically rather than ignored

      Set rs = Me.RecordsetClone

      rs.FindFirst "ID=" & thisID
      If Not rs.NoMatch Then
        thisSort = rs!JobOrder
        rs.MovePrevious
        If Not rs.BOF Then
          previousID = rs!ID
          previousSort = rs!JobOrder

          rs.Edit
          rs!JobOrder = thisSort
          rs.Update

          rs.MoveNext
          rs.Edit
          rs!JobOrder = previousSort
          rs.Update

          Set rs = Nothing
          RefreshSort
        End If
      End If
      Set rs = Nothing

      Debug.Print Me.Sort
    End If
  End If

  Exit Sub
Catch:
  MsgBox "Error updating order." & vbNewLine & vbNewLine & _
    "    " & Err.Number & ": " & Err.Description, vbOKOnly Or vbExclamation, "Error"
End Sub

Aferward,您可以使用以下内容刷新表单的排序顺序:

Private Sub RefreshSort(Optional restoreCurrentRecord As Boolean = True)
  Dim rs As Recordset2
  Dim saveID As Long
  saveID = Me.ID.Value

  Me.OrderBy = "[JobOrder] ASC"
  Me.OrderByOn = True

  If restoreCurrentRecord Then
    Set rs = Me.RecordsetClone
    rs.FindFirst "ID=" & saveID
    If Not rs.NoMatch Then
      Me.Bookmark = rs.Bookmark
    End If
    Set rs = Nothing
  End If
End Sub

或者您可以使用 SQL 查询更新行,然后调用 Me.OrderByOn = False 然后调用 Me.Requery 以强制以正确的顺序重新加载整个记录集(假设记录源具有正确的 ORDER BY 子句)。这种技术的好处是将所有更改包装在可以提交或完全回滚的事务中,这是绑定表单的记录集对象无法做到的。

【讨论】:

以上是关于可以移动记录集中的单个记录吗?的主要内容,如果未能解决你的问题,请参考以下文章

在 Django 中更新查询集中的一堆记录的最快方法

游标的使用

ListView是Dart单条记录/结果的理想选择吗?

oracle游标

Linux内核参数优化记录

ADODB