HanSolo
HanSolo

Reputation: 35

Why does a datasheet view show only 100 records when based on sorted and filtered adodb recordset

I have an access 2003 front end database with a form that allows users to see a sorted and/or filtered view of some data. The data is displayed in a sub-form.

The base data (loaded when the form is opened) is retrieved into a disconnected ADODB.Recordset object (static client side cursor). The sub-form's Recordset property is set to the disconnected recordset and all records are displayed.

Applying just a sort (in code) to the recordset object and then setting the sub-form to use the sorted recordset displays the data with the correct sort applied. The filter property is set to adFilterNone for this to work. All records are displayed (correct).

Applying just a filter (in code) to the recordset object and then setting the sub-form to use the filtered recordset displays the data with the correct filter applied. The sort property is set to an empty string for this to work. All records matching the filter are displayed (correct).

When both the sort property AND the filter property are set on the recordset, and that recordset is then set to the sub-form's Recordset property, only the first 100 matching records are displayed (incorrect). They are displayed in sort order. The underlying recordset object shows the correct record count for the filtered records, they just don't all display on the form.

Does anyone know why this is happening and if there is a way to get around this apart from creating a recordset using a new SQL string each time?

Thanks in advance.

Upvotes: 0

Views: 1151

Answers (1)

HK1
HK1

Reputation: 12230

What you are seeing with filtering and sorting is a known limitation of ADO recordsets.

Take a look at the list of ADO Cons listed on this page. Notice the one on the bottom: http://www.utteraccess.com/wiki/index.php/Choosing_between_DAO_and_ADO

I couldn't find any documentation on MS's Support site about this so I don't know if it's a bug or simply a limitation. I'm assuming it's the latter.

FYI, I think MS has basically forgotten about ADO (classic). The last release of MDAC (which is how you obtain ADO) was 5/10/2005.

As far as a work-around for this problem, you can try using this function. It returns a new, filtered and sorted recordset. Just keep a big, full recordset handy and use this function to get a new one every time you do a sort/filter. This does increase your overall resource usage, especially memory.

I have used this function but it hasn't been fully tested to make sure it's bullet proof in every way. You might quickly find some bug or limitation with it. I actually had a note that it needed some kind of work but my note was unclear, I didn't have time to test it now, and I did find that I'm using this function in my production code so I think it's working.

Public Function GetFilteredRecordset(ByRef rsSource As ADODb.Recordset, _
                                        ByVal sWhere As String, _
                                        Optional ByVal sOrderBy As String, _
                                        Optional ByVal LockType As ADODb.LockTypeEnum = adLockUnspecified) As ADODb.Recordset

    Dim sOriginalOrderBy As String
    sOriginalOrderBy = rsSource.Sort
    Dim F As ADODb.Field
    For Each F In rsSource.Fields
        'Debug.Print F.Name
    Next F

    rsSource.Filter = sWhere
    If sOrderBy <> "" Then
        If Left(LCase(sOrderBy), 8) = "order by" Then sOrderBy = Trim(Right(sOrderBy, Len(sOrderBy) - 8))
        rsSource.Sort = sOrderBy
    End If
    Dim rsF As ADODb.Recordset

    Dim objStream As ADODb.Stream
    'Create a New ADO 2.5 Stream object
    Set objStream = New ADODb.Stream
    'Save the Recordset to the Stream object in XML format
    rsSource.Save objStream, adPersistXML
    'Create an exact copy of the saved Recordset from the Stream Object
    Set rsF = New ADODb.Recordset
    rsF.Open objStream, , , LockType

    rsSource.Filter = ""
    rsSource.Sort = sOriginalOrderBy
    'Close and de-reference the Stream object
    objStream.Close
    Set objStream = Nothing
    Set GetFilteredRecordset = rsF
End Function

Another strange limitation of filtering ADO recordsets is that your OR keyword must always be on the top level. That is also documented in the link I posted above although I'm not sure if the examples given are accurate.

Upvotes: 1

Related Questions