XL 2016 Analyse de Code VBA : Variables inutilisées

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

crocrocro

XLDnaute Impliqué
Bonjour à tous,

je n'ai pas réussi à trouver,
- soit un logiciel gratuit (le logiciel MZ-Tools dans sa version actuelle V8 est payant, à l'essai pendant 30 jours),
- soit un code dans les forums
qui permette de lister les variables, constantes, procédures inutilisées dans un projet VBA, en tenant compte évidemment de la portée des déclarations.

Quelqu'un a peut-être la solution.
Merci d'avance pour vos retours
.
 
Solution
Bonsoir,

en pj mon fichier de bricolage.

[EDIT du 13/03] : Il ne répond pas totalement à ma demande mais je m'en contenterai.
Il détecte bien (sauf erreur de ma part) toutes les variables inutilisées et seulement celles-là, avec le module de test "Module_Test" du fichier. Il tient également compte des paramètres des procédures mono ou multi-lignes (voir post précédent).
RubberDuck, seule proposition que j'ai pu testée, commet des erreurs (voir posts précédents).
En attendant mieux, je mets mon fichier comme solution.

Le contenu du fichier
  • La feuille "Variables Inutilisées"
Le bouton "Analyser Variables inutilisées" exécute la macro LancerAnalyseCodeVarInu pour analyser le module de la ligne...​
Bonjour crocrocro

Mz-Tools est certes payant environ 75€, mais contrairement à beaucoup d'éditeur c'est une licence perpétuelle
Il est clair que si vous n'avez qu'un projet à faire, ce n'est pas intéressant

Perso, j'ai investi cela fait des années déjà et j'ai bien fait
 
Bonjour crocrocro

Mz-Tools est certes payant environ 75€, mais contrairement à beaucoup d'éditeur c'est une licence perpétuelle
Il est clair que si vous n'avez qu'un projet à faire, ce n'est pas intéressant

Perso, j'ai investi cela fait des années déjà et j'ai bien fait
Merci pour le retour.
Je compte l'utiliser pour tous mes fichiers mais seulement pour le besoin que j'ai indiqué
lister les variables, constantes, procédures inutilisées dans un projet VBA, en tenant compte évidemment de la portée des déclarations.
Si pas de solution externe, je retrousserai mes manches. Ce sera du bricolage maison 🛠️
 
Bonsoir,

Fais un tour ICI, MzTools3 est normalement suffisant. Mais il faut bien vérifier cette partie "procédures inutilisées dans un projet VBA".
Bonsoir, Cathodique, merci pour le retour.
As-tu utilisé cette version ? des problèmes ?
Je ne comprends pas le sens de ta remarque
Mais il faut bien vérifier cette partie "procédures inutilisées dans un projet VBA".

Bonjour à tous,
La solution est peut être , et totalement gratuite. 😉
Bonsoir Valtrase, merci également.
j'avais déjà vu cet outil (rubberduckvba) mais j'ai lu des avis qui indiquaient la présence de bugs.
 
Bonjour,

As-tu utilisé cette version ? des problèmes ?
Je ne comprends pas le sens de ta remarque
Oui, je l'ai installé depuis assez longtemps. Depuis qu'il était proposé sur son site officiel. (voir images qui montre qu'il est installé sur ma machine).

Quant à ma remarque, lorsqu'il s'agit de détecter des fonctions ou procédures qui ne sont pas utilisées, il n'est pas fiable.
Et ce, surtout lorsqu'il s'agit de formulaires. Il te dira par exemple que la procédure Private Sub CommandButton1__Click(), ce bouton sert par exemple à fermer le formulaire. Après examen du code, il te dira que la procédure n'est pas utilisée.
Par contre, pour les variables non utilisées, c'est ok.

Bonne journée.
 

Pièces jointes

  • MzTools.jpg
    MzTools.jpg
    199.2 KB · Affichages: 16
  • MzTools2.jpg
    MzTools2.jpg
    36.5 KB · Affichages: 15
Bonjour à tous,
Vous l'utilisez vous Rubberduck 🤔
Perso, j'avais essayé mais il me faisait planter lamentablement Excel 😱
Perso je l'utilise sous Windows 10 64bits et Office 365 en 32bits. en complément de MZ-Tools.
000064.png

Il est vrai qu'il faut de la ressource, et que quelques fois il plante, mais c'est souvent au fait que le classeur ne soit pas totalement parfait.
Par contre, j'ai rencontré plus de problèmes sur le poste qui est sous Windows 11 64bits et Office 365 64bits
Ils sont sur le point de sortir une nouvelle version avec une toute nouvelle architecture.
 
Bonjour,


Oui, je l'ai installé depuis assez longtemps. Depuis qu'il était proposé sur son site officiel. (voir images qui montre qu'il est installé sur ma machine).

Quant à ma remarque, lorsqu'il s'agit de détecter des fonctions ou procédures qui ne sont pas utilisées, il n'est pas fiable.
Et ce, surtout lorsqu'il s'agit de formulaires. Il te dira par exemple que la procédure Private Sub CommandButton1__Click(), ce bouton sert par exemple à fermer le formulaire. Après examen du code, il te dira que la procédure n'est pas utilisée.
Par contre, pour les variables non utilisées, c'est ok.

Bonne journée.

Bonjour Valtrase,
Vous l'utilisez vous Rubberduck 🤔
Perso, j'avais essayé mais il me faisait planter lamentablement Excel 😱

Bonsoir tout le monde,
Mon PC est une 2CV, je voyage donc léger et je pense qu'une Bouée Canard comme le propose Valtrase 😉 ne rentrerait pas dans le coffre, ni sans doute la MZ3.

Mon besoin étant limité, j'ai commencé à bricoler un code qui à l'heure actuelle me permet de :
- Lister par un Debug.Print les variables inutilisées (déclarées Dim) d'un module
- De manière optionnelle de "taguer" la ligne de déclaration de chaquevariable inutilisée (commentaire en bout de ligne)

Le Code (macro à appeler AnalyseCodeVarInu)
VB:
Option Explicit
Dim NomModule As String
Dim NomProc As String
Dim TypeProcedure As vbext_ProcKind
Dim LigneStartProc As Long
Dim LigneBodyProc As Long
Dim NbLignesProc As Long
Dim CodeContenu As String
Dim CodeDeclaration As String
Dim ListeVar As String
Dim NbInutile As Integer
Const TAG = " ' VARIABLE INUTILE"
Dim CommentaireTag As String

Sub AnalyseCodeVarInu()
' Fonctionne pour les Variables déclarées Dim dans le Module
'  Il y aura besoin de code supplémentaire pour des variables :
'       Public, Private, Static, Array, Type ... End Type
Dim Titre As String
Dim Message As String
Dim Debut As Long
Dim ObjModule As Object
Dim TagLigne As Boolean ' on marque les lignes Dim inutilisée

    Titre = "Analyse des Variables inutilisées"
    Message = "Souhaitez-vous ajouter le commentaire <" & TAG & "> sur la ligne de déclaration des variables inutilisées ?"
    If MsgBox(Message, vbYesNo, Titre) = vbYes Then
        TagLigne = True
        CommentaireTag = TAG & " (" & Now & ")"
    Else
        TagLigne = False
    End If

    NbInutile = 0
    ' pour le moment sur le classeur courant
    For Each ObjModule In ThisWorkbook.VBProject.VBComponents
        NomModule = ObjModule.Name
        ' pour le moment test sur seulement un module
        If NomModule = "Module6_PourVar" Then
        
            With ThisWorkbook.VBProject.VBComponents(NomModule).CodeModule
            
                'Déclarations du Module
                '----------------------
                ListeVar = ""
                NomProc = ""
                LigneStartProc = 1
                LigneBodyProc = 1
                NbLignesProc = .CountOfLines - .CountOfDeclarationLines
                NbLignesProc = .CountOfDeclarationLines
                If NbLignesProc > 0 Then
                    CodeDeclaration = .Lines(1, .CountOfDeclarationLines) & vbLf
                    CodeContenu = .Lines(1, .CountOfLines)
                    AnalyseCodeVarInuProcedure CodeDeclaration, CodeContenu, TagLigne
                End If
                Debug.Print "========================================================="
                Debug.Print "   Analyse du Module " & NomModule
                Debug.Print "========================================================="
                Debug.Print ListeVar
                Debug.Print
                
                ' Chaque Procédure
                '-----------------
                'positionnement après la partie Déclarations du Module
                ListeVar = ""
                Debut = .CountOfDeclarationLines + 1
                Do Until Debut >= .CountOfLines
                    NomProc = .ProcOfLine(Debut, TypeProcedure)
                    LigneStartProc = .ProcStartLine(NomProc, TypeProcedure)
                    LigneBodyProc = .ProcBodyLine(NomProc, TypeProcedure)
                    NbLignesProc = .ProcCountLines(NomProc, TypeProcedure)
                    CodeContenu = .Lines(LigneBodyProc, NbLignesProc)
                    AnalyseCodeVarInuProcedure CodeContenu, CodeContenu, TagLigne
                    If ListeVar <> "" Then
                        Debug.Print "--- Procédure " & NomProc & " ---"
                        Debug.Print ListeVar
                        Debug.Print
                    End If
                    ListeVar = ""
                    Debut = Debut + NbLignesProc + 1
                Loop
            End With
            
            Message = "Analyse du Code du Module " & NomModule & " terminée." & vbLf _
                    & NbInutile & " variables inutilisées." & vbLf _
                    & "Voir la fenêtre Exécution de l'éditeur VBE"
                    
            MsgBox Message, vbInformation, Titre
            
        End If
    Next ObjModule

End Sub
Sub AnalyseCodeVarInuProcedure(pCodeDeclaration As String, pCodeContenu As String, pTagLigne As Boolean)

Dim TabCodeDeclaration() As String
Dim TabCodeContenu() As String
Dim ChaineDim As String
Dim TabDim() As String, ITabDim As Integer, ITabDim2 As Integer, ITabDim3 As Integer
Dim TabDimEc() As String, ITabDimEc As Integer
Dim ChaineSansCom As String
Dim TabSansCom() As String, ITabSansCom As Integer
Dim i As Integer, j As Integer
Dim LigneCourante As String
Dim Quoi As String
Dim ChaineW As String
Dim Pos As Long, Pos2 As Long
Dim Absent As Boolean
Dim Fin As Boolean
    ' Analyse variables (pour le moment seulement Dim)
    '-------------------
    Quoi = "Dim "
    
    ' Préparation des tableaux de déclarations Dim
    '---------------------------------------------
    TabCodeDeclaration = Split(pCodeDeclaration, vbLf)
    'la dernière ligne est vide
    ReDim Preserve TabCodeDeclaration(0 To UBound(TabCodeDeclaration) - 1)
    For i = LBound(TabCodeDeclaration) To UBound(TabCodeDeclaration)
        ' on enlève les espaces de gauche
        TabCodeDeclaration(i) = LTrim(TabCodeDeclaration(i))
        ' on enlève le saut de ligne
        If Len(TabCodeDeclaration(i)) <> 0 And i < UBound(TabCodeDeclaration) - LBound(TabCodeDeclaration) Then
            TabCodeDeclaration(i) = Left(TabCodeDeclaration(i), Len(TabCodeDeclaration(i)) - 1)
        End If
        If Left(LTrim(TabCodeDeclaration(i)), Len(Quoi)) = Quoi Then
            ' Ligne Dim
            If ChaineDim = "" Then ChaineDim = TabCodeDeclaration(i) Else ChaineDim = ChaineDim & vbLf & TabCodeDeclaration(i)
        End If
    Next i
    
    ' TabDim contient toutes les déclarations Dim : "Dim xxx"
    TabDim = Split(ChaineDim, vbLf)
    
    ' Tableau du contenu sans les lignes commentaires
    '---------------------------------------------
    ChaineSansCom = ""
    TabCodeContenu = Split(pCodeContenu, vbLf)
    For i = LBound(TabCodeContenu) To UBound(TabCodeContenu)
        If Len(TabCodeContenu(i)) <> 0 And i <> UBound(TabCodeContenu) Then TabCodeContenu(i) = Left(TabCodeContenu(i), Len(TabCodeContenu(i)) - 1)
        If Left(LTrim(TabCodeContenu(i)), Len(Quoi)) <> Quoi Then
            If Left(LTrim(TabCodeContenu(i)), 1) <> "'" Then
                If ChaineSansCom = "" Then ChaineSansCom = TabCodeContenu(i) Else ChaineSansCom = ChaineSansCom & vbLf & TabCodeContenu(i)
            End If
        End If
    Next i
    ' élimination des lignes commentaires
    TabSansCom = Split(ChaineSansCom, vbLf)
  
    ' Contrôle du contenu à partir des tableaux de déclarations Dim
    '--------------------------------------------------------------

    For ITabDim = LBound(TabDim) To UBound(TabDim)
        ' ici on éclate les déclarations multiples sur la même e lignes en x lignes
        TabDimEc = Filter(Split(Replace(Replace(TabDim(ITabDim), "Dim ", "Dim µ"), ", ", " µ")), "µ")
        For i = LBound(TabDimEc) To UBound(TabDimEc)
            TabDimEc(i) = Replace(TabDimEc(i), "µ", "")
            If InStr(TabDimEc(i), "(") <> 0 Then
                ' Variable Tableau
                '   -> pour détecter l'utilisation dans le code on testera "Var(" et "Var"
                TabDimEc(i) = Left(TabDimEc(i), InStr(TabDimEc(i), "(") - 1)
            End If
        Next i
        
        For ITabDimEc = LBound(TabDimEc) To UBound(TabDimEc)
            Absent = True
            For ITabSansCom = LBound(TabSansCom) To UBound(TabSansCom)
                Pos = InStr(TabSansCom(ITabSansCom), TabDimEc(ITabDimEc))
                If InStr(TabSansCom(ITabSansCom), TabDimEc(ITabDimEc)) <> 0 Then
                    ' on regarde si trouvé en dehors d'une zone commentaire
                    Pos2 = InStr(TabSansCom(ITabSansCom), "'")
                    If Pos2 <> 0 Then
                        ' on a trouvé le caractère ' sur la ligne
                        If ChaineEntreApostrophes(TabSansCom(ITabSansCom), "'") Then
                            'le caractère ' est encadré par "" -> ce n'est donc pas commentaire
                            'on regarde si variable encadré par ""
                            Absent = ChaineEntreApostrophes(TabSansCom(ITabSansCom), TabDimEc(ITabDimEc))
                            If Not Absent Then Exit For
                        End If
                    Else
                        'pas dans zone commentaire
                        'on regarde si encadré par ""
                        Absent = ChaineEntreApostrophes(TabSansCom(ITabSansCom), TabDimEc(ITabDimEc))
                        If Not Absent Then Exit For
                    End If
                End If
            Next ITabSansCom
            If Absent Then
                NbInutile = NbInutile + 1
                If pTagLigne Then
                    ' on marque la ligne Dim inutilisée
                    ' recherche du n° d'item de TabDim à partir de TabDimEc
                    For ITabDim2 = LBound(TabDim) To UBound(TabDim)
                        If InStr(TabDim(ITabDim2), TabDimEc(ITabDimEc)) <> 0 Then
                            ITabDim3 = ITabDim2
                            Exit For
                        End If
                    Next ITabDim2
                    
                    For i = LigneBodyProc To LigneBodyProc + NbLignesProc - 1
                        LigneCourante = ThisWorkbook.VBProject.VBComponents(NomModule).CodeModule.Lines(i, 1)
                        If TabDim(ITabDim3) = LTrim(LigneCourante) Then
                            ' on ajoute le tag
                            ' on remplace le Tag précédent s'il existe
                            Pos = InStr(LigneCourante, TAG)
                            If Pos <> 0 Then
                                LigneCourante = Left(LigneCourante, Pos - 1)
                            End If
                            LigneCourante = LigneCourante & CommentaireTag & " ---> " & TabDimEc(ITabDimEc)
                            ThisWorkbook.VBProject.VBComponents(NomModule).CodeModule.ReplaceLine Line:=i, String:=LigneCourante
                            Exit For
                        End If
                    Next i
                End If
                ' pour le Debug.Print
                If ListeVar = "" Then ListeVar = ListeVar & TabDimEc(ITabDimEc) Else ListeVar = ListeVar & vbLf & TabDimEc(ITabDimEc)
            End If
        Next ITabDimEc
    Next ITabDim
End Sub
Function ChaineEntreApostrophes(pChaine As String, pSousChaine As String) As Boolean
    'on regarde si encadré par ""
    Dim ChaineW As String
    Dim Pos As Long, Pos2 As Long
    Dim Absent As Boolean
    Dim Fin As Boolean

    ChaineEntreApostrophes = True
    
    Pos = InStr(pChaine, pSousChaine)
    Pos2 = InStr(pChaine, """")
    If Pos2 < Pos Then
        ' le premier " est situé avant, on va regarder où est le suivant
        ChaineW = Mid(pChaine, Pos2 + 1, Len(pChaine))
        Fin = False
        While Not Fin
            Pos = InStr(ChaineW, pSousChaine)
            Pos2 = InStr(ChaineW, """")
            Select Case True
                Case Pos = 0
                    ' Var non trouvée hors zone commentaire
                    Fin = True
                Case Pos2 = 0 And Pos <> 0
                    ' pas de 2ème "
                    ChaineEntreApostrophes = False
                    Fin = True
                Case Else
                    ' 2ème " avant ou après la variable -> on avance
                    ChaineW = Mid(ChaineW, Pos2 + 1, Len(ChaineW))
            End Select
        Wend
    Else
        ChaineEntreApostrophes = False
    End If
End Function

Le module pour tester (à nommer Module6_PourVar)
Code:
' Module6_PourVar
'----------------
Option Explicit
Dim xxx, yyy ',zzz
Dim Tab1() As String, sss
'Dim Tab2() As String
Dim iii
Dim ttt
Dim jjj '
'===================================================
Sub Procedure_1()
Dim VarInu As String 'même nom que dans Procedure_2 mais inutilisé ici
    With ThisWorkbook.VBProject
    End With
End Sub
Sub Procedure_2()
Dim VarInux As String
    Dim VarInu As String 'même nom que dans Procedure_1 mais utilisé ici
Dim iii As Long 'ici variable locale
    Dim jjj As Long 'ici variable locale
    Dim i As Long
    jjj = 0
    VarInu = ""
    For i = 1 To 10
    Next i
End Sub
Sub Procedure_3()
    Dim Tab2() As String 'VarInconnu0
    'Dim Tab3() As String
    Dim ItemTab1
    Dim ItemTab2
Dim LigneCourante As String, VarInconnu1
    Dim VarConnu1
    Dim VarConnu2
    Dim VarConnu3
Dim VarInconnu2
Dim VarInconnu3
Dim VarInconnu4
    'Dim VarInconnu5

    'VarInconnu2=0
    iii = 0
    LigneCourante = "xxxxxxxxxxxxxxx" & vbLf 'VarInconnu2
    LigneCourante = "xxxxxxxxxxxxxxx" & VarConnu1
    LigneCourante = "xxxxVarConnu2xxxxxxxx" & VarConnu2
    LigneCourante = "'xxxxVarConnu3xxxxxxxx" & VarConnu3
    LigneCourante = "xxxxVarInconnu2xxxxxxxx"
    LigneCourante = "xxxxVarInconnu3xxxVarInconnu3xxxxx"
    LigneCourante = "xxxxVarInconnu4xxxxxxxx" & "xxxxVarInconnu4xxxxxxxx"
    Tab1 = Filter(Split(LigneCourante, vbLf), "Dim")
    Tab2 = Filter(Split(Replace(Replace(ItemTab1, "Dim ", "Dim µ"), ", ", " µ")), "µ")
    For Each ItemTab2 In Tab2
    Next
End Sub

Le Debug.print correspondant

Code:
=========================================================
   Analyse du Module Module6_PourVar
=========================================================
xxx
yyy
sss
ttt

--- Procédure Procedure_1 ---
VarInu

--- Procédure Procedure_2 ---
VarInux
iii

--- Procédure Procedure_3 ---
VarInconnu1
VarInconnu2
VarInconnu3
VarInconnu4


--- Procédure Procedure_3 ---
VarInconnu1
VarInconnu2
VarInconnu3
VarInconnu4

Un exemple de Tag de variable inutilisée
Code:
Dim xxx, yyy ',zzz ' VARIABLE INUTILE (08/03/2025 22:37:33) ---> xxx

Merci à ceux qui prendraient le temps de tester mon code et me faire un retour et / ou qui auraient envie e le compléter.
 
Bonsoir,
J'ai testé...
Pour les néophytes vous devez donner plus d'explication concernant la mise en place et les références.

Cela dit, ça fait le job, la sortie dans la fenêtre d'exécution est un peu confuse. Elle demande à être plus explicite.

Maintenant regardons la différence :
Sur un classeur vierge avec seulement les deux modules de test voilà ce que trouve RubberDuck :
000071.png

Et dans la qualité de code :
000072.png

Voilà suppression en lot des variables non utilisées.
Et bien d'autres outils qui s'avèrent rapidement indispensables.

Merci à ceux qui prendraient le temps de tester mon code et me faire un retour et / ou qui auraient envie e le compléter.
Pour ma part j'essaie de ne pas jouer avec le projet cela m'a parfois joué des tours, mais je pense que vous allez trouver quelqu'un pour finaliser ce projet.

Bonne programmation...
 

Pièces jointes

  • 000070.png
    000070.png
    71.2 KB · Affichages: 12
Mon PC est une 2CV, je voyage donc léger et je pense qu'une Bouée Canard comme le propose Valtrase 😉 ne rentrerait pas dans le coffre, ni sans doute la MZ
Hello,
bon j'ai testé la dernière version de RubberDuck (2.5.92.6367) sous différents environnements :
Excel 2016 32 bits Windows 11 ( i5 12 cores 16 Go Ram)
RbdXl2016.png

Excel 2007 32 bits (en anglais) Windows 7 SP1 32 bits (VirtualBox Config 2 cores 4 Go Ram)
RbdXl2007.png

Excel 2021 64 bits Windows 11
RbdXl2021.png

Pas de problème à l'installation et pas de plantage avec un seul classeur chargé qui ne comprend que le code de test de crocrocro
en ne faisant que l'inspection. Pour diminuer la charge de ressources cocher Legacy workload pendant l'installation :
InstallRbdLwl.png

Au pire si on a pas confiance ou si on constate que cela ralentit le Visual Basic Editor on peut rapidement désactiver le complément quite à
le réactiver quand on a besoin :
rubberDuckVBA.gif


paramètrage pour le français :
RubberDuckFrancais.png

Ne pas oublier de sauvegarder la configuration avec le bouton en bas.

Pour sélectionner un regroupement par sévérité :
Inspections.gif


Ami calmant, JP
 
Dernière édition:
Merci chronologiquement wDog66, cathodique, Valtrase, jurassic pork
Merci wDog66 pour le retour sur MZ-Tools V8 dont vous êtes satisfait.
Merci cathodique de m'avoir suggéré MZ-Tools V3, version ancienne gratuite et dont vous avez remarqué la non-fiablité dans certains cas.
Je n'ai pas installé MZ-Tools et donc pas testé.
Merci Valtrase de m'avoir suggéré d'utiliser RubberDuck, d'avoir pris le temps de tester mon exemple (avec les captures d'écrans RubberDuck), merci également d'avoir tester mon bricolage.
Merci jurassic pork pour avoir détaillé dans une animation le paramétrage à effectuer dans RubberDuck pour être léger (mon soucis) :
30 secondes pour charger à la demande, RubberDuck dans l'éditeur VBE.
J'ai installé la dernière version de RubberDuck (indiquée par jurassic pork) et l'ai testé sur mon module Module6_PourVar dont j'ai fourni le code au post 11 :
Les variables VarConnu1, VarConnu2 et VarConnu3 de la procédure Procedure_3 sont détectées comme "jamais assignée" à tort.
C'est assez bizarre car il n'y a pas de piège pour ces variables-là.
Très dommage !
Voir capture d'écran ci-dessous

1741548985608.png


Mon bricolage (qui n'est que du bricolage) les détecte bien.
Par contre, il se plante sur la variable jjj déclarée au niveau module et aussi dans Procedure_2 où la variable iii est utilisée (mais c'est donc la locale à Procedure_2.
la variable jjj niveau module ne ressort pas comme variable inutilisée alors qu'elle le devrait.
Je dois revoir mon code 😭
 
- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD

Discussions similaires

L
Réponses
6
Affichages
6 K
Ludo-ly
L
Retour