Home > Enterprise >  dbOpenDynaset vs dbOpenTable with index
dbOpenDynaset vs dbOpenTable with index

Time:02-14

I just did a split of an Access database and I've got a couple of linked tables that use a line similar to VL2.Index = "ReportKey" after being opened via VL2.Index = db.OpenRecordset("VolunteerDetail", dbOpenTable), which no longer works because they're now linked tables.

So what do I do instead? I can open the recordset by omitting the dbOpenTable part, but it's the index that I don't know how to handle, because the dynaset piece doesn't have an index in the same way. I understand that VL2.Index = "ReportKey" is assigning the name to the index, but what is the equivalent of that with dbOpenDynaset? I've seen references to things like FindFirst, but those don't make sense to me.

What do I replace VL2.Index = "ReportKey"` with, when using a dynaset?

CodePudding user response:

Ok

VL2.Index = "ReportKey" after being opened via VL2.Index = db.OpenRecordset("VolunteerDetail", dbOpenTable), which no longer works because they're now linked tables.

correct. So this suggests you are using seek() code in your applcation.

There are two solutions here:

So, in place of this:

Dim rstHotels       As DAO.Recordset

Set rstHotels = CurrentDb.OpenRecordset("tblhotels", dbOpenTable)
    
rstHotels.Index = "PrimaryKey"
rstHotels.Seek "=", 17

If rstHotels.NoMatch Then
   Debug.Print "not found"
Else
   Debug.Print "found it"
End If

rstHotels.Close

Change your code to use .FindFirst:

You would use say:

Dim rstHotels  As DAO.Recordset

Set rstHotels = CurrentDb.OpenRecordset("tblHotels1")
    
rstHotels.FindFirst "ID = 17"

If rstHotels.NoMatch Then
   Debug.Print "not found"
Else
   Debug.Print "fount it"
End If

So, you can use .FindFirst, and you do NOT need to use the .index setting. I suspect the above could be used with "much less" changes to your existing code.

but, you can also consider writing out the sql, say like this:

Dim rstHotels  As DAO.Recordset
Dim strSQL     As String

strSQL = "SELECT * from tblHotels WHERE ID = 17"
   
Set rstHotels = CurrentDb.OpenRecordset(strSQL)
    
If rstHotels.RecordCount > 0 Then
   Debug.Print "found it"
End If

So, one approach is to dump seek, but still use .FindFirst and .nomatch.

However, seek() MAY WELL be desired.

VERY important is HOW are you using seek? (or are you even using seek????).

I ask, since seek() is SUPER DUPER high speed performance option. This goes back to the early days of desktop database systems. seek() does NOT even use SQL, and it is VERY fast - I mean blistering fast.

So, it really depends on how you were using the .index setting. If you were just using .FindFirst, then in fact you don't need to set .index. You ONLY need to set the index WHEN using .seek().

Now, if you ARE using .seek() and you ARE hitting a whole bunch of PK or index values for special processing? If you can build a single query, no problem.

However, if the .seek() is to be used over and over - say in a processing loop?

then you can consider a 3rd alternative, use the data engine object, and DIRECLTY open the back end database, and your existing code and .seek() can still be used.

You would use this:

Public Function OpenForSeek(TableName As String) As Recordset
' Assume MS-ACCESS table
Set OpenForSeek = DBEngine.Workspaces(0).OpenDatabase _
                (Mid(CurrentDb().TableDefs(TableName).Connect, _
                11), False, False, "").OpenRecordset(TableName, _
                dbOpenTable)
End Function

Then, you can go:

dim rstHotels   as DAO.RecordSet

set rstHotels = OpenForSeek("tblHotels")

So, the above means you open the back end table directly in a round about way. I only suggest this last option if you REALLY do need .seek(), and you really need super duper performance to pull values.

CodePudding user response:

It is FindFirst and FindNext to use, so if these "don't make sense to me", read up the documentation:

Recordset.FindFirst method (DAO)

  • Related