Lister les onglets à partir d'un classeur sélectionné

Bonsoir Peerl Theze le forum

bon alors il apparaît nettement, que tu ne sais pas lire c'est dommage pour toi mais après tout c'est ton problème, c'est tes fichiers.

Je t'ai demandé très clairement de me faire un tableau avec ce que tu souhaites de ton fichier 7890 dans le ficher Userform.xlsm

et là il y a maintenant deux feuilles résultat!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Mais par contre toujours qu'une seule ou deux lignes!!!!

Donc par fichier on ne doit extraire que deux lignes ?????

La réponse est non, bien sur, alors comme tu n'as pas fait manuellement le tableau pour la feuille complète de ton fichier 7890, je ne vais pas te le redemander à chaque fois, donc si d’aventure tu te mets à lire et comprendre ma demande, tu refais le tableau complet et tu renvoies le fichier Userform.xlsm, en attendant je ne réponds plus pas de temps à perdre.

a+

Papou

Salut Papou , Theze , le Forum

J'ai hésité de vous écrire , je n'ai pas envie de vous embêter ..

Bon j'ai essayer de relire la discussion depuis le départ , et je reconnais que c'est de ma faute d’être pas très précise depuis le départ car rien n'était clair même pour moi apparemment . Je suis novice en VBA , et j'ai commencé à imaginer tout et n'importe quoi et faire des propositions ce qui a causé ce mal entendu . ( je m'excuse Theze , Papou ..).

et si je réexplique juste le besoin ?

J'ai un dossier avec plusieurs fichiers --> le but c'est de pouvoir chercher dans une feuille qui a les mêmes tableaux dans chaque fichiers d'ou l'idée de lister les fichiers puis lister leurs onglets . l'idée de Theze était parfaite même pour chercher seulement les feuilles et y accéder directement.

Une fois l'onglet choisi , je dois pouvoir effectuer une recherche ( ce qui m’intéresse c'est les chiffres )en fonction des colonnes et des lignes ET les stocker dans la feuille résultat .

Bien sur , y'aura pas que deux lignes mais quand je sélectionne une ligne je la stocke puis une autre ligne ainsi de suite ( ce qui fera une liste par la suite ).

cette fois ci , j'ai essayer d'imaginer le tableau que je pourrai avoir, cela me semble logique et propre .Je le place dans USERFORM.xlm avec le formulaire que Theze avait posté ici + les deux fichiers et je laisse la main .

Papou , si j'ai mal compris encore une fois , c'est parce que je n'ai pas d'autres idée pour le tableau résultat . Je m'excuse d'avance .

14fichiers.rar (68.04 Ko)

Bonne après midi .

Re Bonjour Peerl le forum

bon alors on avance pas vite mais on avance

Ce que tu n'as pas compris c'est qu'il ne faut pas tenir compte des données que tu souhaites ouvrir au moment M,

mais que tu dois pour pouvoir consulter tes données ultérieurement créer une ou plusieurs feuilles avec toutes tes données et ensuite un Userform, avec un module de recherche, et là tu pourras lire ce que tu veux quand tu le veux

je vais ouvrir le fichier pour voir ce que tu as pondu

a+

Papou

Bonjour,

Voici le classeur en retour avec une routine de recherche sur le bouton "Rechercher" vu comment sont construit les classeurs où sont rechercher les valeurs je ne garanti pas un résultat parfait !

Les différents blocs liés aux titres doivent être séparés par au moins une ligne vide car une fois le titre trouvé (boucle For Each ... Next avec Like) la plage de recherche est définie de la cellule contenant le titre recherché jusqu'à la dernière cellule utilisé formant la fin du bloc :

28userformv2.xlsm (34.19 Ko)

Bonjour , Theze , Papou , en forme le forum ?

Je viens de tester le userform, et il marche très bien sur mes fichiers de test . Sur tout les ID , etc ...

Quand je teste sur les fichiers de bases , ça marche très bien aussi . Par contre , j'ai remarqué quand je passe d'un fichier à un autre ça Ram trop des fois je suis obligé de mettre fin à la tache ( gestionnaire de tache ). Je me demande si ce n'est pas à cause de la taille du fichier : 10,8 Mo .

