> ## Content Index
> Fetch the complete content index at: https://nolongerset.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# WARNING: Do NOT Declare DAO Fields As Field2, Field3, etc.
- URL: https://nolongerset.com/bug-alert-dao-field3/
- Published: 2022-07-13T17:35:32.000Z
- Updated: 2026-05-08T12:56:20.000Z
- Description: While declaring DAO Field objects as Field2 will get you additional IntelliSense, it comes at the risk of breaking working code when MS releases a new Field type.
- Author: Mike Wolfe
- Tags: Bug Alert, Defensive Programming, #Import 2026-05-20 02:59

Over the past few days, there have been [several](https://stackoverflow.com/q/72831316/154439) [bug](https://www.access-programmers.co.uk/forums/threads/another-access-365-v2206-bug-from-stackoverflow.323876/) [reports](https://github.com/joyfullservice/msaccess-vcs-integration/issues/341#issuecomment-1183383253) where the following code breaks:

```vba
Dim rs as DAO.Recordset2
Dim fld as DAO.Field2

For Each fld in rs.Fields   '<- Code will break here, because Fields suddenly return Field3
   ... 
Next
```

Source: User papa\_bear on [StackOverflow.com](https://stackoverflow.com/q/72831316/154439)

The reason this particular code started breaking is because of the introduction of a new DAO field type (`Field3`) in Access version 2206\. There are now three different types of DAO fields:

- `DAO.Field`: the original field object
- `DAO.Field2`: extended the original to include support for **MVFs**
- `DAO.Field3`: extended Field2 to include support for **Precision** and **Scale** properties of **Decimal types**

## Why Are There Multiple DAO Field Types?

For this explanation, let's go to the Microsoft response that Access MVP Gustav Brock relayed in his SO answer:

> The simplest workaround for now is to change declarations of type `DAO.Field2` to `DAO.Field`.

> Field2 was added to support properties for multi-valued fields, *Field3 was added to support the Precision and Scale properties for decimal types*. (You’ll note that there is also a Recordset2 object in the browser, for similar reasons).

> You don’t get intellisense for the extended properties if you declare as ‘Field’, but you can still access all the properties in code.

> When we make an update to an interface, we can’t update the existing interface, but must extend the existing interface. We are looking into whether we can improve the backward compatibility issue for cases where people explicitly declared variables to be of type Field2, rather than just Field.

## What Should You Do About This?

The bottom line is that you should NEVER declare a DAO Field variable as anything other than `DAO.Field`.

Any code that declares variables as `DAO.Field2` or `DAO.Field3`, should be immediately changed to `DAO.Field`. Likewise for any code with variables declared as `DAO.Recordset2`; those should be changed to `DAO.Recordset` for the same reasons.

By doing this, you will ensure that your code will continue to run when Microsoft inevitably introduces `Field4`, `Field5`, `Recordset3`, `Recordset4` types in the future.

Over on Adam Waller's excellent [Access source control Github project](https://nolongerset.com/instant-version-control/), Github user Alan Van Art graciously [tested this theory out](https://github.com/joyfullservice/msaccess-vcs-integration/issues/341#issuecomment-1183425070) for us:

>> If switching to DAO.Field works, I would also try switching from DAO.Recordset2 to DAO.Recordset.
> 
> Also no errors in this test case.

## Caveats and Additional Notes

### The `DAO.` Prefix Is Optional

Your code may not include the `DAO.` prefix before your `Field` and `Recordset` declarations. 

The prefix is optional but highly encouraged because the ADO library also has Field and Recordset objects. If you include references to both DAO and ADO in your Access application, then a bare `Dim rs As Recordset` declaration will choose DAO or ADO based on the order you set in Tools > References. You can override that behavior by declaring objects as `DAO.Recordset` or `ADODB.Recordset` accordingly.

It does not appear that ADO has a Field2 or Recordset2 type. That means that if you have both ADO and DAO referenced in your project and *ADO has higher priority*, then switching `As Field2` to `As Field` will have the unintended side effect of changing that field variable from DAO to ADO. 

### Missing IntelliSense

When you switch from `As Field2` to `As Field`, you will lose the following properties and methods from the IntelliSense for your Field object:

- `AppendOnly`
- `ComplexType`
- `Expression`
- `IsComplex`
- `LoadFromFile`
- `SaveToFile`

It is important to note, as Microsoft did in their response at the top of this article, that you **will still be able to use the above properties and methods in your code at runtime**. You just lose the IntelliSense.

When you switch from `As Recordset2` to `As Recordset`, you will lose the following properties *entirely* from your Recordset object (not just from IntelliSense):

- `ParentRecordset`

Unlike the `Field` object, if you need to reference the `ParentRecordset` property of the `Recordset2` object, you will need to declare your Recordset2 object as a generic object. For code readability, I would recommend the following declaration:

```vba
Dim rs As Object  'DAO.Recordset2
```

However, you should only take the above approach if you *need* to use the ParentRecordset property of the Recordset2 object. I have no idea why the behavior is different between the Field/Field2 objects and the Recordset/Recordset2 objects.

### IntelliSense Workaround

If you really want the IntelliSense, you can take a page from the late binding/early binding playbook and have two declarations: one that you use during development and a different one that you use when you deploy your code. 

For example:

```vba
'Uncomment the top line for development; 
'   uncomment the bottom line for production
'Note that you may need to adjust the top line as new
'   versions of Recordset and Field are released
'Dim rs as DAO.Recordset2, fld as DAO.Field2
Dim rs As DAO.Recordset, fld As DAO.Field

For Each fld in rs.Fields
   ... 
Next
```

### External references

[Access with breaking changes on Version 2206 (Recordset2.Fields returns DAO.Field3 instead of DAO.Field2) - Error 13It looks like Microsoft introduced a breaking change with version 2206! :-(If you had code likeDim rs as DAO.Recordset2Dim fld as DAO.Field2 For Each fld in rs.Fields ’&lt;- Code will break ...![](https://cdn.sstatic.net/Sites/stackoverflow/Img/apple-touch-icon.png?v=c78bd457575a)Stack Overflowpapa\_bear![](https://cdn.sstatic.net/Sites/stackoverflow/Img/apple-touch-icon@2.png?v=73d79a89bded)](https://stackoverflow.com/q/72831316/154439)