IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

Recherche dans une colonne d'un tableau de variables .. et retourner l'index [XL-2013]


Sujet :

Macros et VBA Excel

  1. #1
    Membre averti
    Homme Profil pro
    Chef d’entreprise
    Inscrit en
    Mai 2014
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Chef d’entreprise

    Informations forums :
    Inscription : Mai 2014
    Messages : 18
    Par défaut Recherche dans une colonne d'un tableau de variables .. et retourner l'index
    Bonsoir,

    Encore une fois, je sèche après plusieurs heures de recherches...
    Tout est dans le titre :

    J'ai un tableau à 2 dimensions, pour lequel j'ai créé des en-tête qui me permettent de chercher l'index correspondant à la variable à alimenter.
    La première dimension est fixe, et la 2e est variable.

    Mon tableau se nomme TBP_HL et ressemble à ça :

    Type _______ Biere _______ Vin _______ Champagne _______ etc...
    DA_Sortie
    DA_Entree
    DD_Sortie
    DD_Entree


    J'ai trouvé cette formule, qui fonctionne et me retourne bien le numéro de l'index ("colonne") de la 1ère ligne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Dim VL_Type_article_en_cours as String
    VL_Type_article_en_cours = "Biere"            ' C'est véridique et ça tombe bien !! :-)
     
    VL_Index_type_article_en_cours = WorksheetFunction.Match(VL_Type_article_en_cours, WorksheetFunction.Index(TBP_HL, 1), 0) - 1
    Par contre, quand j'essaie de faire la même, mais pour rechercher chaque ligne dans la 1ere colonne, j'ai une erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    VL_Index_type_mvt_en_cours = WorksheetFunction.Match(VL_Type_mvt_en_cours, WorksheetFunction.Index(TBP_HL, 1), 0) - 1
    Je suis conscient qu'avec la même formule, je ne peux pas rechercher un coup dans une ligne, un coup dans une colonne ! (Encore que certaines fonctions savent le faire)

    Mais je me dis qu'il doit bien y avoir un moyen plus simple, que de faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    For I_type_mvt = 0 To UBound(TBP_HL)
        If TBP_HL(I_type_mvt, 0) = VL_Type_mvt_en_cours Then
            VL_Index_type_mvt_en_cours = I_type_mvt
        End If
    Next I_type_mvt
    Merci d'avance pour vos idées

  2. #2
    Membre Expert
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Septembre 2013
    Messages
    783
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Septembre 2013
    Messages : 783
    Par défaut
    Bonjour,

    Si j'ai bien compris, le mieux est de passer par un filtre (type autofilter) sur chaque type d'articles, et vous pouvez récupérer tous les enregistrements en une passe (en passant par le Range.SpecialCells(xlCellTypeVisible))
    Voir éventuellement http://excel.developpez.com/faq/?page=Filtre

  3. #3
    Membre extrêmement actif
    Homme Profil pro
    Inscrit en
    Septembre 2013
    Messages
    1 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2013
    Messages : 1 369
    Par défaut
    Bonjour,

    VL_Index_type_mvt_en_cours = WorksheetFunction.Match(VL_Type_mvt_en_cours, WorksheetFunction.Index(TBP_HL, ,1), 0) - 1

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Sub RecherchePositionElement2()
      a = [{"aa",11;"bb",22;"cc",33;"dd",44}]
      clé= "cc"
      p = Application.Match(clé, Application.Index(a, , 1), 0) ' Recherche dans colonne 1 du tableau a()
      MsgBox a(p, 2)
    End Sub
    Boisgontier

  4. #4
    Membre Expert Avatar de antonysansh
    Homme Profil pro
    Chargé d'études RH
    Inscrit en
    Mai 2014
    Messages
    1 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Chargé d'études RH
    Secteur : Finance

    Informations forums :
    Inscription : Mai 2014
    Messages : 1 115
    Par défaut
    Un Enum peut etre top dans ton cas.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Enum eDate
        DA_Sortie = 0
        DA_Entree
        DD_Sortie
        DD_Entree
    End Enum
    eDate.DA_Entree vaudra 1

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Enum eType
        Biere = 0
        Vin
        Champagne
        '...
    End Enum
    eType.Vin Biere vaut 1

    Voila une utilisation possible :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Sub test()
        Dim TBP_HL(3, 2), i&, j&
        'Je remplis TBP_HL avec des dates
        For i = 0 To 3
            For j = 0 To 2
                TBP_HL(i, j) = Date + i * j
            Next j
        Next i
        'Si je veux DA_Sortie de Vin j'ecris :
        MsgBox TBP_HL(eDate.DA_Sortie, eType.Vin)
    End Sub

  5. #5
    Membre averti
    Homme Profil pro
    Chef d’entreprise
    Inscrit en
    Mai 2014
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Chef d’entreprise

    Informations forums :
    Inscription : Mai 2014
    Messages : 18
    Par défaut
    Citation Envoyé par vinc_bilb Voir le message
    Bonjour,

    Si j'ai bien compris, le mieux est de passer par un filtre (type autofilter) sur chaque type d'articles, et vous pouvez récupérer tous les enregistrements en une passe (en passant par le Range.SpecialCells(xlCellTypeVisible))
    Voir éventuellement http://excel.developpez.com/faq/?page=Filtre
    Bonjour Vinc, il me semble qu'on ne peut pas filtrer un tableau de variables (array), et encore moins récupérer les SpecialCells(xlCellTypeVisible) ?!

    Citation Envoyé par boisgontierjacques Voir le message
    Bonjour,

    VL_Index_type_mvt_en_cours = WorksheetFunction.Match(VL_Type_mvt_en_cours, WorksheetFunction.Index(TBP_HL, ,1), 0) - 1

    Boisgontier
    Bonjour Jacques,
    J'avais testé cette solution, mais j'ai une erreur de compilation : argument non facultatif... ? Ça fonctionne chez toi ?

    Citation Envoyé par antonysansh Voir le message
    Un Enum peut etre top dans ton cas.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Enum eDate
        DA_Sortie = 0
        DA_Entree
        DD_Sortie
        DD_Entree
    End Enum
    [ ... ]

    Voila une utilisation possible :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Sub test()
        Dim TBP_HL(3, 2), i&, j&
        'Je remplis TBP_HL avec des dates
        For i = 0 To 3
            For j = 0 To 2
                TBP_HL(i, j) = Date + i * j
            Next j
        Next i
        'Si je veux DA_Sortie de Vin j'ecris :
        MsgBox TBP_HL(eDate.DA_Sortie, eType.Vin)
    End Sub
    Merci pour cette proposition Antony, je vais tester ça dans la journée car je ne connais pas cette fonction

    Merci à toutes vos propositions en tout cas ;-)

  6. #6
    Membre averti
    Homme Profil pro
    Chef d’entreprise
    Inscrit en
    Mai 2014
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Chef d’entreprise

    Informations forums :
    Inscription : Mai 2014
    Messages : 18
    Par défaut
    Citation Envoyé par antonysansh Voir le message
    Un Enum peut etre top dans ton cas.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Enum eDate
        DA_Sortie = 0
        DA_Entree
        DD_Sortie
        DD_Entree
    End Enum
    eDate.DA_Entree vaudra 1


    [ ... ]
    Je viens de capter que Enum n'est pas quelque chose qu'on inclut dans une procédure...
    Et vu que les types d'articles sont "dynamiques" ça ne peut pas correspondre ... à moins qu'on puisse faire un enum sur des valeurs venant d'un tableau de variables !
    Moi un coup ma macro n'aura que des vins + bieres, le coup d'après il y aura les champagnes en plus, etc...
    :-/

  7. #7
    Membre extrêmement actif
    Homme Profil pro
    Inscrit en
    Septembre 2013
    Messages
    1 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2013
    Messages : 1 369
    Par défaut
    Bonjour,

    J'avais testé cette solution, mais j'ai une erreur de compilation : argument non facultatif... ? Ça fonctionne chez toi ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Sub RecherchePositionElement2()
      a = [{"aa",11;"bb",22;"cc",33;"dd",44}]
      clé = "cc"
      p = Application.Match(clé, Application.Index(a, , 1), 0) ' Recherche dans colonne 1 du tableau a()
      MsgBox a(p, 2)
    End Sub
    Attention! Dans une boucle, Match n'est pas très rapide. Pour des tableaux importants, on peut indexer une colonne de tableau avec un dictionnaire.


    Cf PJ

    Boisgontier
    Fichiers attachés Fichiers attachés

  8. #8
    Membre averti
    Homme Profil pro
    Chef d’entreprise
    Inscrit en
    Mai 2014
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Chef d’entreprise

    Informations forums :
    Inscription : Mai 2014
    Messages : 18
    Par défaut Résolu, mais ...?
    Ca fonctionne, merci pour ton fichier joint, en reprenant tout, j'ai pu voir la différence :

    J'avais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    VL_Index_type_mvt_en_cours = WorksheetFunction.Match(VL_Type_mvt_en_cours, WorksheetFunction.Index(TBP_HL, , 1), 0) - 1
    Et ton exemple est avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    VL_Index_type_mvt_en_cours = Application.Match(VL_Type_mvt_en_cours, Application.Index(TBP_HL, , 1), 0) - 1
    Pourtant j'ai lu quelque part que "Application" était déprécié et qu'il valait mieux utiliser "WorksheetFunction" ??
    Deuxième chose étrange, pourquoi ma ligne de code précédente, avec "WorksheetFunction" fonctionne bien pour rechercher dans la 1ere colonne ?

    J'ai l'impression de passer à côté des bases : la différence entre Application et WorksheetFunction ... en même temps j'ai jamais eu de cours de VBA ^^

    Merci encore

  9. #9
    Expert éminent
    Avatar de Marc-L
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    9 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 9 468
    Par défaut

    Bonjour,

    WorkSheetFunction fonctionne uniquement s'il y a une correspondance mais en cas d'un retour en erreur, c'est mort !

    Tandis que la même fonction directement via Application (WorkSheetFunction étant aussi rattachée à Application !)
    combinée à une variable de type Variant est gérable via les fonctions VBA IsError et IsNumeric

    L'instruction Application ne peut être "dépréciée" car c'est Excel lui-même ‼ Ah les affres du marketing …

    _____________________________________________________________________________________________________
    Je suis Charlie, Bardo, Sousse

  10. #10
    Membre averti
    Homme Profil pro
    Chef d’entreprise
    Inscrit en
    Mai 2014
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Chef d’entreprise

    Informations forums :
    Inscription : Mai 2014
    Messages : 18
    Par défaut
    Merci pour cet éclaircissement... mais dans mon cas, je n'ai pas d'erreur en retour puisque j'ai un numéro d'index qui sort ??!

    Je comprends la notion où "Application" est parent de "Worksheet" .. mais je vois toujours pas pourquoi dans un cas ça fonctionne et dans l'autre pas ; mis à part la gestion d'erreurs, ce qui ne me concerne pas dans le cas présent.


  11. #11
    Expert éminent
    Avatar de Marc-L
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    9 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 9 468
    Par défaut



    Oui, comme je l'ai décrit, WorksheetFunction.Match ( fonction EQUIV de feuille de calculs, voir l'aide d'Excel)
    ne pose pas de problème lorsqu'une correspondance existe …

    Si c'est une erreur de compilation, c'est souvent une erreur de syntaxe dans le code …

  12. #12
    Membre extrêmement actif
    Homme Profil pro
    Inscrit en
    Septembre 2013
    Messages
    1 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2013
    Messages : 1 369
    Par défaut
    Il y a bien un pb de syntaxe avec WorksheetFunction (Argument non facultatif) alors qu'il n'y en a pas avec a =Application.Index(a, , 1)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Sub RecherchePositionElement2()
      a = [{"aa",11;"bb",22;"cc",33;"dd",44}]  ' tableau 2D
      clé = "cc"
      b = WorksheetFunction.Index(a, , 1)       ' Recherche dans colonne 1 du tableau a()
      MsgBox UBound(a)
    End Sub
    Boisgontier

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 13/01/2011, 22h09
  2. Recherche dans une colonne
    Par david71 dans le forum Access
    Réponses: 4
    Dernier message: 26/06/2007, 20h37
  3. Recherche dans une colonne tableau Word
    Par cath007 dans le forum VBA Word
    Réponses: 2
    Dernier message: 13/06/2007, 17h35
  4. [XSL~FO] Débordement dans une colonne d'un tableau
    Par palmelas dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 29/01/2007, 20h59
  5. [VBA-E] Recherche dans une colonne
    Par snowkhan dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 03/03/2006, 14h21

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo