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

Vba 可以移动记录集中的单个记录吗?,vba,ms-access,Vba,Ms Access,我有一个包含要完成的作业的表子窗体。我正在VBA中创建一个算法,以最有效的顺序组织作业 是否有办法移动记录集中的单个记录,或者我是否被OrderBy卡住了 编辑: 为了更加清晰,我希望能够将记录移动到同一个表中的任何其他索引。我打算运行我的算法,将记录按完成顺序移动。然后设置每个记录的“处理日期”字段以跟踪订单。简短的回答是“否”,记录集中记录的索引不能直接更新。只有通过设置不同的order by子句并重新查询数据库,或者通过设置recordset.Sort属性或Form.OrderBy属性(绑

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

是否有办法移动记录集中的单个记录,或者我是否被OrderBy卡住了

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

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


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

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

现在,您的VBA代码可以使用各种技术来设置JobOrder值。您可能可以使用
Me.RecordsetClone
方法来使用recordset对象枚举和更新值。使用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
此外,您可以使用以下内容刷新表单的排序顺序:

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
then
Me.Requery
强制以正确的顺序重新加载整个记录集(假设记录源具有正确的order BY子句)。这种技术的好处是将事务中的所有更改包装起来,这些更改可以全部提交或回滚,这是绑定表单的记录集对象所无法做到的。

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


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

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

现在,您的VBA代码可以使用各种技术来设置JobOrder值。您可能可以使用
Me.RecordsetClone
方法来使用recordset对象枚举和更新值。使用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
此外,您可以使用以下内容刷新表单的排序顺序:

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
then
Me.Requery
强制以正确的顺序重新加载整个记录集(假设记录源具有正确的order BY子句)。这种技术的好处是将事务中的所有更改包装起来,这些更改可以一起提交或回滚,这是绑定表单的记录集对象所不能做的。

否,不能在记录集中“移动”记录。表不是电子表格。Order By提供了用户可能需要的几乎所有排序,您可以向表中添加一个新列,该排序将提供您想要的排序,而无需移动记录。在表格中,您将不会看到课程标题的列数据。添加到问题中的更多信息将非常有用。如果您想按特定顺序组织作业,那么您计划如何存储该顺序?您是否已经有了保存该顺序的字段?从技术上讲,6月7日是正确的,但Ibo的答案可以扩展到提供