Database Journal
MS SQL Oracle DB2 Access MySQL PostgreSQL Sybase PHP SQL Etc SQL Scripts & Samples Links Database Forum

» Database Journal Home
» Database Articles
» Database Tutorials
MS SQL
Oracle
DB2
MS Access
MySQL
» RESOURCES
Database Tools
SQL Scripts & Samples
Links
» Database Forum
» Sitemap
Free Newsletters:
DatabaseDaily  
News Via RSS Feed


follow us on Twitter
Database Journal |DBA Support |SQLCourse |SQLCourse2
 

Featured Database Articles

MS Access

Posted Nov 2, 2009

Create In-Memory ADO Recordsets

By Danny Lesandrini

Creating in-memory ADO recordsets may be a solution in search of a problem, but I find the process fascinating and there's been at least one occasion where it was just the right thing for my application. Maybe it's just what you need too. The download has everything you'll need to check it out.

Working with the Invisible

In a way, all data is invisible but at least when it's in a table you can click on it and "touch it", as it were. What we're proposing to create is a virtual table, in memory, in the form of an ADO recordset. Once we get it, we can manipulate it in code and more importantly, for the sake of this demo, load it into an Access form.

The code to accomplish this is simple and IntelliSense will help you extend what is described below. What follows will work fine, provided you've got a reference set to some version of Microsoft ActiveX Data Objects.

Dim rstADO As ADODB.Recordset
Dim fld As ADODB.Field

Set rstADO = New ADODB.Recordset
With rstADO
    .Fields.Append "EmployeeID", adInteger, , adFldKeyColumn
    .Fields.Append "FirstName", adVarChar, 10, adFldMayBeNull
    .Fields.Append "LastName", adVarChar, 20, adFldMayBeNull
    .Fields.Append "Email", adVarChar, 64, adFldMayBeNull
    .Fields.Append "Include", adInteger, , adFldMayBeNull
    .Fields.Append "Selected", adBoolean, , adFldMayBeNull

    .CursorType = adOpenKeyset
    .CursorLocation = adUseClient
    .LockType = adLockPessimistic
    .Open
End With

There it is. We have a virtual table that we created from nothing. Now we can load it with our own data from the Employees table. For loading the data I reference the fields by their ordinal position but one could also reference them by name.

Dim dbs As DAO.Database
Dim rstDAO As DAO.Recordset
Dim strSQL As String

Set dbs = CurrentDb
strSQL = "SELECT EmployeeID, FirstName, LastName, Email " & _
         "FROM Employees ORDER BY LastName, FirstName"
Set rstDAO = dbs.OpenRecordset(strSQL, dbOpenDynaset)

Do Until rstDAO.EOF
    rstADO.AddNew
    rstADO.Fields(0) = rstDAO!EmployeeID
    rstADO.Fields(1) = rstDAO!FirstName
    rstADO.Fields(2) = rstDAO!LastName
    rstADO.Fields(3) = rstDAO!Email
    rstADO.Fields(4) = Null
    rstADO.Fields(5) = Null
    rstADO.Update
    
    rstDAO.MoveNext
Loop

Notice that two of the columns, Include and Selected, do not correspond to our Employee's table in any way. This is the very reason to use our virtual table. We need a virtual field which we can edit and then potentially use to process the result set. I've set their initial values to NULL.

Finally, we set the Recordset property of the form to our ADO recordset. Note that this is NOT the RecordSource property, which takes the name of a table, a query or a complete SQL Statement. The Recordset property takes an object, an ADO recordset, and requires the SET keyword to make it work. Once it's been set, the ADO recordset we created can be destroyed. When the form opens, it displays our records.

Set Me.Recordset = rstADO

Set rstDAO = Nothing
Set dbs = Nothing

Editing the Recordset

This is where it gets tricky. In my experience, when an ADO recordset is created based directly on a table, the Add New function works fine. In this screen shot you see that the form looks like it supports moving to a new record, but the whole new record row is locked. I couldn't find a work-around for the user interface limitation, but it's easy enough to add a record in code. Once added, it can be edited like any other row.

I had written an article last year that discussed binding ADO recordsets to Access forms. The article link is below and the sample code shows that this limitation doesn't exist naturally. It must be the result of using a virtual table as the source for the ADO recordset.

http://www.databasejournal.com/features/msaccess/article.php/3672601/Manage-Recordsets-in-ADPs.htm

Well, there is another exception, but it's a Microsoft Access limitation. It seems that in versions prior to Access 2003 there is a checkbox bug that really screws up the editing of forms bound to an ADO recordset. In some cases, it causes the application to crash. You can't beat it through any settings, and I tried them all, but upgrading to Access 2003 fixes the issue.

Alternatively, you can use a drop-down box instead of a checkbox. It's clumsy and users tend not to like it, but it does solve the problem. As you can see in the screen shot, it's not pretty.

you can use a drop-down box instead of a checkbox

Why Bother With This Approach

I've used this approach a couple of times, when it was appropriate. There are definite limits to its usefulness but it's just right when you need a Datagrid-With-Checkboxes. Below is a screen shot of an interface I built for users to associate labs with sites. They would select a lab from the drop-down list and it would then be saved as a new row in the SiteLab table. The problem is, this form confused my users.

drop-down list

I know, it's not that complicated and the users shouldn't have been confused but consider the new, improved version below. This is similar to the Access References dialog box where every possible library is shown and the ones you have referenced show up at the top with their checkboxes checked.

the new, improved version

This approach is naturally intuitive, though it requires more code behind the scenes to make it work. When a user checks a box, the AfterUpdate event adds or removes that Lab to the SiteLab table and rebuilds the list. My users prefer this interface and there is no visible performance hit.

One of the nice things about the checkbox interface is that the users can scan the list more easily. They may even double-click an entry and be taken to the Lab Detail page to be sure it's the one they want to add.

Conclusion

Virtual tables from in-memory ADO recordsets are an odd little tool, but one that has a place in my applications. It may or may not be of use in yours, but if you find this useful, drop me a line at dlesandrini@gmail.com and let me know how it worked for you.

Download the ADORST .mdb file.

» See All Articles by Columnist Danny J. Lesandrini



MS Access Archives

Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 




Latest Forum Threads
MS Access Forum
Topic By Replies Updated
Help With Microsoft Access kasy 0 September 4th, 07:35 PM
Linked table not sorting or filtering - ODBC error Java 1 August 28th, 10:37 AM
Use Parameter in select statement (Sql in Microsoft Access) katty.jonh 1 July 25th, 06:45 AM
Query Issue algebroni 7 July 23rd, 04:22 PM