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 :

Extraction de multiples chaines de caractères de tailles variables [XL-2010]


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Inscrit en
    Janvier 2013
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Janvier 2013
    Messages : 28
    Par défaut Extraction de multiples chaines de caractères de tailles variables
    Bonjour,

    J'ai une cellule A1 avec un texte contenant des slashs (/). Le nombre de parties/slashs est variable et le nombre de caractères de chaque partie est également variable.

    Exemples :
    aa/b/ccc/d/ee/f/gg/hhh
    aa/b/ccc/d/ee
    aa/b/ccc
    aa/b
    aa

    Pour l'instant je trouve la première et la deuxième parties.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    A2 = GAUCHE(A1;CHERCHE("/";A1)-1)
    A3 = DROITE(GAUCHE(A1;CHERCHE("/";A1;CHERCHE("/";A1)+1)-1);
    CHERCHE("/";A1;CHERCHE("/";A1)+1)-CHERCHE("/";A1)-1)
    Les parties suivantes me posent problème. Mais peut-être que je pars mal dès les premières parties ?
    Comment extraire dans les cellules A2, A3, A4, A5, A6, ... les différentes parties contenues avant/entre/après les slash (c'est à dire aa en A2, b en A3, ccc en A4, etc) ?
    Je préfèrerais éviter les solutions à base d'expressions régulières, que je ne maîtrise pas encore (sauf si c'est nettement plus efficace et polyvalent évidemment).
    Pour mon usage le meilleur système serait un système où je pourrais extraire la chaine en définissant la position du slash d'avant et du slash d'après (ex : trouver le texte entre le 4ème et le 5ème slash).

    Pourriez-vous m'aider s'il vous plait ?
    Merci pour votre aide !

  2. #2
    Expert confirmé

    Homme Profil pro
    Curieux
    Inscrit en
    Juillet 2012
    Messages
    5 169
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Curieux
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2012
    Messages : 5 169
    Billets dans le blog
    5
    Par défaut
    Bonjour,

    la fonction Split() est ton ami ! Regarde l'aide en ligne pour comprendre ma proposition

    je découpe ta chaine avec les slash en séparateurs, et tant qu'on a des morceaux, on les écrits les uns après les autres

    ainsi, tu n'as pas à gérer le nombre de slash existants, la taille des portions etc... tout est dynamique sur ce point

    cet exemple correspond à ton premier exemple (aa/b/ccc/d/ee/f/gg/hhh), écrit en A1 de la feuille active, avec renvoi des morceaux en B1 - C1 - D1 etc... de la feuille active

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Cells(1, 2).Resize(1, UBound(Split(Cells(1, 1).Value, "/")) + 1).Value = Split(Cells(1, 1).Value, "/")
    il te reste simplement :

    - à créer une boucle pour parcourir ta colonne et à chaque tour de boucle utiliser cette proposition
    - mieux encore (mais pas obligatoire) : transformer cette proposition en une procédure standard, que tu pourras appeler à plusieurs endroits de ton projets si besoin


    EDIT : puisque j'ai fait le radin sur les lignes de code (une seule), voici quand même un exemple un peu plus riche pour que tu puisses comprendre la mécanique
    ce n'est encore une fois qu'une proposition à totalement customiser

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Sub toto()
    Const SEPARATEUR As String = "/"
    Dim MesMorceaux
        MesMorceaux = Split(Cells(1, 1).Value, SEPARATEUR)
        ' on commence en B1 et on va s'étendre sur autant de colonnes que de morceaux
        '                          | |
        '                           v
        Cells(1, 2).Resize(1, UBound(MesMorceaux) + 1).Value = MesMorceaux
    End Sub

  3. #3
    Expert confirmé

    Homme Profil pro
    Curieux
    Inscrit en
    Juillet 2012
    Messages
    5 169
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Curieux
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2012
    Messages : 5 169
    Billets dans le blog
    5
    Par défaut
    Désolé du double post, je rebondis sur la dernière demande

    si tu veux pouvoir choisir les portions de ton choix, Split() de le permet aussi

    ici par exemple, je vais afficher dans une boite de dialogue :

    - le nombre de morceaux
    - le morceau numéro 4
    - si le morceau n'existe pas : on te l'indique

    toujours basé sur ton premier exemple
    j'ai mis un paquet de variables pour ta compréhension, mais elles ne sont pas obligatoire
    et comme toujours, à totalement adapter

    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
    Sub toto()
    Const SEPARATEUR As String = "/"
    Dim NumMorceaux As Long
    Dim MonMorceaux As String
    Dim MesMorceaux
        MesMorceaux = Split(Cells(1, 1).Value, SEPARATEUR)
        NumMorceaux = 4
     
        If UBound(MesMorceaux) + 1 < NumMorceaux Then MonMorceaux = " n'existe pas" Else MonMorceaux = " est : " & MesMorceaux(NumMorceaux - 1)
     
        MsgBox ("Il y a " & UBound(MesMorceaux) + 1 & " morceaux dans la chaine suivante : " & vbCrLf & _
               Cells(1, 1).Value & vbCrLf & _
               "Le morceau numéro " & NumMorceaux & MonMorceaux)
     
     
    End Sub

  4. #4
    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 !

    Citation Envoyé par Thierry360 Voir le message
    Comment extraire dans les cellules A2, A3, A4, A5, A6
    Par le B-A-BA d'Excel via le menu Données, Convertir ! Il suffit ensuite de bien répondre à l'assistant …
    Et en activant l'Enregistreur de macros, une base de code est livrée sur un plateau !

    Sinon pour ceux n'ayant pas peur de lire, tout est expliqué dans l'aide VBA de la méthode TextToColumns

    Les expressions régulières sont effectivement les plus efficaces.

    _________________________________________________________________________________________________________
    Je suis Paris, Charlie, Bruxelles, …

  5. #5
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    3 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 3 453
    Par défaut
    Bonjour,

    Tu peux aussi te faire une fonction perso :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    Function BLOC(Cel As Range, Sep As String, Pos As Long)
     
        'valeur retournée si Pos supérieur au nombre de blocs
        BLOC = ""
     
        'dans le cas contraire, retourne le bloc désiré
        If Pos < UBound(Split(Cel.Value, Sep)) + 1 Then
     
            BLOC = Split(Cel.Value, Sep)(Pos - 1)
     
        End If
     
    End Function
    Que tu utilise de cette façon :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    =BLOC($C$1;"/";B1)
    Où en C1 se trouve ta chaîne et en B1 et Bx les positions ordinales du bloc considéré et ensuite, tu tire vers le bas

  6. #6
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 374
    Billets dans le blog
    8
    Par défaut re
    Bonjour
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Sub test1()
    'on remplace les saut de ligne sous toute ses formes
    texte = Replace(Replace(Replace([A1].Value, vbCrLf, ""), Chr(10), ""), Chr(13), "")
    Debug.Print texte
    'on créé le tableau
    tablo = Split(texte, "/")
    'on remet le tableau en place a partir de A1 :chaque partie sera dans une cellule 
    Cells(1, 1).Resize(UBound(tablo), 1) = tablo
    End Sub
    mes fichiers dans les contributions:
    mail avec CDO en vba et mail avec CDO en vbs dans un HTA
    survol des bouton dans userform
    prendre un cliché d'un range

    si ton problème est résolu n'oublie pas de pointer : : ça peut servir aux autres
    et n'oublie pas de voter

  7. #7
    Expert confirmé
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4 253
    Par défaut
    hello,
    voici une autre solution en utilisant les expressions rationnelles. Cela consiste en une fonction personnalisée qui a deux paramètres. Le premier paramètre est la cellule sur laquelle on fait le traitement. Le deuxième paramètre qui est optionnel est la position de l'élément à extraire (0 pour le premier). Cette formule marche aussi en matricielle ligne ou colonne.
    La voici :
    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
    Public Function SplitChaineMulti(MaCellule, Optional pos As Variant)
        ' J.P  juin 2016
        Dim myTarg As Range
        Dim regEx As New RegExp
        Dim OMatches, OMatch
        Dim Rslt() As String
        Dim NbElem, DimRslt As Integer
        If IsMissing(pos) Then pos = 0
         With regEx
            .Global = True
            .IgnoreCase = False
            'le motif consiste à capturer tout ce qui n'est pas /
            .Pattern = "([^/])+"
         End With
        Set myTarg = Application.Caller
        If myTarg.Rows.Count > 1 And myTarg.Columns.Count > 1 Then
        MsgBox "Vous ne pouvez pas sélectionner plusieurs lignes et " & vbCrLf & _
               " plusieurs colonnes  dans la formule !"
        Exit Function
        End If
         ' On recherche tous les éléments
        Set OMatches = regEx.Execute(MaCellule)
        NbElem = OMatches.Count
        '  On dimensionne le tableau de résultat au
        ' max entre les lignes et les colonnes
        If myTarg.Rows.Count > myTarg.Columns.Count Then
        DimRslt = myTarg.Rows.Count
        Else
        DimRslt = myTarg.Columns.Count
        End If
        ReDim Rslt(1 To DimRslt)
        For i = LBound(Rslt) To UBound(Rslt)
        If i + pos <= NbElem Then
        Rslt(i) = OMatches(i - 1 + pos)
        Else
        Rslt(i) = ""
        End If
        Next
        'On transpose si on a une formule sur plusieurs lignes
        If myTarg.Rows.Count > 1 Then
        SplitChaineMulti = Application.Transpose(Rslt)
        Else
        SplitChaineMulti = Rslt
        End If
    End Function
    et voici un exemple d'utilisation :
    1 - en D1 on a rentré la formule =SplitChaineMulti(A1;2) on prend le 3ème élément
    2 - en A4:A8 on a rentré la formule matricielle =SplitChaineMulti(A1) (sélectionner les cellules A4:A8 puis rentrer la formule puis valider par CTRL + MAJ + Entrée)
    3 - en D3:H3 on a rentré la formule matricielle =SplitChaineMulti(A1;1) (sélectionner les cellules D3:H3 puis rentrer la formule puis valider par CTRL + MAJ + Entrée)

    voici le résultat :

    Nom : SplitChaineMulti.png
