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.

Bonjour yal_excel,

De mon coté la macro fonctionne.

Je voudrais juste préciser si certains ont l'erreur "L'accès par programme au projet VB n'est pas fiable"

On peut résoudre l'erreur en cochant l'option ci-dessous:

image

A+

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 Then

par

            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 Then

et 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 ?

Bonjour

Vérifiez que les références nécessaires soient activées.

capture d ecran 2021 11 10 171039

Si c'est possible joignez votre fichier que je puisse voir ce qu'il se passe.

Cordialement

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

Rechercher des sujets similaires à "outil analyse code vba"