Access Cookbook - Ken Getz [90]
' retrieve the information. With forms, you can open the
' form in hidden mode, at least.
Dim db As Database
Dim rstObj As DAO.Recordset
Dim rstProps As DAO.Recordset
Dim lngObjectID As Long
Dim frm As Form
Dim ctl As Control
Dim intI As Integer
Dim obj As Object
On Error GoTo HandleErr
Call SysCmd(acSysCmdSetStatus, "Getting information on form " & _
strName & ".")
Set db = CurrentDb( )
' No need to open the form if it's THIS form.
If strName <> Me.Name Then
DoCmd.OpenForm strName, View:=acDesign, WindowMode:=acHidden
End If
Set rstObj = db.OpenRecordset("zstblSubObjects", _
dbOpenTable, dbAppendOnly)
Set rstProps = db.OpenRecordset("zstblProperties", _
dbOpenTable, dbAppendOnly)
' Handle the form properties first.
Set frm = Forms(strName)
AddProps rstObj, rstProps, frm, "Form", lngParentID
' Handle the five possible form sections.
For intI = 0 To 4
Set obj = frm.Section(intI)
AddProps rstObj, rstProps, obj, "Section", lngParentID
Form_Next_Section:
Next intI
' Handle all the controls.
For Each ctl In frm.Controls
AddProps rstObj, rstProps, ctl, GetControlType(ctl), lngParentID
Next ctl
' Don't close the form that's running all this.
If Me.Name <> strName Then
DoCmd.Close acForm, strName
End If
ExitHere:
Exit Sub
HandleErr:
Select Case Err
Case acbErrInvalidSection
Resume Form_Next_Section
Case Else
MsgBox Err & ": " & Err.Description, , "DocumentForm"
End Select
Resume ExitHere
End Sub
The procedure starts by opening the requested object in design mode so it can get the information it needs. It cannot open the objects in normal view mode, because that would run the objects' event procedures, which might have unpleasant side effects.
Starting with Access 2002, you can specify a WindowMode when you use DoCmd.OpenReport. This allows you to hide a report when you open it, which is nice when you are opening it in design view.
As shown in our example, if the code tries to open the current form, it simply skips the open step. (This means, of course, that your documentation on the current form will be different than that of other forms: it's already open in form view, and the rest will be opened in design view.) Skipping the current form isn't an issue if you're documenting reports. When it's complete, DocumentForm/Report also closes the object (as long as it wasn't the current form). This is shown in the following code fragment from the DocumentForm procedure:
' No need to open the form if it's THIS form.
If strName <> Me.Name Then
DoCmd.OpenForm strName, View:=acDesign, WindowMode:=acHidden
End If
.
. ' All the real work happens here...
.
' Don't close the form that's running all this.
If Me.Name <> strName Then
DoCmd.Close acForm, strName
End If
DocumentForm next opens two recordsets, to which it adds rows as it documents your objects. These are specified as append-only recordsets in order to speed up the processing. The relevant code is:
Set rstObj = db.OpenRecordset("zstblSubObjects", _
dbOpenTable, dbAppendOnly)
Set rstProps = db.OpenRecordset("zstblProperties", _
dbOpenTable, dbAppendOnly)
Next, the procedure documents all the properties of the main object itself. As it will do when documenting all the objects, it calls the AddProps procedure. AddProps expects to receive references to the two recordsets, a reference to the object to be documented, the text to appear in the list box for the object's type, and the ID value for the main, parent object. The code fragment that calls AddProps appears as follows:
' Handle the form properties first.
Set frm = Forms(strName)
AddProps rstObj, rstProps, frm, "Form", lngParentID
The procedure then documents the properties of the sections. For forms, there can be at most five sections (detail, form header/footer, page header/footer). For reports, there can be up to 25: the same 5 as for forms, plus a header and footer for up to 10 report grouping sections. Note that any section may or may not exist. Therefore, the code traps for this error and