Since you can perform so many different tasks with standard modules, standalone class modules, and class modules for forms, your applications are likely to have many of these modules. This will eventually create a need for maintenance. One common maintenance requirement is the insertion or deletion of one or more lines of code in a set of modules. This section shows how to add a line to and remove a line from all the standard and standalone class modules, and then it shows the same for form class modules. Because the code for standard and standalone class modules is stored differently from the code for class modules for forms, the steps are slightly different.
The Module object offers an array of methods and properties that can help you programmatically edit modules. The samples in this section use the InsertLines, Find, and DeleteLines methods. These methods process both standard and class modules, including standalone class modules and report and form class modules. These are a subset of the methods and properties that support programmatically managing module content.
You use the InsertLines method with a Module object to insert one or more lines into the module. Module line numbers start with 1 and extend through the CountOfLines property value for the module. The method takes a line number and a string argument. If you need to insert multiple lines into a module, add vbCrLf constants into the string expression representing the method's string argument. When you insert lines with this method, it moves down the remaining lines in the module.
The Find method searches for a text string in a module. It returns a value of True if it finds the search text, and it returns False otherwise. If you know precisely where some text is, you can specify a starting line and column and an ending line and column. If you do not know where some search text resides in a module, leave the text position arguments blank and the function will return the values of the search text in the module. You can also designate pattern searches and case-restrictive searches.
The DeleteLines method removes one or more lines of text from a module. The method takes two arguments: a start line and the total number of lines to remove from a module. You can use the DeleteLines method in combination with the Find method. You use the Find method to search for text in a module. You can then base the invocation of the DeleteLines method on the return value from the Find method.
The procedures below combine the AllModules and Modules collections to edit the text in a collection of modules. Specifically, they insert a comment line at the beginning of each module, proclaiming it a standard module or a class module. The EnumerateAllModulestoInsert procedure loops through the members of the AllModules collection and calls the other procedure, which actually updates the target modules. Since the InsertIntoModules procedure requires an open module, the first procedure opens the module if it is not already open. Then, when the second procedure returns control to the first one, it closes the module again to restore its initial state.
Sub EnumerateAllModulestoInsert() Dim obj1 As AccessObject 'Loop through AllModules members. 'If module is open, call sub to insert lines; 'else open module first, then close afterwards. For Each obj1 In Application.CurrentProject.AllModules If obj1.IsLoaded = True Then InsertIntoModules obj1.Name Else DoCmd.OpenModule obj1.Name InsertIntoModules obj1.Name DoCmd.Close acModule, obj1.Name, acSaveYes End If Next obj1 End Sub Sub InsertIntoModules(modname) Dim strType As String, mod1 As Module Set mod1 = Modules(modname) 'Detect module type to determine which 'string to insert. If mod1.Type = 0 Then strType = "'Standard Module" Else strType = "'Class Module" End If mod1.InsertLines 1, strType Set mod1 = Nothing End Sub |
The InsertIntoModules procedure accepts a single argument—the name of the module to edit. It performs no iteration because the first procedure calls it once for each member in the AllModules collection. The procedure begins by setting a reference to the module named in the passed argument. Then it determines the type of module to which the reference points and sets a string variable to a comment naming the module type. After determining the text to insert, the procedure invokes the InsertLines method for the referenced module.
The following two procedures delete a line from a procedure. In fact, they remove the line added by the preceding pair of procedures. The design of these next two procedures is flexible enough so that you can easily extend them to accommodate the deletion of multiple selected lines from any set of modules.
The procedures follow the same general logic as the preceding pair, with one major difference: this pair uses the Find and DeleteLines methods to remove text instead of the InsertLines method. The Find method is often critical when you prepare to use the DeleteLines method because the Find method lets your code determine whether some text is there before it deletes any content. In this instance, the Find method looks for the word Module in the first 40 characters of the first line. The DeletefromModules procedure invokes the DeleteLines method to delete one line starting with the first line in the module. The DeleteLines method removes lines unconditionally. However, you can manually invoke the Undo Delete function to restore removed text.
Sub EnumerateAllModulestoDelete() Dim obj1 As AccessObject, dbs As Object Dim mod1 As Module, frm1 As Form 'Loop through AllModules members. 'If module is open, call sub to delete line; 'else open module first, then close afterwards. For Each obj1 In Application.CurrentProject.AllModules If obj1.IsLoaded = True Then DeletefromModules obj1.Name Else DoCmd.OpenModule obj1.Name DeletefromModules obj1.Name DoCmd.Close acModule, obj1.Name End If Next obj1 End Sub Sub DeletefromModules(modname) Dim mod1 As Module Set mod1 = Modules(modname) 'Delete first line if first 40 characters 'contain "Module". If mod1.Find("Module", 1, 1, 1, 40) = True Then mod1.DeleteLines 1, 1 End If Set mod1 = Nothing End Sub |
The following two procedures insert a line at the beginning of each form class module with the comment that it is a class module. Instead of looping through the AllModules collection, the first procedure loops through the AllForms collection. For each member of the AllForms collection, it calls the InsertIntoForms procedure.
This second procedure assesses whether the passed form name is a class module. If it is, the procedure sets a reference to the module behind the form. This step exposes that module. The procedure closes by inserting the comment line into the module and setting the reference to Nothing to free its resources.
Sub EnumerateAllFormsToInsert() Dim obj1 As AccessObject 'Loop through AllForms members; 'if form is loaded invoke module to insert line, 'else open form first and then close afterwards. For Each obj1 In Application.CurrentProject.AllForms If obj1.IsLoaded Then InsertIntoForms obj1.Name Else DoCmd.openform obj1.Name InsertIntoForms obj1.Name DoCmd.Close acForm, obj1.Name, acSaveYes End If Next obj1 End Sub Sub InsertIntoForms(frmname) Dim mod1 As Module, strType As String 'If Form has module, set reference to it 'and insert line into the module. 'Free reference resource when done. If Forms(frmname).HasModule = True Then Set mod1 = Forms(frmname).Module strType = "'Form Class Module" mod1.InsertLines 1, strType Set mod1 = Nothing End If End Sub |
The two procedures below remove the Class Module comment line from the first line of modules behind forms. As you can see, this pair's design mimics critical elements from the preceding pairs of procedures for inserting and deleting lines. This pair iterates through the AllForms collection, like the pair that added a comment line to the beginning of all form class modules in a project.
However, the second procedure in this pair uses the Find and DeleteLines methods to remove the first line in a module if it contains the word Module in the first 40 characters of its first line. This resembles the procedure for deleting lines from the Modules collection.
Sub EnumerateAllFormstoDelete() Dim obj1 As AccessObject 'Loop through AllForms members; 'if form is loaded invoke module to remove line, 'else open form first and then close afterwards. For Each obj1 In Application.CurrentProject.AllForms If obj1.IsLoaded Then DeletefromForms obj1.Name Else DoCmd.openform obj1.Name DeletefromForms obj1.Name DoCmd.Close acForm, obj1.Name, acSaveYes End If Next obj1 End Sub Sub DeletefromForms(frmname) Dim mod1 As Module, strType As String 'If form has module, then check contents of first line 'for "Module", and delete the first line if it is present. 'Free module reference resource when done. If Forms(frmname).HasModule = True Then Set mod1 = Forms(frmname).Module If mod1.Find("Module", 1, 1, 1, 40) = True Then mod1.DeleteLines 1, 1 End If Set mod1 = Nothing End If End Sub |