ADO - ADO Recordset State Property and Object Lifecycle

The ADO Recordset State property is used to determine the current state of an ADO Recordset object. A Recordset represents a set of records retrieved from a data source, and its state changes as the application opens, uses, and closes it. Understanding the State property is important because it allows a program to check whether a Recordset is currently open, closed, or involved in an asynchronous operation before performing another action.

1. What Is the Recordset State Property?

In ADO, the State property indicates the current operational state of a Recordset object. It is a read-only property, meaning that you cannot directly assign a new value to it.

The basic syntax is:

 
recordset.State
 

The value returned by the State property is represented by an ObjectStateEnum constant.

The most commonly encountered states are:

 
adStateClosed = 0
adStateOpen = 1
adStateConnecting = 2
adStateExecuting = 4
adStateFetching = 8
 

These values can sometimes be combined because the State property is a bitmask. Therefore, an ADO object can have more than one state at the same time.

For example, a Recordset might be in an executing and fetching state during an asynchronous operation.

2. adStateClosed

adStateClosed indicates that the Recordset is currently closed.

A newly created Recordset object is normally closed until the application opens it.

Example:

 
Dim rs As ADODB.Recordset

Set rs = New ADODB.Recordset

If rs.State = adStateClosed Then
    MsgBox "The Recordset is closed."
End If
 

A closed Recordset does not provide access to its records. Before attempting to work with its fields or move through its records, the Recordset generally needs to be opened.

The state also becomes adStateClosed after calling:

 
rs.Close
 

Checking for adStateClosed before opening a Recordset can help prevent errors caused by trying to open an already-open object.

3. adStateOpen

adStateOpen indicates that the Recordset is open and available for operations.

For example:

 
rs.Open "SELECT * FROM Employees", conn

If rs.State = adStateOpen Then
    MsgBox "Recordset is open."
End If
 

Once the Recordset is open, the application can perform operations such as:

 
rs.MoveFirst
rs.MoveNext
rs.MovePrevious
rs.MoveLast
 

It can also access field values:

 
MsgBox rs.Fields("EmployeeName").Value
 

When the application has finished using the Recordset, it should normally close it:

 
rs.Close
 

4. Why Checking the State Is Important

One of the most practical uses of the State property is to determine whether an object is already open before attempting to close or reopen it.

For example:

 
If rs.State = adStateOpen Then
    rs.Close
End If
 

This prevents the program from unnecessarily calling Close on a Recordset that is already closed.

Similarly, before opening a Recordset, an application can check its state:

 
If rs.State = adStateClosed Then
    rs.Open "SELECT * FROM Employees", conn
End If
 

This approach is particularly useful in applications where the same Recordset object is reused multiple times.

5. Recordset Object Lifecycle

The object lifecycle describes the stages through which a Recordset passes during its existence.

A typical lifecycle looks like this:

 
Create Recordset
       |
       v
Closed State
       |
       v
Open Recordset
       |
       v
Work with Records
       |
       v
Close Recordset
       |
       v
Closed State
       |
       v
Release Object
 

The lifecycle can be divided into several important stages.

Stage 1: Object Creation

The first stage is creating the Recordset object.

In VB6 or VBA:

 
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
 

At this point, the Recordset object exists, but it has not necessarily been connected to a set of records.

Its state is normally:

 
adStateClosed
 

Stage 2: Configuration

Before opening the Recordset, the application can configure properties such as cursor type and lock type.

For example:

 
rs.CursorType = adOpenStatic
rs.LockType = adLockOptimistic
 

These settings influence how the Recordset behaves when it is opened.

Stage 3: Opening the Recordset

The application then opens the Recordset.

 
rs.Open "SELECT * FROM Employees", conn
 

ADO communicates with the data provider and obtains the requested data.

After a successful open operation, the Recordset normally enters:

 
adStateOpen
 

The application can now work with the returned records.

Stage 4: Processing Records

While the Recordset is open, the application can navigate through the records and read or modify data, depending on the Recordset configuration.

For example:

 
Do Until rs.EOF
    Debug.Print rs.Fields("EmployeeName").Value
    rs.MoveNext
Loop
 

During this stage, the Recordset remains open.

Stage 5: Closing the Recordset

When the application no longer needs the records, it should close the Recordset.

 
rs.Close
 

The Recordset then returns to:

 
adStateClosed
 