Affichages : 1133
Taille : 11,7 Ko

    Il doit y avoir quelques bugs dans le code et des optimisations à faire . L'avantage d'utiliser la fonction en matricielle c'est qu'on ne passe qu'une seule fois dans le code vba quelque soit le nombre de lignes ou le nombre de colonnes sur laquelle s'applique la formule.

    Ami calmant, J.P

  8. #8
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 374
    Billets dans le blog
    8
    Par défaut re
    re
    pas mal du tout le dinosaure!!
    mais tu te leurre en disant que le code passe une fois

    a chaque cellule que tu sélectionne le code fera son tour

    après pour la chaine a splitter c'est un peu lourd le regex sachant que le découpage n'a pas besoins de beaucoup d'arguments
    mes fichiers dans les contributions:
    mail avec CDO en vba et mail avec CDO en vbs dans un HTA
    survol des bouton dans userform
    prendre un cliché d'un range

    si ton problème est résolu n'oublie pas de pointer : : ça peut servir aux autres
    et n'oublie pas de voter

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

Discussions similaires

  1. Réponses: 7
    Dernier message: 05/04/2009, 11h40
  2. Réponses: 2
    Dernier message: 05/03/2009, 17h06
  3. chaine de caractère de taille inconnue !
    Par Mister Ghazi dans le forum Débuter
    Réponses: 3
    Dernier message: 16/01/2009, 20h46
  4. Extraction d'une chaine de caractère
    Par ozzy75 dans le forum Développement
    Réponses: 0
    Dernier message: 26/10/2008, 12h23
  5. Extraction d'une chaine de caractères
    Par megane dans le forum Langage
    Réponses: 2
    Dernier message: 05/01/2004, 15h52

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