Outil d'analyse de code VBA
Bonjour
Un module qui répertorie toutes les procédures et tous les appels à procédure.
Il suffit de copier / coller le code dans un module standard dans le classeur à analyser et d'exécuter la "sub Main". Cela va créer deux feuilles.
- Liste procs comme son nom l'indique liste toutes les procédures du classeur.
- Liste appels qui devinez quoi liste tous les appels à chaque procédure avec le nom de la procédure, le nom du module appelant, le nom de la procédure appelante, le numéro de ligne ou commence la procédure appelante, le numéro de ligne de l'appel dans la pprocédure appelante, le nom du module où se trouve la procédure appelée. et l'index de ligne de début de la procédure appelée.
Voila, j'espère que cela pourra être utile…
Option Explicit
Sub Main()
Call ListeProcedures
Call ListeAppels
End Sub
Public Sub ListeProcedures()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Dim Component As Object
Dim Name As String
Dim Kind As Long
Dim Index As Long
Dim tmp$, n!
Dim i!, fExist!
Dim adr$
' Crée la feuille Liste procédures
For i = 1 To ActiveWorkbook.Sheets.Count
If Worksheets(i).Name = "liste procs" Then
Worksheets("liste procs").Delete
Exit For
End If
Next i
If fExist = 0 Then
Sheets.Add.Name = "liste procs"
Range("A1:C1").Value = Array("nom Module", "nom Procédure", "Index")
Range("A1:C1").Font.Bold = True
Range("A1:C1").Borders.Value = 1
End If
' Liste toutes les procédures du classeur
For Each Component In Application.VBE.ActiveVBProject.VBComponents
With Component.CodeModule
Index = .CountOfDeclarationLines + 1
Do While Index < .CountOfLines
Name = .ProcOfLine(Index, Kind)
tmp = Component.Name & "." & Name & "." & Index
Sheets("liste procs").Range("A" & n + 2 & ":C" & n + 2).Value = Split(tmp, ".")
n = n + 1
Index = .ProcStartLine(Name, Kind) + .ProcCountLines(Name, Kind) + 1
Loop
End With
Next Component
Range("A:B").EntireColumn.AutoFit
With Sheets("liste procs")
adr = .[A1].CurrentRegion.Address
.ListObjects.Add(xlSrcRange, .Range(adr), , xlYes).Name = "tb_procs"
.ListObjects("tb_procs").TableStyle = "TableStyleLight14"
End With
' Worksheets("liste procs").Visible = False
Application.DisplayAlerts = False
Application.ScreenUpdating = True
End Sub
Sub ListeAppels()
Dim nomModule$, NomMacro$
Dim tbProcs()
Dim i%, j%, k%
Dim Debut!, Lignes!, n!, x!, fExist!
Dim texte$, tmp$, adr$, source$, id$
Dim dc As Object, cle
' Crée la feuille Liste appels
For i = 1 To ActiveWorkbook.Sheets.Count
If Worksheets(i).Name = "liste appels" Then
Application.DisplayAlerts = False
Worksheets("liste appels").Delete
Application.DisplayAlerts = True
Exit For
End If
Next i
If fExist = 0 Then
Sheets.Add.Name = "liste appels"
Range("A1:G1").Value = Array("nom Procédure", "Module appelant", "Procédure appelante", _
"Début", "Num ligne", "Localisation procédure", "Index")
Range("A1:G1").Font.Bold = True
Range("A1:G1").Borders.Value = 1
End If
tbProcs = Range("tb_procs").Value2
Set dc = CreateObject("Scripting.dictionary")
For i = 1 To UBound(tbProcs)
dc(tbProcs(i, 2)) = ""
Next i
For Each cle In dc.keys
For i = 1 To UBound(tbProcs)
nomModule = tbProcs(i, 1)
NomMacro = tbProcs(i, 2)
If nomModule <> "Mod_Analyse_Code" Then
With ThisWorkbook.VBProject.VBComponents(nomModule).CodeModule
Debut = .ProcStartLine(NomMacro, 0)
Lignes = .ProcCountLines(NomMacro, 0)
End With
For j = Debut + 2 To Lignes + Debut
With ThisWorkbook.VBProject.VBComponents(nomModule).CodeModule
texte = .Lines(j, 1)
If InStr(1, texte, cle) > 0 Then
texte = Trim(texte)
For k = 1 To UBound(tbProcs)
If tbProcs(k, 2) = cle Then
source = tbProcs(k, 1): id = tbProcs(k, 3)
End If
Next k
tmp = cle & "|" & nomModule & "|" & NomMacro & "|" & Debut & "|" & j - Debut & "|" & source & "|" & id
Sheets("liste appels").Range("A" & n + 2 & ":G" & n + 2).Value = Split(tmp, "|")
n = n + 1
End If
End With
Next j
Else
End If
Next i
Next cle
Range("A:G").EntireColumn.AutoFit
With Sheets("liste appels")
adr = .[A1].CurrentRegion.Address
.ListObjects.Add(xlSrcRange, .Range(adr), , xlYes).Name = "tb_appels"
.ListObjects("tb_appels").TableStyle = "TableStyleLight12"
End With
End Sub
Vous pouvez aussi télécharger le fichier ci dessous et changer l'extension en .bas pour l'importer directement dans le classeur à analyser.
Si vous trouvez des bugs ou des améliorations à apporter merci de m'en faire part.
Merci Gabin37 en effet je n'avais pas pensé à cette condition dans mon mode d'emploi
Un léger défaut que je viens de découvrir mais qui n'a pas de grave conséquence.
Si plus d'une ligne vide sépare deux procédures dans un module le programme identifie le nom de la procédure comme un appel à celle-ci. C'est pas grave mais ça peut être source d'incompréhension. On pourrait passer du temps à chercher un appel qui n'existe pas…
Pareil s'il n'y a pas de ligne vide entre deux procédures, sauf qu'il attribue l'appel à la procédure du dessus.
Donc dans l'idéal une et une seule ligne vide entre deux procédures.
Correctif au défaut mentionné plus tôt.
Dans la "Sub ListeAppels()" remplacer la ligne
If InStr(1, texte, cle) > 0 Thenpar
If InStr(1, texte, cle) > 0 And _
InStr(1, texte, "Sub ") = 0 And _
InStr(1, texte, "PrivateSub ") = 0 And _
InStr(1, texte, "PublicSub ") = 0 And _
InStr(1, texte, "Function ") = 0 And _
InStr(1, texte, "PrivateFunction ") = 0 And _
InStr(1, texte, "PublicFunction ") = 0 Thenet tout rentre dans l'ordre. Jusqu'à preuve du contraire bien sûr.
Bonjour,
Excel 2019
Nouveau sur le site je découvre l'outil d'analyse de code VBA
à l’exécution j'ai le message d’erreur suivant
Erreur d’exécution 35
Sub ou Function non définie
sur la ligne suivante: Debut = .ProcStartLine(NomMacro, 0) dans la procédure ListeAppels
J'ai oublié quelque chose ?
Merci du retour,
Joindre le fichier dur car il y a beaucoup de données confidentielles et faire le ménage avant
Par contre je viens de faire un essai sur d'autres fichier pas de PB c'est bon, apparemment c'est juste celui-là. Pourquoi ?
Je cherche
Un outil pour anonymiser les données. Pas bien finalisé côté ergonomie
Bonjour,
merci pour le classeur, je vrais cela plus tard car pas beaucoup de temps pour l'instant