Closing the Recordset releases resources associated with the active result set.

Stage 6: Releasing the Object

After closing the Recordset, the object itself can be released.

In VB6 or VBA:

 
Set rs = Nothing
 

This removes the application's reference to the Recordset object.

It is important to distinguish between closing and releasing.

 
rs.Close
 

closes the active Recordset.

 
Set rs = Nothing
 

releases the object reference.

They are related but are not the same operation.

6. Connecting, Executing, and Fetching States

ADO can also use states associated with operations taking place against the data source.

adStateConnecting

adStateConnecting indicates that a connection operation is in progress.

Although this state is more commonly associated with an ADO Connection object, understanding it is useful when studying ADO's state model.

adStateExecuting

adStateExecuting indicates that an operation is being executed.

For example, when a command is being processed by the provider, the object can temporarily enter an executing state.

adStateFetching

adStateFetching indicates that records are currently being retrieved from the data source.

These states are particularly relevant when asynchronous ADO operations are being used.

7. State Values Can Be Combined

ADO State values are designed as bit flags. Consequently, the State property should not always be treated as a simple single-value enumeration.

For example:

 
If (rs.State And adStateOpen) <> 0 Then
    MsgBox "Recordset is open."
End If
 

This method is safer when multiple state flags may be active.

Instead of assuming that the State property must equal exactly adStateOpen, the And operation checks whether the open flag is present.

8. Practical Example

Consider the following example:

 
Dim rs As ADODB.Recordset

Set rs = New ADODB.Recordset

If (rs.State And adStateClosed) <> 0 Then
    rs.Open "SELECT * FROM Employees", conn
End If

If (rs.State And adStateOpen) <> 0 Then

    Do Until rs.EOF
        Debug.Print rs.Fields("EmployeeName").Value
        rs.MoveNext
    Loop

    rs.Close

End If

Set rs = Nothing
 

The program follows a controlled lifecycle.

First, it creates the Recordset. It then checks whether the Recordset is closed. If it is closed, the program opens it. Once it is open, the application processes the records. Finally, it closes the Recordset and releases the object.

9. State Property vs. Object Lifecycle

The State property and object lifecycle are closely related, but they describe different things.

The State property tells the application what the object is doing or whether it is open or closed.

The object lifecycle describes the complete progression of the object from creation through use and finally release.

For example:

Lifecycle Stage Typical State
Recordset created Closed
Opening operation Connecting/Executing/Fetching as applicable
Records available Open
Records being processed Open
Recordset closed Closed
Object reference released Object no longer referenced

The State property therefore provides a way for the application to monitor part of the Recordset's lifecycle.

10. Common Programming Mistakes

One common mistake is trying to open a Recordset without checking whether it is already open.

 
rs.Open "SELECT * FROM Employees", conn
 

If the same object is already open, the application can encounter an ADO error.

A safer approach is:

 
If (rs.State And adStateOpen) <> 0 Then
    rs.Close
End If

rs.Open "SELECT * FROM Employees", conn
 

Another mistake is assuming that closing a Recordset automatically destroys the object.

 
rs.Close
 

does not mean the object reference has been released. If the object is no longer needed, it can also be released:

 
Set rs = Nothing
 

A third mistake is accessing records after closing the Recordset:

 
rs.Close

MsgBox rs.Fields("EmployeeName").Value
 

The Recordset no longer has an active set of records, so attempting to access its data after closing it can result in an error.

11. Advantages of Using the State Property

Using the State property provides several benefits.

First, it allows applications to determine whether a Recordset is currently available for use.

Second, it helps prevent invalid operations, such as opening an already-open Recordset or attempting to manipulate records after closing it.

Third, it makes reusable database code more reliable. A procedure can examine the current state before deciding whether to open, close, or continue working with the Recordset.

Finally, state checking contributes to better resource management because applications can explicitly close objects when their work is finished.

Conclusion

The ADO Recordset State property provides information about the current operational condition of a Recordset. The most important states for everyday ADO programming are adStateClosed and adStateOpen, while adStateExecuting and adStateFetching become particularly relevant when operations occur asynchronously.

 

Understanding the State property together with the Recordset object lifecycle helps developers write safer and more predictable database applications. A well-managed Recordset generally follows a clear sequence: create the object, configure it, open it, process the records, close it, and finally release the object reference. This approach reduces unnecessary errors and helps ensure that database resources are managed properly.