Mark A Matte
markamatte at hotmail.com
Tue Apr 8 09:31:43 CDT 2008
Roz, I found this online when I started my project. I have NOT used it yet...but it seems to be related to yours. Also, this code stores the data in a table...so for your future wishes...you could display the original and your changes. Good luck, Mark A. Matte '********* Code Starts Here ******** Option Compare Database Option Explicit Public Function EnumerateModules(strPath As String, strPassWord As String, Optional bolEmptytable As Boolean = True) As Boolean '------------------------------------------------------------------------------ 'Purpose: Go through all of the Modules in the specified database and put them ' into a table, creating the table if it does not exist. 'Parameters: ' strDatabasePath: The full path of the database you wish to enumerate; ' "" if you want the current database 'Sets: Puts all information into the table 'tblModules'. If it is not there, ' create the table 'Returns: Boolean value telling if it finished correctly, or there was an error. 'Author: Stan Paszt 'Created: 08/10/2001 'Modified: '------------------------------------------------------------------------------ 'Changes by Gary Walter 10/3/2001 '1) Added automation to always open another instance of "OtherDB." '2) Expects full path to OtherDB even if same db as this one. '3) Changed some fields in tblModules where info from OtherDB is stored. '4) Added password parameter in case OtherDB secured. '5) Now assumes tblModules exist. '6) Added code to properly handle Property LET/GET/SET stmts. '------------------------------------------------------------------------------ On Error GoTo ERR_EnumerateModules Dim OtherDB As database Dim strUserName As String Dim strPass As String Dim oAcc As Access.Application Dim dbCurrent As database Dim RS As Recordset Dim doc As Document, rpt As Report, frm As Form Dim mdl As Module, bolIsLoaded As Boolean, strDocName As String Dim lngCount As Long, lngR As Long, intProcOrder As Integer Dim lngCountDecl As Long, intI As Integer Dim lngI As Long, lngCountProcLines As Long Dim strProcName As String, strProcLines As String Dim strModuleType() As String, intMT As Integer Dim objTemp As Object, intModuleType As Integer Dim strDBName As String, strDBPath As String Dim strDrive As String, strDir As String, strFName As String, strExt As String Dim varReturn As Variant Dim lngOldProcType As Long, strOldProcName As String, strFinalProcName As String DoCmd.Hourglass True 'clear table that will contain new module info DoCmd.SetWarnings False If bolEmptytable = True Then DoCmd.RunSQL ("Delete * from tblModules") End If DoCmd.SetWarnings True ReDim strModuleType(0 To 2) strModuleType(0) = "Modules" strModuleType(1) = "Forms" strModuleType(2) = "Reports" Call SplitPath(strPath, strDrive, strDir, strFName, strExt) strDBPath = strDrive & strDir strDBName = strFName & "." & strExt 'open recordset to tblModules in THIS database Set dbCurrent = CurrentDb() Set RS = dbCurrent.OpenRecordset("tblModules") 'open OTHER database Set oAcc = New Access.Application Set OtherDB = oAcc.DBEngine.OpenDatabase(strPath, False, False, ";PWD=" & strPassWord) oAcc.OpenCurrentDatabase strPath intProcOrder = 0 'Move through the modules For intMT = 0 To 2 Step 1 For Each doc In OtherDB.Containers(strModuleType(intMT)).Documents strDocName = doc.Name Select Case strModuleType(intMT) Case "Modules" intModuleType = acModule Case "Forms" intModuleType = acForm Case "Reports" intModuleType = acReport End Select bolIsLoaded = IsObjectOpen(intModuleType, strDocName) 'you can't open the module if it's already open. If bolIsLoaded = False Then Select Case intModuleType Case acModule oAcc.DoCmd.OpenModule doc.Name Set objTemp = oAcc.Modules(doc.Name) Case acForm oAcc.DoCmd.OpenForm strDocName, acDesign, , , acFormReadOnly, acWindowNormal Set objTemp = oAcc.Forms(strDocName).Module Case acReport oAcc.DoCmd.OpenReport strDocName, acViewDesign Set objTemp = oAcc.Reports(doc.Name).Module End Select Else Select Case intModuleType Case acModule Set objTemp = Modules(doc.Name) Case acForm Set objTemp = Forms(doc.Name).Module Case acReport Set objTemp = Reports(doc.Name).Module End Select End If 'get number of lines in this module lngCount = objTemp.CountOfLines 'Declarations 'find out how many lines in Declaration section lngCountDecl = objTemp.CountOfDeclarationLines 'get code lines for Declaration section strProcLines = objTemp.Lines(1, lngCountDecl) Do Until (Asc(Left(strProcLines, 1)) <> 13 And Asc(Left(strProcLines, 1)) <> 10 _ And Asc(Left(strProcLines, 1)) <> 32) strProcLines = Mid(strProcLines, 2) Loop Do Until (Asc(Right(strProcLines, 1)) <> 13 And Asc(Right(strProcLines, 1)) <> 10 _ And Asc(Right(strProcLines, 1)) <> 32) strProcLines = Mid(strProcLines, 1, Len(strProcLines) - 1) Loop With RS .AddNew !DatabaseName = strDBName !databasepath = strDBPath !ModuleName = objTemp.Name !CodeLinesCount = lngCount !ModuleType = objTemp.Type !ProcedureName = "Declarations" !ProcedureLines = strProcLines !ProcedureLinesCount = lngCountDecl !ProcedureOrder = intProcOrder .Update End With strOldProcName = "Declarations" 'Check to see if there is anything else after the declarations section 'Are there more lines in module than just the lines of Declaration? If lngCount> lngCountDecl Then 'start at first line after Declaration section intI = lngCountDecl + 1 intProcOrder = intProcOrder + 1 '***** Get Name of Proc of this line ********* 'inti specifies the number of a line in the module. 'When return from getting the ProcOfLine, 'lngR will specify the type of procedure: ' vbext_pk_Get lngR=3 A Property Get proc ' vbext_pk_Let lngR=1 A Property Let proc ' vbext_pk_Proc lngR=0 A Sub or Function proc ' vbext_pk_Set lngR=2 A Property Set proc strProcName = objTemp.ProcOfLine(intI, lngR) 'save proc name so will know when reach line with new proc strOldProcName = strProcName 'save type of proc for next compare (to distinguish same-name Property stmts) lngOldProcType = lngR 'If proc was a property stmt, add type to procname that will save in tblModules Select Case lngOldProcType Case vbext_pk_Proc strFinalProcName = strProcName Case vbext_pk_Get strFinalProcName = strProcName & " [Property Get]" Case vbext_pk_Let strFinalProcName = strProcName & " [Property Let]" Case vbext_pk_Set strFinalProcName = strProcName & " [Property Set]" End Select '****** update progress display in status bar ***************** varReturn = SysCmd(acSysCmdSetStatus, "Processing " _ & strModuleType(intMT) & " " & doc.Name & ".... Procedure " & strFinalProcName) 'get the number of lines for this proc lngCountProcLines = objTemp.ProcCountLines(strProcName, lngR) 'get the code lines for this proc strProcLines = objTemp.Lines(intI, lngCountProcLines) 'strip CRLF's and SPACES from left side of codelines Do Until (Asc(Left(strProcLines, 1)) <> 13 And Asc(Left(strProcLines, 1)) <> 10 _ And Asc(Left(strProcLines, 1)) <> 32) strProcLines = Mid(strProcLines, 2) Loop 'strip CRLF's and SPACES from right side of codelines Do Until (Asc(Right(strProcLines, 1)) <> 13 And Asc(Right(strProcLines, 1)) <> 10 _ And Asc(Right(strProcLines, 1)) <> 32) strProcLines = Mid(strProcLines, 1, Len(strProcLines) - 1) Loop 'for html coding (you probably want to delete the following) 'if have a Proc (not a Property stmt), 'add "Sub" or "Function" to start of proc name If lngOldProcType = vbext_pk_Proc Then If Left(strProcLines, 15) = "Public Function" _ Or Left(strProcLines, 16) = "Private Function" Then strFinalProcName = "Function " & strFinalProcName Else strFinalProcName = "Sub " & strFinalProcName End If End If With RS .AddNew !DatabaseName = strDBName !databasepath = strDBPath !ModuleName = objTemp.Name !CodeLinesCount = lngCount !ModuleType = objTemp.Type !ProcedureName = strFinalProcName !ProcedureLines = strProcLines !ProcedureLinesCount = lngCountProcLines !ProcedureOrder = intProcOrder .Update End With 'Go through the rest of the module, enumerating the procedures For lngI = intI To lngCount '***** Get Name of Proc of this line ********* 'inti specifies the number of a line in the module. 'When return from getting the ProcOfLine, 'lngR will specify the type of procedure: ' vbext_pk_Get lngR=3 A Property Get proc ' vbext_pk_Let lngR=1 A Property Let proc ' vbext_pk_Proc lngR=0 A Sub or Function proc ' vbext_pk_Set lngR=2 A Property Set proc strProcName = objTemp.ProcOfLine(lngI, lngR) 'see if ProcName for this line has changed 'or ProcName is the same but have different ProcType If (strProcName <> strOldProcName) _ Or ((strProcName = strOldProcName) And (lngR <> lngOldProcType)) Then intProcOrder = intProcOrder + 1 'save proc name so will know when reach line with new proc strOldProcName = strProcName 'save type of proc for next compare (to distinguish same-name Property stmts) lngOldProcType = lngR 'If proc was a property stmt, add type to procname that will save in tblModules Select Case lngOldProcType Case vbext_pk_Proc strFinalProcName = strProcName Case vbext_pk_Get strFinalProcName = strProcName & " [Property Get]" Case vbext_pk_Let strFinalProcName = strProcName & " [Property Let]" Case vbext_pk_Set strFinalProcName = strProcName & " [Property Set]" End Select '****** update progress display in status bar ***************** varReturn = SysCmd(acSysCmdSetStatus, "Processing " _ & strModuleType(intMT) & " " & doc.Name & ".... Procedure " & strFinalProcName) 'get the number of lines for this proc lngCountProcLines = objTemp.ProcCountLines(strProcName, lngR) 'get the code lines for this proc strProcLines = objTemp.Lines(lngI, lngCountProcLines) 'strip CRLF's and SPACES from left side of codelines Do Until (Asc(Left(strProcLines, 1)) <> 13 And Asc(Left(strProcLines, 1)) <> 10 _ And Asc(Left(strProcLines, 1)) <> 32) strProcLines = Mid(strProcLines, 2) Loop 'strip CRLF's and SPACES from right side of codelines Do Until (Asc(Right(strProcLines, 1)) <> 13 And Asc(Right(strProcLines, 1)) <> 10 _ And Asc(Right(strProcLines, 1)) <> 32) strProcLines = Mid(strProcLines, 1, Len(strProcLines) - 1) Loop 'for html coding (you probably want to delete the following) 'if have a Proc (not a Property stmt), 'add "Sub" or "Function" to start of proc name If lngOldProcType = vbext_pk_Proc Then If Left(strProcLines, 15) = "Public Function" _ Or Left(strProcLines, 16) = "Private Function" Then strFinalProcName = "Function " & strFinalProcName Else strFinalProcName = "Sub " & strFinalProcName End If End If With RS .AddNew !DatabaseName = strDBName !databasepath = strDBPath !ModuleName = objTemp.Name !CodeLinesCount = lngCount !ModuleType = objTemp.Type !ProcedureName = strFinalProcName !ProcedureLines = strProcLines !ProcedureLinesCount = lngCountProcLines !ProcedureOrder = intProcOrder .Update End With End If 'look at next line in code module Next lngI 'finished getting all info from this module '/* End of If lngCount> lngCountDecl Then End If 'reinit vars to get a new module intProcOrder = 0 lngCountProcLines = 0 strProcLines = " " No_Module: 'close object that contained last code module Set objTemp = Nothing oAcc.DoCmd.close intModuleType, doc.Name, acSaveNo 'go get another code module of the same module type Next 'doc 'have gotten all code modules for this type 'so start getting another type of module Next 'intMT '****** update progress display in status bar ***************** varReturn = SysCmd(acSysCmdClearStatus) MsgBox "Processing Complete" EnumerateModules = True EXIT_EnumerateModules: oAcc.CloseCurrentDatabase OtherDB.close: Set OtherDB = Nothing RS.close: Set RS = Nothing dbCurrent.close: Set dbCurrent = Nothing DoCmd.Hourglass False DoCmd.SetWarnings True Exit Function ERR_EnumerateModules: EnumerateModules = False MsgBox Err & ": " & Err.Description, vbCritical, _ "Error in function basModuleCode.EnumerateModules" Resume EXIT_EnumerateModules End Function Sub SplitPath(strPath As String, _ strDrive As String, _ strDir As String, _ strFName As String, _ strExt As String) Dim intPos As Integer ' current position of \ Dim intLast As Integer ' last position of \ Dim strTemp As String If Len(strPath) < 3 Or IsNull(strPath) Then Exit Sub strDrive = Left(strPath, 2) 'find position of last "\" intPos = InStr(strPath, "\") While intPos <> 0 intLast = intPos intPos = InStr(intPos + 1, strPath, "\") Wend If intLast> 3 Then strDir = Mid(strPath, 3, intLast - 3) Else strDir = "" End If 'get FName and Ext strTemp = Mid(strPath, intLast + 1) intPos = InStr(strTemp, ".") If intPos <> 0 Then 'found a "." strExt = Mid(strTemp, intPos + 1) strFName = Left(strTemp, intPos - 1) Else 'did not find "." so no extension strExt = "" strFName = strTemp End If End Sub Private Sub Create_tblModules_Table() Dim tdf As TableDef Dim idxPrimary As index Set tdf = CurrentDb.CreateTableDef("tblModules") With tdf .Fields.Append .CreateField("DatabaseName", dbText, 50) .Fields.Append .CreateField("DatabasePath", dbText, 255) .Fields.Append .CreateField("ModuleName", dbText, 50) .Fields.Append .CreateField("ProcedureOrder", dbLong) .Fields.Append .CreateField("ProcedureName", dbText, 50) .Fields.Append .CreateField("ProcedureLines", dbMemo) .Fields.Append .CreateField("ProcedureLinesCount", dbLong) .Fields.Append .CreateField("CodeLinesCount", dbLong) .Fields.Append .CreateField("ModuleType", dbLong) End With CurrentDb.TableDefs.Append tdf Set tdf = Nothing End Sub '******** Code Ends Here ******** _________________________________________________________________ Going green? See the top 12 foods to eat organic. http://green.msn.com/galleries/photos/photos.aspx?gid=164&ocid=T003MSN51N1653A