如何在DAO数据库中正确使用Seek



我正在尝试在表上的列表框控件中搜索当前选定的项目。

在更新事件后的列表框控件中,我有此代码

Private Sub lst_MainList_AfterUpdate()
    Dim theDB As DAO.Database
    Dim theProposalsTable As DAO.Recordset
    Set theDB = CurrentDb
    Set theProposalsTable = theDB.OpenRecordset("tbl_PROPOSAL", dbOpenDynaset)
    theSeeker theProposalsTable, Me.lst_PPpg_MainList.Value    
End Sub

然后我的模块 1 上有一个带有此代码的子。我从一个示例代码@ https://msdn.microsoft.com/en-us/library/office/ff836416.aspx

Sub theSeeker(ByRef rstTemp As Recordset, intSeek As Integer)
   Dim theBookmark As Variant
   Dim theMessage As String
   With rstTemp
      ' Store current record location.
      theBookmark = .Bookmark
      .Seek "=", intSeek
      ' If Seek method fails, notify user and return to the
      ' last current record.
      If .NoMatch Then
         theMessage = "Not found! Returning to current record." & vbCr & vbCr & "NoMatch = " & .NoMatch
         MsgBox theMessage
         .Bookmark = theBookmark
      End If
   End With
End Sub

我收到运行时错误 3251 此类对象不支持操作。

当我点击调试时,它会突出显示.Seek "=", intSeek

在这一点上从链接页面...

在索引表类型的记录集对象中查找记录

"表类型记录集"表示必须使用dbOpenTable而不是dbOpenDynaset OpenRecordset()

这一点至关重要。 如果无法使用 dbOpenTable 打开表,则无法使用 Seek 。 并且dbOpenTable只能与当前数据库中包含的本机 Access 表一起使用。 它不能与任何类型的链接表一起使用。

因此,如果dbOpenTabletbl_PROPOSAL兼容,此更改将消除第一个错误...

'Set theProposalsTable = theDB.OpenRecordset("tbl_PROPOSAL", dbOpenDynaset)
Set theProposalsTable = theDB.OpenRecordset("tbl_PROPOSAL", dbOpenTable)

如果这确实有效,下一个错误将是 #3019,"没有当前索引的操作无效"。 发生这种情况是因为您必须在调用 Seek ...

With rstTemp
  ' Store current record location.
  theBookmark = .Bookmark
  ' Set the index. 
  .Index = "PrimaryKey" '<- use your index name here
  .Seek "=", intSeek

如果需要列出表索引的名称,可以检查其TableDef.Indexes集合。 这是一个即时窗口示例,我的数据库中有一个表......

set db = CurrentDb
for each idx in db.TableDefs("tblFoo").Indexes : ? idx.name : next
id
PrimaryKey

不能对链接表使用 Seek 方法,因为不能将链接表作为表类型的记录集对象打开...

但是,如果使用 OpenDatabase 方法打开后端数据库,则可以使用 Seek 方法。

所以代替:

Set theDB = CurrentDb()

这样做:

Set theDB = OpenDatabase("full path to backend database")
Set theProposalsTable = theDB.OpenRecordset("tbl_PROPOSAL", dbOpenTable)

请允许我结合这两个古老的答案。是的,在dbOpenTable打开链接表时会出现错误,因为只有您正在处理的数据库对象的本地表才支持该表。正如David指出的那样,您可以将链接的后端作为数据库对象打开并使用它。

我在后端使用一个名为"设置"的可靠表。如果您没有可用于拉取后端的可靠表,则可以将表名作为参数传入。

一旦我有了后端对象的句柄,我就会存储它,这样我们就可以在整个代码中快速调用它,而无需重新创建对象。

Private thisBEDB As Database
'@Description("This allows us to call directly against linked tables.")
Public Function thisBackend() As Database
    ' For MS-ACCESS table
    If (thisBEDB Is Nothing) Then
        With DBEngine
            Set thisBEDB = .OpenDatabase(Mid(CurrentDB.TableDefs("Settings").Connect, 11), False, False, "")
        End With
    End If
    
    Set thisBackend = thisBEDB
End Function

现在,我们可以使用后端句柄使示例中的代码按预期工作。

Private Sub lst_MainList_AfterUpdate()
    Dim theDB As DAO.Database
    Dim theProposalsTable As DAO.Recordset
    Set theDB = CurrentDb
    Set theProposalsTable = thisBackend.OpenRecordset("tbl_PROPOSAL", dbOpenTable)
    theSeeker theProposalsTable, Me.lst_PPpg_MainList.Value    
End Sub
Sub theSeeker(ByRef rstTemp As Recordset, intSeek As Integer)
    Dim theBookmark As Variant
    Dim theMessage As String
    With rstTemp
        .Index = "PrimaryKey" 
        ' Store current record location.
        theBookmark = .Bookmark
        .Seek "=", intSeek
        ' If Seek method fails, notify user and return to the
        ' last current record.
      If .NoMatch Then
         theMessage = "Not found! Returning to current record." & vbCr & vbCr & "NoMatch = " & .NoMatch
         MsgBox theMessage
         .Bookmark = theBookmark
      End If
   End With
End Sub

最新更新