Autres Faire une recherche de sous-dossiers Windows (pas de fichiers) dans un dossier précis à partir de son nom contenu dans une cellule

  • Initiateur de la discussion Initiateur de la discussion Michou9
  • Date de début Date de début

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 !

Michou9

XLDnaute Occasionnel
Bonjour à tous
J'ai un fichier Excel (environ 500 lignes actuellement)
Dans la colonne A sont contenus des noms de sous dossiers
Je souhaiterais pouvoir faire une recherche de ces sous-dossiers Windows dans un dossier précis à partir de ces noms contenus dans les cellules de cette colonne
Les noms de ces sous-dossiers sont assez long
Je suis sous Excel 2007
Je ne sais pas si c'est réalisable ?
Je viens chercher de l'aide
Merci par avance
 
Solution
Bonsoir @Michou9

Avec votre fichier en Poste #5
VBA sans Module de classe.

VB:
Option Explicit
Option Compare Text

Sub Main()
' Procédure VBA :
' A1 = le chemin complet du dossier générale
' B2 = le chemin complet du (nom du dossier exact en A20) qui noyer dans l arborescence du dossier générale
' B2 = le Nom du dossier exact en A20 s'ouvrent automatiquement
' Recherche :
' A20 = Le Nom du dossier Exact (qui noyer dans l'arborescence du dossier générale)
    Application.ScreenUpdating = False
  
    Dim F1 As Worksheet
    Dim DossierRacine As String
    Dim DossierCherche As String
    Dim CheminTrouve As String
  
    Set F1 = Worksheets(ActiveSheet.Name)
  
    ' Récupération des paramètres
    DossierRacine = F1.Cells(1...
Oui c'est ce j'ai fini par comprendre puisque j'ai vu que tu avais mis chemin = ThisWorkbook.Path & "\"
Comme je souhaite laisser mon fichier avec tous les autres fichiers Excel
j'ai essayé de remplacer chemin = ThisWorkbook.Path & "\" par chemin = "F:\House\"
et "Dossier général" par "A-85"
Mais cela ne fonctionne pas
 
Effectivement j'ai mal dû adapter le code
Avec votre dernier code, c'est Ok

Mais c'est super long!!, Beaucoup trop long, j'ai trop de fichiers

Est-ce qu'il serait possible de ne pas lister les sous-dossiers
une fois lister par exemple le dossier "Dupond machin 500€ 200m"
ne pas lister les sous dossiers qui sont dedans ?

Ou autrement exclure les dossiers comportant un mot comme "Lien" "Photo" par exemple
 
Mais c'est super long!!, Beaucoup trop long, j'ai trop de fichiers
Salut,
combien de dossiers ?
parce qu' avec l'exemple de job75 , il ne faut que 9 ms chez moi. J' ai une autre méthode mais qui est plus compliquée à mettre en oeuvre et qui est intéressantes qu'en il y a énormément de dossiers :
Résultat typique :
Nombre de dossiersVBAAutre méthode
1005–10 ms1–3 ms
1 00020–40 ms3–5 ms
10 000150–300 ms5–15 ms
50 0001–3 secondes20–40 ms

Cela dépend aussi des niveaux de sous-dossiers
La récursion descend dans tous les niveaux, donc :
  • plus il y a de niveaux,
  • plus il y a de sous‑dossiers,
  • plus on fait d’appels récursifs.
👉 Ce n’est pas la profondeur en elle‑même qui coûte, mais le volume total de dossiers.

Le vrai goulot d’étranglement : ReDim Preserve

Nullosse
 
Bonjour nullosse

Là j'ai environ 200 dossiers, cela peut allez jusqu'à 500 dossiers
Pour les 200 cela mis plus de 5mn
Avec les sous dossiers, le nombre est d'environ 5 fois plus et cela peut aller jusqu'à 12 ou 15 sous-dossiers par dossier
C'est pour cela qu'il serait intéressant à ce limiter au seuls dossiers comportant le signe "€"
et à en exclure tous les sous dossiers
Les dossiers ne comportant le signe "€" et les sous-dossiers ne me sont d'aucune utilisée dans ce contexte
Maintenant je ne sais pas si cela est possible ??
 
Bonjour nullosse

Là j'ai environ 200 dossiers, cela peut allez jusqu'à 500 dossiers
Pour les 200 cela mis plus de 5mn
Avec les sous dossiers, le nombre est d'environ 5 fois plus et cela peut aller jusqu'à 12 ou 15 sous-dossiers par dossier
C'est pour cela qu'il serait intéressant à ce limiter au seuls dossiers comportant le signe "€"
et à en exclure tous les sous dossiers
Les dossiers ne comportant le signe "€" et les sous-dossiers ne me sont d'aucune utilisée dans ce contexte
Maintenant je ne sais pas si cela est possible ??
Je ne sais pas si j'ai bien compris :
tu as 200 à 500 dossiers à partir de la racine qui peuvent contenir un € dans leurs noms ? et dans ces dossiers tu as plein de sous-dossiers ?
C'est cela ? Il y a beaucoup de dossiers qui contiennent un € ?
 
tu as 200 à 500 dossiers à partir de la racine qui peuvent contenir un € dans leurs noms ?
Oui c’est bien cela

et dans ces dossiers tu as plein de sous-dossiers ?
Oui aussi

Les sous-dossiers des dossiers comportant un €, ne comportent pas de €

Pour être plus claire, je donne un exemple bidon, mais qui représente exactement mes dossiers

Machin truc chouette 500€ 120m 500m @2000 DpA
Machin truc chouette 500€ 120m 500m @2000 DpA\Lien
Machin truc chouette 500€ 120m 500m @2000 DpA\Photo
Machin truc chouette 500€ 120m 500m @2000 DpA\Genre
Machin truc chouette 500€ 120m 500m @2000 DpA\Info

Dans le cas présent on a donc un dossier concerné
Et ce dossier comporte4 sous-dossiers

Les dossiers comportant un € sont de 200 environ ce jour et peuvent montés à plus de 500
Il y a donc aussi des dossiers ne comportant pas de €
Les sous dossiers des dossiers comportant un € sont en général de 5 à 12
 
Bon j'ai complètement revu le code :
VB:
Option Compare Text 'la casse est ignorée
Dim chemin$, fso As Object, a$(), n& 'mémorise les variables

Sub CheminDossierGeneral()
With Application.FileDialog(msoFileDialogFolderPicker)
    .Title = "Sélectionnez le Dossier Général"
    If .Show = False Then End
    [B10] = .SelectedItems(1) 'stockage en B10
End With
End Sub

Sub NomsDossiers()
If fso Is Nothing Then
    chemin = [B10]
    If Replace(Dir(chemin, vbDirectory), ".", "") = "" Then MsgBox "Le chemin en B10 n'est pas valide !", 48: Exit Sub
    Set fso = CreateObject("Scripting.FileSystemObject")
End If
NomsDossiersRecursive chemin
Application.ScreenUpdating = False
With [A12] '1ère cellule de destination
    If n Then
        .Resize(n) = Application.Transpose(a)
        .Resize(n).RemoveDuplicates 1, Header:=xlNo 'supprime les doublons
    End If
    .Offset(n).Resize(Rows.Count - n - .Row + 1).ClearContents 'RAZ en dessous
End With
Set fso = Nothing
Erase a: n = 0
End Sub

Sub NomsDossiersRecursive(NomComplet$)
Dim sf As Object
For Each sf In fso.GetFolder(NomComplet).SubFolders
    If InStr(sf.Name, "€") Then
        ReDim Preserve a(n)
        a(n) = Mid(sf.Path, InStrRev(sf.Path, "\") + 1)
        n = n + 1
    End If
    NomsDossiersRecursive sf.Path
Next sf
End Sub

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
If Target.Row < 12 Or Target(1) = "" Then Exit Sub
Cancel = True
chemin = [B10]
If Replace(Dir(chemin, vbDirectory), ".", "") = "" Then MsgBox "Le chemin en B10 n'est pas valide !", 48: Exit Sub
If Not Intersect(Target, [A12].Resize(Rows.Count - 11)) Is Nothing Then
    Recherche Target
ElseIf Not Intersect(Target, [B12].Resize(Rows.Count - 11, Columns.Count - 1), Me.UsedRange) Is Nothing Then
Shell "explorer.exe """ & chemin & Target & """", vbNormalFocus 'ouvre le dossier
End If
End Sub

Sub Recherche(Target As Range)
If fso Is Nothing Then Set fso = CreateObject("Scripting.FileSystemObject")
Application.ScreenUpdating = False
Target(1, 2).Resize(, Columns.Count - 1).ClearContents 'RAZ
RechercheRecursive chemin, Target
[B12].Resize(Rows.Count - 11, Columns.Count - 1).Columns.AutoFit 'ajustement largeurs
Set fso = Nothing
End Sub

Sub RechercheRecursive(NomComplet$, Target As Range)
Dim sf As Object, lig&, col%
For Each sf In fso.GetFolder(NomComplet).SubFolders
    If Mid(sf.Path, InStrRev(sf.Path, "\") + 1) = Target Then
        lig = Target.Row
        col = Cells(lig, Columns.Count).End(xlToLeft).Column + 1
        Cells(lig, col) = Mid(sf.Path, Len(chemin) + 1)
    End If
    RechercheRecursive sf.Path, Target
Next sf
End Sub
1) Le 1er bouton recherche le chemin du 1er dossier (Dossier Général) qui s'inscrit en B10.

2) Le 2ème bouton crée la liste en colonne A des noms des dossiers contenant "€".

3) Le double-clic recherche les chemins d'un seul dossier, c'est donc très rapide.

Edit : j'ai complété le code du message d'erreur concernant B10.
 

Pièces jointes

Dernière édition:
Bonsoir @Michou9 @nullosse @job75
Pour les 200 cela mis plus de 5mn
ca devrait etre vraiment beaucoup plus rapide

En cellule A1 = noter le chemin complet du dossier source.

VB:
Option Explicit
Option Compare Text
#If VBA7 Then
    Private Declare PtrSafe Function QueryPerformanceCounter Lib "kernel32" (lpPerformanceCount As Currency) As Long
    Private Declare PtrSafe Function QueryPerformanceFrequency Lib "kernel32" (lpFrequency As Currency) As Long
#Else
    Private Declare Function QueryPerformanceCounter Lib "kernel32" (lpPerformanceCount As Currency) As Long
    Private Declare Function QueryPerformanceFrequency Lib "kernel32" (lpFrequency As Currency) As Long
#End If

Sub Main_Ultime()
  Application.ScreenUpdating = False
    Dim F1 As Worksheet
    Dim i As Long
    Dim DossierRacine As String
    Dim DossierCherche As String
    Dim TableauResultats As Variant
    '
    ' Compteurs haute précision
    Dim freq As Currency, startCount As Currency, endCount As Currency
    Dim elapsed As Double
    Dim msgTemps As String
    Dim mins As Long
    Dim secs As Double
    QueryPerformanceFrequency freq
    QueryPerformanceCounter startCount
    '
    Set F1 = Worksheets(ActiveSheet.Name)
             DossierRacine = F1.Cells(1, 1).Value
             DossierCherche = F1.Cells(20, 1).Value
    '
    ' Nettoyage
        F1.Range(F1.Cells(1, 2), F1.Cells(F1.Range("B65536").End(xlUp).Row, 2)).Clear
    '
    ' ---------------------------------------------------------
    ' APPEL DE LA FONCTION ULTIME
    ' Retourne directement un Tableau (Variant) et non une Collection
    ' ---------------------------------------------------------
        TableauResultats = Chercheur_Dir_Dictionary(DossierRacine, DossierCherche)
    '
    ' --- RESTITUTION ---
    '
    ' Gestion du tableau vide (si non trouvé)
        If Not IsArray(TableauResultats) Then
            F1.Cells(1, 2).Value = "Non trouvé"
            F1.Cells(1, 2).Interior.Color = vbRed
        Else
            ' Si un seul résultat (UBound est à 0)
            If UBound(TableauResultats) = 0 Then
                F1.Hyperlinks.Add Anchor:=F1.Cells(1, 2), Address:=TableauResultats(0), TextToDisplay:=TableauResultats(0)
                F1.Cells(1, 2).Interior.Color = vbGreen
                Shell "explorer.exe " & Chr(34) & TableauResultats(0) & Chr(34), vbNormalFocus
            Else
                ' Cas multiple
                F1.Cells(1, 2).Value = "Il y a " & (UBound(TableauResultats) + 1) & " dossiers identiques :"
                F1.Cells(1, 2).Interior.Color = vbYellow
                F1.Cells(1, 2).Font.Bold = True
                
                ' Boucle sur le tableau (Index commence à 0)
                For i = LBound(TableauResultats) To UBound(TableauResultats)
                    ' On décale de 1 ligne pour le titre
                    F1.Hyperlinks.Add Anchor:=F1.Cells(i + 2, 2), Address:=TableauResultats(i), TextToDisplay:=TableauResultats(i)
                    F1.Cells(i + 2, 2).Interior.Color = RGB(220, 240, 220)
                    
                    ' Ouverture auto du premier
                    If i = 0 Then Shell "explorer.exe " & Chr(34) & TableauResultats(0) & Chr(34), vbNormalFocus
                Next i
            End If
        End If
'
        F1.Columns("B").AutoFit
        Application.ScreenUpdating = True
    ' ---------------------------------------------------------
    ' FIN DE MESURE ET CONVERSION INTELLIGENTE
    ' ---------------------------------------------------------
        QueryPerformanceCounter endCount
    
    ' Calcul du temps en Millisecondes
        elapsed = (endCount - startCount) / freq * 1000
    
    ' Formatage du message selon la durée
        If elapsed < 1000 Then
            ' Moins d'une seconde : on affiche en ms
                msgTemps = Format(elapsed, "0.000") & " millisecondes"
        ElseIf elapsed < 60000 Then
            ' Moins d'une minute : on affiche en secondes
                msgTemps = Format(elapsed / 1000, "0.000") & " secondes"
        Else
            ' Plus d'une minute : on affiche minutes et secondes
                mins = Int(elapsed / 60000)
                secs = (elapsed - (mins * 60000)) / 1000
                msgTemps = mins & " minute(s) et " & Format(secs, "0.00") & " secondes"
        End If
        MsgBox "La Recherche a été exécutée en " & msgTemps, vbInformation, "Performance ULTIME"
End Sub

' ---------------------------------------------------------
' FONCTION ULTIME : DIR + PILE + DICTIONARY
' ---------------------------------------------------------
Function Chercheur_Dir_Dictionary(Racine As String, NomRecherche As String) As Variant
    Dim Pile As New Collection      ' La pile pour stocker les dossiers à scanner
    Dim Dict As Object              ' Le Dictionary pour stocker les résultats
    Dim CheminEnCours As String     ' Le dossier en cours de lecture
    Dim Element As String           ' L'élément trouvé par Dir
    Dim CheminComplet As String
    '
    Set Dict = CreateObject("Scripting.Dictionary")
    '
    ' Normalisation du chemin racine
        If Right(Racine, 1) <> "\" Then Racine = Racine & "\"
    
    ' 1. On met le dossier racine dans la pile
        Pile.Add Racine
    
    ' 2. BOUCLE ITERATIVE (Plus rapide que la récursivité pour Dir)
        Do While Pile.Count > 0
            ' On prend le premier de la pile
                CheminEnCours = Pile(1)
                Pile.Remove 1
            ' On lance Dir pour ce dossier (vbDirectory pour voir les dossiers)
                Element = Dir(CheminEnCours, vbDirectory)
                    Do While Element <> ""
                        ' On ignore les dossier système . et ..
                            If Element <> "." And Element <> ".." Then
                                CheminComplet = CheminEnCours & Element
                                ' On teste si c'est un dossier (GetAttr est natif et rapide)
                                On Error Resume Next
                                    If (GetAttr(CheminComplet) And vbDirectory) = vbDirectory Then
                                        If Err.Number = 0 Then
                                            ' A. C'est un dossier -> On ajoute à la PILE pour le scanner plus tard
                                            Pile.Add CheminComplet & "\"
                                            ' B. Si c'est celui qu'on cherche -> On ajoute au DICTIONARY
                                            If Element = NomRecherche Then
                                                ' Dictionary gère les doublons tout seul (Clé unique)
                                                ' Ici la clé est le chemin complet
                                                Dict(CheminComplet) = 1
                                            End If
                                        End If
                                    End If
                                On Error GoTo 0
                            End If
        ' Element suivant
            Element = Dir()
        Loop
    Loop
    ' 3. TRANSFERT IMMEDIAT EN TABLEAU
    ' La propriété .Keys renvoie un tableau Variant() en une seule fois
    ' Pas de boucle de conversion nécessaire !
        If Dict.Count > 0 Then
            Chercheur_Dir_Dictionary = Dict.Keys
        End If
End Function
 
Dernière édition:
Bonsoir :
Nouvelle Variantes (Recherche depuis le disque)
en cellule A1 noté :
Exemple :
C:\
D:\
La procédure fait la recherche sur tous le disque

VB:
Option Explicit
Option Compare Text
#If VBA7 Then
    Private Declare PtrSafe Function QueryPerformanceCounter Lib "kernel32" (lpPerformanceCount As Currency) As Long
    Private Declare PtrSafe Function QueryPerformanceFrequency Lib "kernel32" (lpFrequency As Currency) As Long
#Else
    Private Declare Function QueryPerformanceCounter Lib "kernel32" (lpPerformanceCount As Currency) As Long
    Private Declare Function QueryPerformanceFrequency Lib "kernel32" (lpFrequency As Currency) As Long
#End If

Sub Main_Ultime()
  Application.ScreenUpdating = False
    Dim F1 As Worksheet
    Dim i As Long
    Dim DossierRacine As String
    Dim DossierCherche As String
    Dim TableauResultats As Variant
    '
    ' Compteurs haute précision
    Dim freq As Currency, startCount As Currency, endCount As Currency
    Dim elapsed As Double
    Dim msgTemps As String
    Dim mins As Long
    Dim secs As Double
    QueryPerformanceFrequency freq
    QueryPerformanceCounter startCount
    '
    Set F1 = Worksheets(ActiveSheet.Name)
             DossierRacine = F1.Cells(1, 1).Value
             DossierCherche = F1.Cells(20, 1).Value
    '
    ' Nettoyage
        F1.Range(F1.Cells(1, 2), F1.Cells(F1.Range("B65536").End(xlUp).Row, 2)).Clear
    '
    ' ---------------------------------------------------------
    ' APPEL DE LA FONCTION ULTIME
    ' Retourne directement un Tableau (Variant) et non une Collection
    ' ---------------------------------------------------------
        TableauResultats = Chercheur_Dir_Dictionary(DossierRacine, DossierCherche)
    '
    ' --- RESTITUTION ---
    '
    ' Gestion du tableau vide (si non trouvé)
        If Not IsArray(TableauResultats) Then
            F1.Cells(1, 2).Value = "Non trouvé"
            F1.Cells(1, 2).Interior.Color = vbRed
        Else
            ' Si un seul résultat (UBound est à 0)
            If UBound(TableauResultats) = 0 Then
                F1.Hyperlinks.Add Anchor:=F1.Cells(1, 2), Address:=TableauResultats(0), TextToDisplay:=TableauResultats(0)
                F1.Cells(1, 2).Interior.Color = vbGreen
                Shell "explorer.exe " & Chr(34) & TableauResultats(0) & Chr(34), vbNormalFocus
            Else
                ' Cas multiple
                F1.Cells(1, 2).Value = "Il y a " & (UBound(TableauResultats) + 1) & " dossiers identiques :"
                F1.Cells(1, 2).Interior.Color = vbYellow
                F1.Cells(1, 2).Font.Bold = True
                
                ' Boucle sur le tableau (Index commence à 0)
                For i = LBound(TableauResultats) To UBound(TableauResultats)
                    ' On décale de 1 ligne pour le titre
                    F1.Hyperlinks.Add Anchor:=F1.Cells(i + 2, 2), Address:=TableauResultats(i), TextToDisplay:=TableauResultats(i)
                    F1.Cells(i + 2, 2).Interior.Color = RGB(220, 240, 220)
                    
                    ' Ouverture auto du premier
                    If i = 0 Then Shell "explorer.exe " & Chr(34) & TableauResultats(0) & Chr(34), vbNormalFocus
                Next i
            End If
        End If
'
        F1.Columns("B").AutoFit
        Application.ScreenUpdating = True
    ' ---------------------------------------------------------
    ' FIN DE MESURE ET CONVERSION INTELLIGENTE
    ' ---------------------------------------------------------
        QueryPerformanceCounter endCount
    
    ' Calcul du temps en Millisecondes
        elapsed = (endCount - startCount) / freq * 1000
    
    ' Formatage du message selon la durée
        If elapsed < 1000 Then
            ' Moins d'une seconde : on affiche en ms
                msgTemps = Format(elapsed, "0.000") & " millisecondes"
        ElseIf elapsed < 60000 Then
            ' Moins d'une minute : on affiche en secondes
                msgTemps = Format(elapsed / 1000, "0.000") & " secondes"
        Else
            ' Plus d'une minute : on affiche minutes et secondes
                mins = Int(elapsed / 60000)
                secs = (elapsed - (mins * 60000)) / 1000
                msgTemps = mins & " minute(s) et " & Format(secs, "0.00") & " secondes"
        End If
        MsgBox "La Recherche a été exécutée en " & msgTemps, vbInformation, "Performance ULTIME"
End Sub

' ---------------------------------------------------------
' FONCTION ULTIME : DIR + PILE + DICTIONARY
' ---------------------------------------------------------
Function Chercheur_Dir_Dictionary(Racine As String, NomRecherche As String) As Variant
    Dim Pile As New Collection      ' La pile pour stocker les dossiers à scanner
    Dim Dict As Object              ' Le Dictionary pour stocker les résultats
    Dim CheminEnCours As String     ' Le dossier en cours de lecture
    Dim Element As String           ' L'élément trouvé par Dir
    Dim CheminComplet As String
    '
    Set Dict = CreateObject("Scripting.Dictionary")
    '
    ' Normalisation du chemin racine
        If Right(Racine, 1) <> "\" Then Racine = Racine & "\"
    
    ' 1. On met le dossier racine dans la pile
        Pile.Add Racine

    ' 2. BOUCLE ITERATIVE (Plus rapide que la récursivité pour Dir)
        Do While Pile.Count > 0
            ' On prend le premier de la pile
                CheminEnCours = Pile(1)
                Pile.Remove 1
    ' ---------------------------------------------------------
        ' CORRECTION DU PLANTAGE ICI AVEC RACINE C:\
        ' On protège l'appel initial de Dir car c'est là que ça plante
        ' sur les dossiers systèmes (PerfLogs, System Volume Information...)
        ' ---------------------------------------------------------
        On Error Resume Next
            ' On lance Dir pour ce dossier (vbDirectory pour voir les dossiers)
                Element = Dir(CheminEnCours & "*", vbDirectory)
        
            ' Si erreur (ex: Accès refusé), Err.Number > 0
                If Err.Number <> 0 Then
                    ' On ignore ce dossier, on vide l'erreur, et on passe au suivant dans la Pile
                        Err.Clear
                        On Error GoTo 0
                        GoTo ContinueLoop ' Saut vers la fin de la boucle Do
                End If
        On Error GoTo 0
        ' ---------------------------------------------------------
                    Do While Element <> ""
                        ' On ignore les dossier système . et ..
                            If Element <> "." And Element <> ".." Then
                                CheminComplet = CheminEnCours & Element
                                ' On teste si c'est un dossier (GetAttr est natif et rapide)
                                On Error Resume Next
                                    If (GetAttr(CheminComplet) And vbDirectory) = vbDirectory Then
                                        If Err.Number = 0 Then
                                            ' A. C'est un dossier -> On ajoute à la PILE pour le scanner plus tard
                                            Pile.Add CheminComplet & "\"
                                            ' B. Si c'est celui qu'on cherche -> On ajoute au DICTIONARY
                                            If Element = NomRecherche Then
                                                ' Dictionary gère les doublons tout seul (Clé unique)
                                                ' Ici la clé est le chemin complet
                                                Dict(CheminComplet) = 1
                                            End If
                                        End If
                                    End If
                                On Error GoTo 0
                            End If
        ' Element suivant
            Element = Dir()
        Loop
ContinueLoop:
    Loop
    ' 3. TRANSFERT IMMEDIAT EN TABLEAU
    ' La propriété .Keys renvoie un tableau Variant() en une seule fois
    ' Pas de boucle de conversion nécessaire !
        If Dict.Count > 0 Then
            Chercheur_Dir_Dictionary = Dict.Keys
        End If
End Function
 
- 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

Réponses
3
Affichages
869
Retour