Recently I published an article on documenting queries in your database. This article will help you to document your table fields and indexes.
There are six functions used in this tutorial; two each to create and populate the documenter tables, one to control them, and a utility function to check for the presence of the documenter tables.
You can download a sample database containing the code and a simple menu form. To use, import the form and the module into your database, open the form and click the Document Tables button.
There are two tables for this technique; ztblTableFields and ztblIndexes. They can be created using the following scripts:
''==================================================================
''CreateztblTableFields function.
''Description: Creates a table to hold field names and
''properties. First tries to delete the table, to
''prevent an error when the SQL statement runs.
''Created 27 Nov 2007 by Denis Wright.
''Updated 21 Dec 2007 by Denis Wright.
''Updated 22 Apr 2008 by Denis Wright -- added Description field
''==================================================================
Function Create_ztblTableFields()
Dim sSQL As String
DoCmd.SetWarnings False
On Error Resume Next
DoCmd.RunSQL "DROP TABLE ztblTableFields"
On Error GoTo 0
sSQL = "CREATE TABLE ztblTableFields " _
& "( TableFieldID COUNTER, " _
& "TableName TEXT(50), " _
& "FieldName TEXT(50), " _
& "FieldType LONG, " _
& "FieldRequired INTEGER, " _
& "FieldDefault TEXT(50), " _
& "FieldDescription TEXT(255) )"
DoCmd.RunSQL sSQL
DoCmd.SetWarnings True
End Function
''===================================================================
''CreateztblIndexes function.
''Description: Creates a table to hold field names and
''index properties. First tries to delete the table, to
''prevent an error when the SQL statement runs.
''Created 27 Nov 2007 by Denis Wright.
''Updated 22 Apr 2007 by Denis Wright -- Added IndexIgnoreNulls field
''===================================================================
Function Create_ztblIndexes()
Dim sSQL As String
DoCmd.SetWarnings False
On Error Resume Next
DoCmd.RunSQL "DROP TABLE ztblIndexes"
On Error GoTo 0
sSQL = "CREATE TABLE ztblIndexes " _
& "( TableIndexID COUNTER, " _
& "TableName TEXT(50), " _
& "IndexName TEXT(50), " _
& "IndexRequired INTEGER, " _
& "IndexUnique INTEGER, " _
& "IndexPrimary INTEGER, " _
& "IndexForeign INTEGER, " _
& "IndexIgnoreNulls INTEGER )"
DoCmd.RunSQL sSQL
DoCmd.SetWarnings True
End Function
These functions use DDL to create the tables and their fields. As their structures are very similar, I will just describe the first one.
| Field Type | DDL Data Type |
|---|---|
| Text | TEXT(50) |
| Memo | MEMO |
| Byte | BYTE |
| Integer | INTEGER |
| Long Integer | LONG |
| AutoNumber | COUNTER |
| Single | SINGLE |
| Double | DOUBLE |
| Currency | CURRENCY |
| Replication ID | GUID |
| Date/Time | DATETIME |
| Yes/No | YESNO |
| Long Binary (OLE Object) | LONGBINARY |
| Binary | BINARY(50) |
The two functions below populate the documenter tables. Each is passed the name of an existing table, and loops through the fields or indexes of that table, writing the properties of each field / index to a new record in the corresponding documenter table.
The On Error Resume Next line in ListTableFields causes the code to skip properties that do not exist for that field.
''====================================================================
''ListTableFields function
''Takes: The name of a table to be processed.
''Returns: The name and selected properties of the table's fields.
''Created: 27 Nov 2007 by Denis Wright
''Updated: 22 Apr 2008 by Denis Wright -- added Description property
''====================================================================
Function ListTableFields(strTableName As String)
Dim dbs As DAO.Database
Dim tdf As DAO.TableDef
Dim rst As DAO.Recordset
Dim fld As DAO.Field
Set dbs = CurrentDb()
'define the tabledef and write field properties to ztblTableFields
Set tdf = dbs.TableDefs(strTableName)
Set rst = dbs.TableDefs("ztblTableFields").OpenRecordset
On Error Resume Next
For Each fld In tdf.Fields
rst.AddNew
rst!TableName = tdf.Name
rst!FieldName = fld.Name
rst!FieldType = fld.Type
rst!FieldSize = fld.FieldSize
rst!FieldRequired = fld.Required
rst!FieldDefault = fld.DefaultValue
rst!FieldUpdatable = fld.DataUpdatable
rst!FieldDescription = fld.Properties("Description")
rst.Update
Next fld
rst.Close
Set rst = Nothing
Set tdf = Nothing
Set dbs = Nothing
On Error GoTo 0
End Function
''====================================================================
''ListTableIndexes function
''Takes: The name of a table to be processed.
''Returns: The name and selected properties of the table's indexes.
''Created: 27 Nov 2007 by Denis Wright
''====================================================================
Function ListTableIndexes(strTableName As String)
Dim dbs As DAO.Database
Dim tdf As DAO.TableDef
Dim rst As DAO.Recordset
Dim idx As DAO.Index
Set dbs = CurrentDb()
'define the tabledef and write field properties to ztblTableFields
Set tdf = dbs.TableDefs(strTableName)
Set rst = dbs.TableDefs("ztblIndexes").OpenRecordset
For Each idx In tdf.Indexes
rst.AddNew
rst!TableName = tdf.Name
rst!IndexName = idx.Name
rst!IndexRequired = idx.Required
rst!IndexUnique = idx.Unique
rst!IndexPrimary = idx.Primary
rst!IndexForeign = idx.Foreign
rst!IndexIgnoreNulls = idx.IgnoreNulls
rst.Update
Next idx
rst.Close
Set rst = Nothing
Set tdf = Nothing
Set dbs = Nothing
End Function
This is the function that controls the others. It does the following:
''=======================================================================
''DocumentTables function.
''Description: Checks to see if the two documenter tables exist. If not,
''they are created; otherwise they are cleared.
''The function then loops through the TableDefs collection and documents
''all tables except for system and temporary tables.
''Created: 27 Nov 2007 by Denis Wright.
''Modified: 21 Dec 2007 -- turn off warnings
''=======================================================================
Function DocumentTables()
Dim dbs As DAO.Database
Dim tdf As DAO.TableDef
DoCmd.SetWarnings False
'check that the documentor tables exist; if not, create them.
'otherwise, remove contents of documenter tables before re-populating
If Not TableExists("ztblTableFields") Then
Call Create_ztblTableFields
Else
DoCmd.SetWarnings False
DoCmd.RunSQL "DELETE * FROM ztblTableFields"
DoCmd.SetWarnings True
End If
If Not TableExists("ztblIndexes") Then
Call Create_ztblIndexes
Else
DoCmd.SetWarnings False
DoCmd.RunSQL "DELETE * FROM ztblIndexes"
DoCmd.SetWarnings True
End If
Set dbs = CurrentDb()
'exclude non-system and temp tables, otherwise list field and index properties
For Each tdf In dbs.TableDefs
If Left(tdf.Name, 4) <> "Msys" And Left(tdf.Name, 4) <> "~TMP" Then
Call ListTableFields(tdf.Name)
Call ListTableIndexes(tdf.Name)
End If
Next tdf
DoCmd.SetWarnings True
Set dbs = Nothing
End Function
To check whether or not a table exists, you can search for it in the TableDefs collection and look for the result of the Err function. Here is one way to do that:
''==========================================================
''TableExists function
''Takes: The name of a table whose existence we want to test.
''Returns: True if table is found, False otherwise.
''Description: Test that a table exists by trying to assign
''a TableDef to it.
''If the table has not been found, an error is generated and the
''TableExists function returns False; otherwise it is True.
''Created: 26 Nov 2007 by Denis Wright.
''Modified: 7 July 2010.
''==========================================================
Function TableExists(strTable As String) As Boolean
Dim tdf As DAO.TableDef
TableExists = True
On Error GoTo Err_Handle
Set tdf = CurrentDb.TableDefs(strTable)
Err_Exit:
Set tdf = Nothing
Exit Function
Err_Handle:
If Err.Number = 3265 Then 'table not found
'exit without error message; the caller function
'will create the table
Else
MsgBox "Error " & Err.Number & "; " & Err.Description
End If
TableExists = False
Resume Err_Exit
End Function
The code does the following:
Paste all 6 functions into a new module and call it basDocumentation. Or, if you have already created that module for the query documenter, add this code to the existing module.
Run the DocumentTables function by placing your cursor in the code and pressing the F5 key. Alternatively, run it from a button on a form by adding this code to the button's Click event:
basDocumentation.DocumentTables
If you are unsure how to create event code in Access, see this tip.
Alternatively, download the sample database, import the module and the form into your database, and run the code by pressing the Document Tables button on the form.