Puis , sur les fichiers de bases ( sachant que je n'ai modifié que les données ) : quand je choisi un ID autre que celui qui est juste après le titre il ne le trouve pas.En regardant le code , je ne vois pas de spécification de ligne par rapport à la recherche des ID donc je me demande pourquoi cela ?

Merci bien et bonne journée

Bonjour,

Par contre , j'ai remarqué quand je passe d'un fichier à un autre ça Ram trop des fois je suis obligé de mettre fin à la tache ( gestionnaire de tache ). Je me demande si ce n'est pas à cause de la taille du fichier : 10,8 Mo

C'est peut être lié au nombre de classeurs ouverts qui peut poser problème, dans ce cas, il est préférable de fermer ce qui ne sont plus utiles. Remplace le code lié à la ListBox1 par celui-ci dessous. Au changement de sélection dans la ListBox1, le précédent classeur est fermé :

Private Sub ListBox1_Click()

    Dim Cat As Object
    Dim Tbl() As String

    If Existe = False Then Exit Sub

    'si le classeur sélectionné est celui-ci, fin de procédure
    If ListBox1.Text = ThisWorkbook.Name Then ListBox2.Clear: Exit Sub

    'si la variable est initialisée et que le nom du classeur est
    'différent de celui qui vient d'être sélectionné dans la liste, ferme le classeur
    'et décharge la variable
    If Not Cls Is Nothing Then

        If Cls.Name <> ListBox1.Text Then

            Cls.Close False
            Set Cls = Nothing

        End If

    End If

    'dans le cas où il serait déjà ouvert, erreur si ce n'est pas le cas donc la gérer
    On Error Resume Next
    Set Cls = Workbooks(ListBox1.Text)

    'si il y a erreur, le classeur n'est pas ouvert donc, ouverture
    If Err.Number <> 0 Then Set Cls = Workbooks.Open(Dossier & ListBox1.Text)

    'si on souhaite ne pas voir le classeur ouvert à l'écran, ôter les apostrophes
    'Application.ScreenUpdating = False
    'Windows(ListBox1.Text).Visible = False
    'Application.ScreenUpdating = True

    On Error GoTo 0

    'crée l'objet catalogue
    Set Cat = CreateObject("ADOX.Catalog")

    Cat.ActiveConnection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & _
                           Dossier & ListBox1.Text & _
                           ";Extended Properties=""Excel 12.0;HDR=NO;IMEX=2;"""

    'récupère les noms des feuilles
    Tbl = FeuillesExcel(Cat)

    'rempli la liste
    ListBox2.List = Tbl()

End Sub

Puis , sur les fichiers de bases ( sachant que je n'ai modifié que les données ) : quand je choisi un ID autre que celui qui est juste après le titre il ne le trouve pas.En regardant le code , je ne vois pas de spécification de ligne par rapport à la recherche des ID donc je me demande pourquoi cela ?

Comme j'ai dis dans mon précédent message, les blocs doivent être séparés par une ligne vide mais il ne doit pas y en avoir entre la ligne où se trouve le titre et celle soù se trouvent les ID comme dans l'exemple ci-dessous :

Titre 1

ID

ID

ID

ID

<------ ligne vide !

Titre 2

ID

ID

ID

<----- ligne vide

Titre 3

etc...

Cette ligne de code effectue la recherche du titre sur chaque cellule de la colonne A (l'astérisque permet de prendre en compte toutes lettres ou chiffres qui peuvent se trouver entre le mot "Titre" et le titre lui même) :

If Cel.Value Like "Titre*" & TxtTitre.Text Then

Si le titre est trouvé, on défini la plage de recherche de l'ID avec cette ligne de code :

With Fe: Set PlageID = .Range(.Cells(Cel.Row, 1), .Cells(Cel.Row, 1).End(xlDown)): End With

et comme tu peux le voir, la recherche de la dernière ligne utilisée sous la cellule contenant le titre est faite en descendant (xlDown) donc il ne faut pas de ligne vide sous la ligne qui contient le titre mais pour définir le bloc d'ID correspondant au titre recherché, il faut qu'il y est une ligne vide avant le titre prochain !

Re Theze ,

Je viens de modifier le code , effectivement , ça Ram moins mais ça Ram toujours car , si je comprends bien ça dépends de combien on charge dans le LISTBOX . les fichiers que j'ai actuellement sont 18 fichiers et les feuilles sont 90 par fichiers . ça Ram pas pour le premier fichier.

Pour les feuilles , peut on limiter la récupération des noms des feuilles ? si on précise quelle feuille ou par exemple charger que les feuilles commençant par A ou B ? J'ai pensé à ajouter un bouton réinitialiser comme ça une fois je finis avec un classeur je vide la liste puis charger une autre liste de feuilles . --> j'ai testé , mais pas de différence.

Autre question , pour les ID , je comprends mieux maintenant qu'il faut pas y avoir une ligne vide entre le titre et l'ID parce qu’on utilise (xlDown) , et dans le cas ou y'a une ligne vide ? y a t il une solution pour ça ?

Sinon , le code il réponds au plus important Merci Theze .

Bonjour Peerl Theze le forum

sans vouloir me mêler de ce qui ne me regarde pas Theze moi je modifierai ta macro recherche de la sorte

a+

Papou

.Cells(Lgn, 3).Value = Cel.Text
                .Range(.Cells(Lgn, 4), .Cells(Lgn, 13)).Value = Fe.Range(Fe.Cells(CelTrouve.Row, 1), Fe.Cells(CelTrouve.Row, 10)).Value
            End With
            MsgBox "Valeurs enregistrés!", , "Enregistreé": TxtTitre = "": TxtID = "": Exit For 'sortie de boucle d'office si le titre est trouvé
        End If

Re,

Dans les ListBox, c'est seulement les noms des classeurs et des feuilles qui sont inscrits sans qu'ils soient ouverts donc ce n'est pas ce qui fait ramer ! Les ListBox ne contiennent en fait que du texte et tu pourrais en avoir 100 fois plus que ça ne changerait rien, le problème est ailleurs. Le dernier code que je t'ai donné ferme le classeur ouvert (celui où tu viens de récupérer les valeurs) avant d'en ouvrir un autre donc, il n'y a que deux classeurs ouverts, celui qui contient le code et celui où tu veux récupérer les valeurs.

Poses un bouton sur ta Form et dansl'événement CLick() colles ces lignes de code et testes :

Dim C As Workbook

For Each C In Workbooks
    MsgBox C.Name
Next C

Normalement, tu ne devrais pas avoir plus de deux messages qui s'affichent, le nom de celui qui contient le code et celui sélectionné dans la ListBox1

Re ,

Theze , avec ce code , ça affiche que les deux noms des deux ficheirs qui sont ouvert comme tu as dis . quand je clique sur le premier fichier de la liste , ça Ram pas du tout c'est surtout les autres fichiers .

Papou , ta macro permet de réinitialiser les txtTitre et txtID .

Bonjour Papou,

pour :

.Cells(Lgn, 3).Value = TxtTitre.Text

on peut effectivement mettre "Cel.Text" au lieu de "TxtTitre.Text" mais ceci ne change rien car si trouvé, le titre correspond.

Tu as raison, il faut vider les TextBox et on peut même activer la feuille "Résultat" pour justement les voir :

Private Sub CmdRecherche_Click()

    Dim Plage As Range
    Dim PlageID As Range
    Dim Cel As Range
    Dim CelTrouve As Range
    Dim Lgn As Long

    If Cls Is Nothing Then MsgBox "Veuillez sélectionner un classeur dans la liste de gauche !": Exit Sub
    If Fe Is Nothing Then MsgBox "Veuillez sélectionner une feuille dans la liste de droite !": Exit Sub

    If TxtTitre.Text = "" Then MsgBox "Veuillez indiquer un titre !": Exit Sub
    If TxtID.Text = "" Then MsgBox "Veuillez indiquer un ID !": Exit Sub

    With Fe: Set Plage = .Range(.Cells(1, 1), .Cells(.Rows.Count, 1).End(xlUp)): End With

    For Each Cel In Plage

        If Cel.Value Like "Titre*" & TxtTitre.Text Then

            With Fe: Set PlageID = .Range(.Cells(Cel.Row, 1), .Cells(Cel.Row, 1).End(xlDown)): End With

            Set CelTrouve = PlageID.Find(TxtID.Text, Cel, xlValues, xlWhole)

            If CelTrouve Is Nothing Then MsgBox "ID introuvable pour " & TxtTitre.Text: Exit Sub

            With ThisWorkbook.Worksheets("Résultat")

                Lgn = .Cells(.Rows.Count, 1).End(xlUp).Row + 1

                .Cells(Lgn, 1).Value = Fe.Range("B5").Value
                .Cells(Lgn, 2).Value = Fe.Range("B4").Value
                .Cells(Lgn, 3).Value = Cel.Text '.Cells(Lgn, 3).Value = TxtTitre.Text

                .Range(.Cells(Lgn, 4), .Cells(Lgn, 13)).Value = Fe.Range(Fe.Cells(CelTrouve.Row, 1), Fe.Cells(CelTrouve.Row, 10)).Value

                MsgBox "Valeurs enregistrés !", , "Enregistrée.": TxtTitre.Text = "": TxtID.Text = ""

                ThisWorkbook.Worksheets("Résultat").Activate

            End With

            Exit For 'sortie de boucle d'office si le titre est trouvé

        End If

    Next Cel

End Sub

Theze , avec ce code , ça affiche que les deux noms des deux ficheirs qui sont ouvert comme tu as dis . quand je clique sur le premier fichier de la liste , ça Ram pas du tout c'est surtout les autres fichiers .

Quand tu cliques en premier sur un fichier autre que le premier de la liste ça rame ou pas du tout ? Ou c'est après l'ouverture d'un second classeur quel qu'il soit ?

Quand tu cliques en premier sur un fichier autre que le premier de la liste ça rame ou pas du tout ? Ou c'est après l'ouverture d'un second classeur quel qu'il soit ?

Quand je cliques en premier sur un fichier autre que le premier de la liste ça rame aussi

Donc, je pense que se sont certains classeurs qui posent problème !

C'est à quel moment que ça rame ? Quand tu fais une recherche, quand tu sélectionnes un classeur dans la liste de la ListBox1, quand tu sélectionnes une feuille dans la ListBox2 ?

c'est surtout quand je cliques sur un classeur dans listbox1 : les listes se vident ( tout devient blanc )

Je peux attendre 1 à deux minutes pour que j'aie le formulaire avec les listbox rempli de nouveau . J'ai testé une autre fois en cliquant directement sur un autre classeur , cette fois çi la liste n'a pas disparu mais ça rame de nouveau ( flou + cercle bleu ) sachant qu'il a ouvert le fichier quand même sur mon écran .

Juste pour tester, remplace le code de la ListBox1 par celui-ci, qui n'utilise plus le catalogue ADO mais une boucle puisque le classeur est chargé :

Private Sub ListBox1_Click()

    Dim Fe As Worksheet

    If Existe = False Then Exit Sub

    'si le classeur sélectionné est celui-ci, fin de procédure
    If ListBox1.Text = ThisWorkbook.Name Then ListBox2.Clear: Exit Sub

    'si la variable est initialisée et que le nom du classeur est
    'différent de celui qui vient d'être sélectionné dans la liste, ferme le classeur
    'et déchartge la vazriable
    If Not Cls Is Nothing Then

        If Cls.Name <> ListBox1.Text Then

            Cls.Close False
            Set Cls = Nothing

        End If

    End If

    'dans le cas où il serait déjà ouvert, erreur si ce n'est pas le cas donc la gérer
    On Error Resume Next
    Set Cls = Workbooks(ListBox1.Text)

    'si il y a erreur, le classeur n'est pas ouvert donc, ouverture
    If Err.Number <> 0 Then Set Cls = Workbooks.Open(Dossier & ListBox1.Text)

    'si on souhaite ne pas voir le classeur ouvert à l'écran, ôter les apostrophes
    'Application.ScreenUpdating = False
    'Windows(ListBox1.Text).Visible = False
    'Application.ScreenUpdating = True

    On Error GoTo 0

    'rempli la liste
    For Each Fe In Cls.Worksheets

        ListBox2.AddItem Fe.Name

    Next Fe

End Sub

Je viens de tester , ça ne rame plus quand je passe d'un classeur à un autre , mais dans listbox2 il rajoute les feuilles à chaque fois : feuilles du premier classeur + les feuilles du deuxième classeur sélectionné etc..

Il faut juste vider la liste avant (j'ai oublié !) avec "ListBox2.Clear" avant la boucle :

Private Sub ListBox1_Click()

    Dim Fe As Worksheet

    If Existe = False Then Exit Sub

    'si le classeur sélectionné est celui-ci, fin de procédure
    If ListBox1.Text = ThisWorkbook.Name Then ListBox2.Clear: Exit Sub

    'si la variable est initialisée et que le nom du classeur est
    'différent de celui qui vient d'être sélectionné dans la liste, ferme le classeur
    'et déchartge la vazriable
    If Not Cls Is Nothing Then

        If Cls.Name <> ListBox1.Text Then

            Cls.Close False
            Set Cls = Nothing

        End If

    End If

    'dans le cas où il serait déjà ouvert, erreur si ce n'est pas le cas donc la gérer
    On Error Resume Next
    Set Cls = Workbooks(ListBox1.Text)

    'si il y a erreur, le classeur n'est pas ouvert donc, ouverture
    If Err.Number <> 0 Then Set Cls = Workbooks.Open(Dossier & ListBox1.Text)

    'si on souhaite ne pas voir le classeur ouvert à l'écran, ôter les apostrophes
    'Application.ScreenUpdating = False
    'Windows(ListBox1.Text).Visible = False
    'Application.ScreenUpdating = True

    On Error GoTo 0

    ListBox2.Clear

    'rempli la liste
    For Each Fe In Cls.Worksheets

        ListBox2.AddItem Fe.Name

    Next Fe

End Sub

C'est ce que je pensais, c'est ADO qui fait ramer. Tu peux virer la fonction "FeuillesExcel()" elle ne t'est plus utile et donc, inutile d'encombrer le module de fonction qui ne servent à rien

Ah ça fonctionne parfaitement maintenant ! Je viens d'apprendre un nouveau truc merci Theze

et pour ma question précédente , si on tombe sur une ligne vide qui sépare les IDs du titre ?

Une autre question CHEF , est il possible que quand je clique sur la feuille dans listbox2 qu'il me dirige directement vers la feuille . J'ai une macro qui fait ça mais faut insérer le bouton dans la première feuille du classeur à chaque fois :

Sub onglets()

Dim tablRetour As Variant
Dim TheFil As Variant
Dim LeClasseur, LaFeuille As Variant

For Each LeClasseur In Workbooks
     For Each LaFeuille In LeClasseur.Worksheets
           If LaFeuille.Name = " Nom de la feuille" And LeClasseur.Name <> " Nom du classeur  " Then
                LeClasseur.Activate
                Sheets("Nom de le feuille").Select
           End If

     Next LaFeuille
Next LeClasseur

End Sub

Remplaces le code lié au bouton de recherche par celui-ci mais attention, ce n'est pas très propre et plutôt perfectible !

Tes classeurs devraient être construit autrement, plutôt comme une base de données quitte à répéter plusieurs fois certaines valeurs mais bon, c'est à toi de voir :

Private Sub CmdRecherche_Click()

    Dim Plage As Range
    Dim PlageID As Range
    Dim Cel As Range
    Dim CelTrouve As Range
    Dim Lgn As Long

    If Cls Is Nothing Then MsgBox "Veuillez sélectionner un classeur dans la liste de gauche !": Exit Sub
    If Fe Is Nothing Then MsgBox "Veuillez sélectionner une feuille dans la liste de droite !": Exit Sub

    If TxtTitre.Text = "" Then MsgBox "Veuillez indiquer un titre !": Exit Sub
    If TxtID.Text = "" Then MsgBox "Veuillez indiquer un ID !": Exit Sub

    With Fe: Set Plage = .Range(.Cells(1, 1), .Cells(.Rows.Count, 1).End(xlUp)): End With

    For Each Cel In Plage

        If Cel.Value Like "Titre*" & TxtTitre.Text Then

            If Cel.Offset(1).Value = "" Then

                With Fe: Set PlageID = .Range(.Cells(Cel.Row + 2, 1), .Cells(Cel.Row + 2, 1).End(xlDown)): End With

                If PlageID Is Nothing Then MsgBox "Impossible de définir la plage !": Exit Sub

                Set CelTrouve = PlageID.Find(TxtID.Text, Cel.Offset(2), xlValues, xlWhole)

            Else

                With Fe: Set PlageID = .Range(.Cells(Cel.Row, 1), .Cells(Cel.Row, 1).End(xlDown)): End With

                If PlageID Is Nothing Then MsgBox "Impossible de définir la plage !": Exit Sub

                Set CelTrouve = PlageID.Find(TxtID.Text, Cel, xlValues, xlWhole)

            End If

            If CelTrouve Is Nothing Then MsgBox "ID introuvable pour " & TxtTitre.Text: Exit Sub

            With ThisWorkbook.Worksheets("Résultat")

                Lgn = .Cells(.Rows.Count, 1).End(xlUp).Row + 1

                .Cells(Lgn, 1).Value = Fe.Range("B5").Value
                .Cells(Lgn, 2).Value = Fe.Range("B4").Value
                .Cells(Lgn, 3).Value = Cel.Text '.Cells(Lgn, 3).Value = TxtTitre.Text

                .Range(.Cells(Lgn, 4), .Cells(Lgn, 13)).Value = Fe.Range(Fe.Cells(CelTrouve.Row, 1), Fe.Cells(CelTrouve.Row, 10)).Value

                MsgBox "Valeurs enregistrés !", , "Enregistrée.": TxtTitre.Text = "": TxtID.Text = ""

                ThisWorkbook.Worksheets("Résultat").Activate

            End With

            Exit For 'sortie de boucle d'office si le titre est trouvé

        End If

    Next Cel

End Sub
Rechercher des sujets similaires à "lister onglets partir classeur selectionne"