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 :

rechercher une valeur et concaténer


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Candidat au Club
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juillet 2011
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2011
    Messages : 2
    Par défaut rechercher une valeur et concaténer
    Bonjour à tous,

    Je débute en excel et encore plus en VBA (zéro base).

    Je souhaiterai effectuer la recherche d'une valeur dans une colonne X
    et renvoyer la valeur correspondante d'une autre colonne X+1 dans une
    cellule en colonne X+X. Le problème est que l'on peut trouver cette
    première valeur dans plusieurs lignes de la colonne X et que les
    valeurs correspondantes en colonne X+1 sont toutes différentes. C'est
    pour cela que je souhaite les concaténer dans une cellule en colonne
    X+X.

    Un exemple pour plus de compréhension:

    1 Arbre
    2 mouton
    3 Arbre
    4 route
    5 Arbre
    6 route
    7 mouton
    8 Arbre
    9 route
    10 route

    Je souhaite ainsi faire apparaître dans la cellule en colonne X+X les
    valeurs suivantes: 1;3;5;8; (voir plutot l'un en dessous de l'autre plutôt que ";" si possible).

    Je suppose qu'il faut obligatoirement passer par du VBA...

    Voilà j’espère avoir été assez claire et je vous remercie d'avance
    pour l'aide apportée.

    Charly

  2. #2
    Expert confirmé Avatar de jfontaine
    Homme Profil pro
    Contrôleur de Gestion
    Inscrit en
    Juin 2006
    Messages
    4 756
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Contrôleur de Gestion

    Informations forums :
    Inscription : Juin 2006
    Messages : 4 756
    Par défaut
    Bonjour,

    Ci dessous une solution avec l'instruction Find

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    Sub RechercheConcat()
     
    Dim StrValeur As String
    Dim Rg As Range
    Dim RgCible As Range
     
    Dim Plage As Range
    Dim Adresse As String
    Dim StrRetour As String
     
    'Colonne de recherche
    Set Rg = Sheets("Feuil1").Range("B:B")
     
    StrValeur = "Lundi"
     
    Set Plage = Rg.Find(StrValeur)
     
    If Not Plage Is Nothing Then
     
        Adresse = Plage.Address
     
        Do
     
        'Le 1 représentant la numero de colonne a concatener
        If StrRetour <> "" Then StrRetour = StrRetour & ";"
        StrRetour = StrRetour & Cells(Plage.Row, 1).Value
     
        Set Plage = Rg.FindNext(Plage)
     
        Loop While Not Plage Is Nothing And Plage.Address <> Adresse
     
    End If
     
    MsgBox StrRetour
     
    End Sub

  3. #3
    Membre chevronné
    Profil pro
    Inscrit en
    Juillet 2011
    Messages
    141
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2011
    Messages : 141
    Par défaut A la ligne dans une cellule
    Bonjour grosyouyou,

    Dans la solution précédente, j'ai remplacé StrValeur = "Lundi" par :
    Il faut également adapter le nom de la feuille si elle ne s'appelle pas "Feuil1".
    L'appel de la procédure RechercheConcat() m'a affiché la boîte de dialogue avec le message : "3;5;8;1".
    ___________

    A la ligne dans une cellule

    Voici une solution sans le Find du Range d'Excel, c-a-d en VBA basique.

    Avec l'Excel menu "Outils" > "Options" > onglet "General"
    cochez l'option [x] R1C1 reference style.

    Dans la feuille de calcul de R1C1 à R10C1 on a les nombres de 1 à 10.
    Traduire de la rangée rowStart à rowEnd en colonne colValue.

    De R1C2 à R10C2 on a la liste des mots indiqués.
    Traduire de la rangée rowStart à rowEnd en colonne colWord.

    Agrandir la rangée 11 d'une hauteur au moins quatre fois plus grande qu'une cellule classique pour afficher le résultat en R11C3.
    Traduire en rangée rowResult, colonne colResult.

    Ouvrir le Visual Basic Editor par Alt+F11 ou
    Excel menu "Outils" > "Macro" > "Visual Basic Editor" (VBE)

    Cliquez sur le VBE menu "Insérer" > "Module"
    Dans sa fenêtre d'édition, copier-coller le code VBA suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    Option Explicit
    Public Const rowStart = 1               ' Input
    Public Const rowEnd = rowStart + 9
    Public Const rowResult = rowEnd + 1     ' Output: rangée X+X
     
    Public Const colValue = 1               ' Input
    Public Const colWord = colValue + 1     ' Colonne X
    Public Const colResult = colWord + 1    ' Output: Colonne X+X
     
    Sub SearchWord(ByVal strWord As String)
    Dim indRow As Integer, strResult As String, nbrOccurence As Integer
     
        nbrOccurence = 0
        strResult = ""
        For indRow = rowStart To rowEnd
            If Cells(indRow, colWord) = strWord Then
                If nbrOccurence > 0 Then
                    strResult = strResult + vbCrLf ' The one under the others
                End If
                strResult = strResult + CStr(Cells(indRow, colValue)) ' Concatenate
                nbrOccurence = nbrOccurence + 1
            End If
        Next
        If nbrOccurence > 0 Then
            Cells(rowResult, colResult) = strResult
        End If
    End Sub
    Dans la fenêtre d'Exécution immédiate (Ctlr+G) du VBE, copier-coller et valider par ENTER :
    Voir le résultat des quatres valeurs de la recherche concaténées sur quatre lignes de texte à l'intérieur d'une seule cellule R11C3 grâce au retour-chariot (VbCrLf) ajouté après chaque valeur.
    Dans la fenêtre d'Exécution immédiate (Ctlr+G) du VBE :
    affiche en R11C3 :
    ___________

    En bas de ce message s'il vous a apporté des éléments de réponse pertinents, pensez également à voter en cliquant sur le bouton vert ci-dessous.

  4. #4
    Candidat au Club
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juillet 2011
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2011
    Messages : 2
    Par défaut
    Merci à tous pour vos réponse, je m'excuse je viens seulement de regarder vos réponse.

    Vos réponse sont parfaites mais pas tout à fait ce que je souhaite faire => de ma faute je n'ai pas été assez clair.

    Je vous joins un excel précisant ce que je souhaite: j'ai réussi avancer un peu mais je suis bloqué...

    Comme vous le verrez, j'arrive a trouver les nombres pour une valeur cherchée mais pas pour tous en une seul exécution.

    Merci d'avance pour votre aide.

    dsl pour les fautes d'orthographe
    Fichiers attachés Fichiers attachés

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 125
    Billets dans le blog
    131
    Par défaut
    Salut


    Citation Envoyé par grosyouyou Voir le message
    ...Je suppose qu'il faut obligatoirement passer par du VBA...
    Sans VBA, tu pourrais passer par le filtre élaboré...
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes billets de blog sur DVP
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Pensez à utiliser les tableaux structurés. Ils vous simplifieront la vie, tant en Excel qu'en VBA ==> mon tuto
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    ---------------

  6. #6
    Membre chevronné
    Profil pro
    Inscrit en
    Juillet 2011
    Messages
    141
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2011
    Messages : 141
    Par défaut SearchWord() dans une formule d'une cellule
    grosyouyou, finalement le résultat est à afficher dans une seconde feuille dénommée "Recherche". Vous allez pouvoir comparer ce que j'ai changé entre ma première version et cette version.

    La première chose à faire dans l'énoncé d'un problème est de fournir la déclaration des constantes. Cela permet immédiatement de comprendre qu'il y a deux feuilles :

    • "Feuil1" de données de référence en lecture seule : c'est la source.
    • "Recherche", la feuille des mots clés à chercher ainsi que la zone des résultats : c'est la cible [Target].



    De plus ces constantes permettent tout de suite de savoir où trouver les données et où afficher le résultat. C'est une étape indispensable dans la résolution du problème même si on peut penser que la solution a l'air plus longue. En fait cela documente le programme et permet de mieux le comprendre si on doit le faire évoluer dans quelques mois.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    Option Explicit
    Public Const indSheetSource = 1         ' Source : Données de référence
    Public Const rowStart = 1
    Public Const rowEnd = rowStart + 9
     
    Public Const colValue = 1
    Public Const colWord = colValue + 1     ' Colonne X
     
    Public Const indSheetTarget = 2         ' Cible : Mot clé à chercher et résultat
    Public Const rowKeywordBegin = 5
    Public Const rowKeywordEnd = 7
     
    Public Const colKeyword = 2             ' Colonne des mots clés
    Public Const colResult = colKeyword + 1 ' colonne appelée "X X"
     
    Sub FindWords()
    Dim indRow As Integer, strWord As String
     
        With Worksheets(indSheetTarget)
            For indRow = rowKeywordBegin To rowKeywordEnd
                strWord = .Cells(indRow, colKeyword)
                .Cells(indRow, colResult) = SearchWord(strWord)
            Next
        End With
    End Sub
     
    Function SearchWord(ByVal strWord As String) As String
    Const strSep = ";" ' Pour un retour-chariot remplacer par vbCrLf
    Dim indRow As Integer, strResult As String, nbrOccurence As Integer
     
        nbrOccurence = 0
        strResult = ""
        With Worksheets(indSheetSource)
            For indRow = rowStart To rowEnd
                If .Cells(indRow, colWord) = strWord Then
                    If nbrOccurence > 0 Then
                        strResult = strResult + strSep
                    End If
                    strResult = strResult + CStr(.Cells(indRow, colValue)) ' Concatenate
                    nbrOccurence = nbrOccurence + 1
                End If
            Next
        End With
        SearchWord = strResult
    End Function
    Usage de SearchWord() et résultat attendu

    Dans la fenêtre d'Exécution immédiate (Ctlr+G) du VBE, copier-coller et valider par ENTER :
    Notez le pluriel à la fin de Words.

    Dans la feuille n° 2 "Recherche", le résultat suivant s'affiche de C5 à C7 soit de R5C3 à R7C3 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    2;7
    1;3;5;8
    4;6;9;10
    Quand on programme en VBA, on a tout intérêt de basculer en notation R1C1.
    C-a-d éviter Range("A1"). Préférez Cells(1,1) plus performant.

    Test de la fonction SearchWord()

    On a changé Sub SearchWord() en Function retournant le résultat de la recherche.
    Cela veut dire que l'on peut directement la tester dans la fenêtre d'Exécution immédiate :

    1;3;5;8

    Dans la procédure FindWords(), on appelle SearchWord(strWord) dans une boucle For Next pour chaque mot clé de la rangée 5 à la rangée 7 en colonne 2.

    On est passé au séparateur ";" dans la liste des résultats concaténés. Voir la constante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Const strSep = ";" ' Pour un retour-chariot remplacer par vbCrLf
    Référence la première solution.

    SearchWord() dans une formule d'une cellule

    Dans la feuille de calcul, dupliquons, dans la même colonne "B", le dernier mot-clé "route" juste dessous, de B7 à B8 soit de R7C2 à R8C2.
    Dans la cellule de résultat C8 soit R8C3, entrons la formule inédite :
    Quand on valide la formule, la cellule présente le résultat :

    SearchWord() peut donc être utilisée comme nouvelle fonction dans les formules de cellules !

    On aurait pu aisément dupliquer cette formule dans toute la colonne C de résultat plutôt que de coder la boucle For Next dans FindWords().

    Optimisation

    Une fois que tout fonctionne comme souhaité, vous pouvez optionnellement optimiser le cœur de la recherche dans la fonction SearchWord() en intégrant la solution de jfontaine.

    Quand la plage de recherche sera beaucoup plus importante (plusieurs centaines de rangées), vous pourrez ainsi mesurer si on gagne du temps avec Rg.Find(StrValeur) et combien.

    Dans un premier temps c'est la structuration du programme qui importe. D'abord les constantes puis des procédures Sub ou Function courtes faciles à mettre au point avec des noms de variables significatifs. Ensuite on peut optimiser et mesurer la performance.
    ___________

    Si la discussion est résolue, vous pouvez cliquer sur le bouton

    En bas de ce message s'il vous a apporté des éléments de réponse pertinents, pensez également à voter en cliquant sur le bouton vert ci-dessous.

Discussions similaires

  1. Recherche une valeur d'une cellule dans une colonne d'une autre feuille
    Par kourria dans le forum Macros et VBA Excel
    Réponses: 8
    Dernier message: 21/06/2007, 13h48
  2. [find] Comment rechercher une valeur dans une matrice
    Par VanessaDu67 dans le forum MATLAB
    Réponses: 6
    Dernier message: 06/06/2007, 14h55
  3. expresson reguliere recherche une valeur non presente
    Par mikebranque dans le forum Langage SQL
    Réponses: 4
    Dernier message: 09/05/2007, 16h13
  4. Rechercher une valeur dans un tableau
    Par pafi76 dans le forum Access
    Réponses: 2
    Dernier message: 29/06/2006, 14h23
  5. Réponses: 7
    Dernier message: 26/10/2004, 11h02

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