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

时间:2017-07-26 17:33:30

标签: vba ms-access

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

有没有办法在记录集中移动单个记录,还是我坚持使用OrderBy?

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

1 个答案:

答案 0 :(得分:2)

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

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

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

现在,您的VBA代码可以使用各种技术来设置JobOrder值。您也许可以使用Me.RecordsetClone方法使用记录集对象枚举和更新值。使用RecordsetClone将避免更新绑定主记录集的某些副作用。最后,以下假设所有记录都已具有有效的唯一JobOrder值,但它假定JobOrder不是 required 是唯一的(因为交换技术暂时将两行设置为相同的值)。您可以编写自己的聪明实现来保证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子句)。这种技术的好处是可以将事务中的所有更改包装起来,这些更改可以完全提交或回滚,这是绑定表单的记录集对象无法做到的。