Professional Documents
Culture Documents
Microsoft Access Tips For Serious Users
Microsoft Access Tips For Serious Users
1. DAO versus ADO 2. Recordset types 3. Move with no records 4. RecordCount without MoveLast 5. MoveNext without testing EOF 6. Loop without MoveNext 7. Find without NoMatch 8. AddNew without LastModified 9. Failing to close recordsets 10. Nested recordsets
Solution:
To ensure your code works reliably: 1. Set your references to use just the library you want. 2. If you must use both, list your main one first. 3. Disambiguate by specifying which library's recordset you want. Use: Dim rs As DAO.Recordset not: Dim rs As Recordset
2. Recordset types
There are different types of DAO recordset, with different methods. When you OpenRecordset() on a query or attached table, Access defaults to a Dynaset type (dbOpenDynaset). When you OpenRecordset() on a local table, it defaults to a Table type (dbOpenTable.) The Table type has different methods (e.g. Seek instead of FindFirst), but it cannot be used with attached tables. So if you later split your database so the tables are attached, the code fails when you use a method that no longer applies.
Solution:
Always specify the type you want. Dynaset guarantees your code will work for all queries and tables, local and attached. Example:
Set rs = db.OpenRecordset("Table1", dbOpenDynaset)
Solution:
Test before using any of the Move methods. Either of these approaches works:
If Not (rs.BOF And rs.EOF) Then 'There are no records if BeginningOf-File and End-Of-File are both true. If rs.RecordCount <> 0 Then '100% reliable in DAO, but some ADO recordsets return -1 as the count.
Solution:
If you need to know the RecordCount, use the MoveLast method first. This forces Access to wait while all records load, so the RecordCount reflects the entire recordset.
Hint:
Don't MoveLast unless you really need to: this will be slow with a large recordset or a recordset drawn across a network. RecordCount will always be at least 1 if records exist, so there is no need to MoveLast if you only want to know if you have records to work with.
Solution:
Use this construct for looping through Access recordsets:
Do while Not rst.EOF If rst![MyField] <> Something Then condition. Exit Do End If ' Rest of your code here. rst.MoveNext 'The real loop exit
Loop
Solution:
VBA is more forgiving than most other languages: just press Ctrl+Break to break out of the loop.
Hint:
Even in a quick'n'dirty procedure, a progress indicator lets you know if a loop is stuck. The simplest reports every 100th record in the loop like this:
i = i + 1 If i Mod 100 = 0 Then 100. DoCmd.Echo True, i End If 'Mod gives the remainder of i divided by
Solution:
Always test for NoMatch after using Seek or a Find method. Example:
rs.FindFirst "City = ""New York""" If Not rs.NoMatch Then 'It's okay to keep processing. End If
Solution:
To access the new record, move to the bookmark LastModified:
rst.AddNew 'Assign fields here. rst.Update rst.Bookmark = rst.LastModified ' Work with the new record here.
Solution:
Always close recordsets and set objects to Nothing in the error recovery of your procedure. Use this construct:
Sub MyProc On Error Goto Err_MyProc Dim db as Database Dim rst As Recordset Set db = CurrentDb() Set rst = db.OpenRecordset("MyTable") 'Useful code here. rst.Close 'Close what you opened. Exit_MyProc: Set rst = Nothing Set db = Nothing Exit Sub Err_MyProc: 'Error handler here. Resume Exit_MyProc End Sub 'Deassign all objects.
harder to apply criteria, harder to pass arguments, harder to determine the delimiters to use for a field, and harder to upsize since other databases like SQL Server don't use these complex types. Eschewing the complex data types is a perfectly valid choice if you only deal with databases you created, but if you support end users or write generic utilities to work with any Access tables, you must learn to handle them.
Solutions
Specifically test for and handle the complex data types if your code must work with databases in Access 2007 or later. Particularly, if you:
Loop through the fields of a recordset, examining each. Apply criteria to a field without knowing its data type.
The Find-as-you-type utility contains a practical example of testing for and excluding the complex data types in the function FindAsUTypeLoad(), while ensuring the code still works in earlier versions of Access. Home Index of tips Top