Modification de caractères selon détection d'un certain caractère

Bonjour à tous,

Pour diverses raisons professionnelles, je passe de l'électronique à de la programmation VBA. J'ai essayé de me débrouiller avec les ressources du net mais je bloque.

Mon objectif dans un premier temps est de pouvoir convertir tous les signaux qui commencent par IO quelque chose en IOBANK+numéro de la 3e colomne (IOBANK13 par exemple) et de garder uniquement les 2ers groupes de mots après IO avec un swap entre les 2 groupes de mots.

Pa exemple si on prend IO_L15P_T2_DQS_13, le résultat devrait finir en : IOBANK13_T2_L15P. Et ce pour tous les cases où il y a IO d'écrit.

J'ai réussi à changer le début pour avoir IOBANK dès que le mot IO est détecté mais sans plus. L'un des problèmes est que j'ai tenté de stocké les valeurs des numéros (colomne C) dans un tableau mais je me retrouve avec un décalage quand je fais une sorte de concaténation avec ce tableau.

Je ne sais pas si c'est vraiment clair, n'hésitez pas à me reposer des questions si ca ne l'est pas.

Merci d'avance.

16test.xlsm (43.88 Ko)

Bonjour,

Une première piste comme ceci ?

Sub test()
With Sheets("Feuil1")
    dl = .Cells(.Rows.Count, 2).End(xlUp).Row
    ReDim t(1 To dl, 1 To 1)
    For i = LBound(t) To dl
        If Left(.Cells(i, 2), 2) <> "IO" Then
            t(i, 1) = .Cells(i, 2)
        Else
         tableau = Split(.Cells(i, 2), "_")
            t(i, 1) = "IOBANK_" & tableau(2) & "_" & tableau(1) & "_" & .Cells(i, 3)
        End If
    Next i
    .Cells(1, 7).Resize(UBound(t)).Value = t
End With
End Sub

Tu n'as pas vraiment dit ce que tu voulais faire dans les autres cas, donc tu pourras adapter.

Bonjour,

Les explications ne sont pas claires, je viens de regarder les données, et je ne comprends cette histoire de groupes.

Vous dites:

"et de garder uniquement les 2ers groupes de mots après IO avec un swap entre les 2 groupes de mots."

Ok c'est bien, mais il est où le 2ème groupe dans "IO_L3N_T0_DQS_EMCCLK_14"? et dans "IO_0_14"? ou encore dans "IO_L15N_T2_DQS_DOUT_CSO_B_14"?

C'est pas clair pour moi, donc je ne peux pas produire de code...

@Formatic, je regarde ça dès que je peux et ferais un retour dès que possible, merci !

@Ausecour, méa culpa je n'avais pas fais gaffe à toutes les données et cela change en fonction du composant. Du coup le changement de données serait essentiellement pour les données "IO_L quelque chose". Pour le reste je vais devoir voir en fonction de nos règles de nommage.
Concernant les groupes, la donnée brute est comme ceci : IO_L3P_T0_DQS_13 et doit se transformer en IO_T0_L3P, il y a un swap entre T0 et L3P, au vu des données, les noms sont toujours comme ceci : Groupe1_Groupe2_Groupe3_GroupeX mais nous coupons au groupe 3.

En espérant avoir été plus clair.

C'est ce que fait ma proposition.

Si tu dois adapter à IO_L et non plus seulement IO, tu as juste à adapter la fonction Left() dans la macro.

D'ailleurs, je ne suis pas certain d'avoir compris tout ce que j'ai proposé (notamment au niveau de la déclaration du tableau). Si quelqu'un voit une façon plus "propre" de faire, que cette personne se manifeste :)

ReDim t(1 To dl, 1 To 1)

Pour un tableau unidimensionnel, peut-on faire autrement ?

C'est ce que fait ma proposition.

Si tu dois adapter à IO_L et non plus seulement IO, tu as juste à adapter la fonction Left() dans la macro.

D'ailleurs, je ne suis pas certain d'avoir compris tout ce que j'ai proposé (notamment au niveau de la déclaration du tableau). Si quelqu'un voit une façon plus "propre" de faire, que cette personne se manifeste :)

ReDim t(1 To dl, 1 To 1)

Pour un tableau unidimensionnel, peut-on faire autrement ?

Ce que tu as fais me semble bien par rapport à la déclaration.

Le passage par ReDim me semble obligatoire comme c'est le seul moment où on peut insérer une variable pour la dimension du tableau. Et pour le fait que ce soit un tableau à deux dimensions c'est normal je dirais, à chaque fois que je fais tableau = Plage, je me retrouve avec un tableau à deux dimensions. De ce que j'en ai compris c'est obligé pour pouvoir ensuite dire ma Plage = mon tableau modifié.

Faire plus propre...

Peut-être qu'à la place de ça :

If Left(.Cells(i, 2), 2) <> "IO" Then

j'aurais mis:

If Not .Cells(i, 2) Like "IO*" Then

Mais sinon je ne vois pas trop

Merci pour la réponse :)

Non mais c'est ça, je suis tout le temps tenté de mettre une variable dans la déclaration du tableau et ça ne passe pas toujours. Du coup je recopie une structure que je sais fonctionnelle, mais sans tout comprendre.

Il faudrait que je me replonge un peu plus dans tout ça maintenant que je vois un peu mieux comment cela fonctionne.

@formatic If Left(.Cells(i, 2), 2) <> "IO" Then

Juste comme retour, cette ligne ne fonctionne pas mais @ausecour l'a apparemment remarqué immédiatement. Du coup voici le code légèrement remanié pour convenir à ce que j'avais écrit comme nommage dans mon 1er post.

Sub test()
With Sheets("Feuil1")
    dl = .Cells(.Rows.Count, 2).End(xlUp).Row
    ReDim t(1 To dl, 1 To 1)
    For i = LBound(t) To dl
        If Not .Cells(i, 2) Like "IO_L*" Then
            t(i, 1) = .Cells(i, 2)
        Else
         tableau = Split(.Cells(i, 2), "_")
            t(i, 1) = "IOBANK" & .Cells(i, 3) & "_" & tableau(2) & "_" & tableau(1)
        End If
    Next i
    .Cells(1, 7).Resize(UBound(t)).Value = t
End With
End Sub

Un énorme merci à vous 2 pour l'aide, je vais maintenant plonger dans le code pour le comprendre et pouvoir l’agrandir dans le futur. Difficile de replonger dans ce genre de programmation étant plus axé programmation orienté objet dans le passé mais j'y crois :)

Apparemment l'édition de message bug aujourd'hui.

@formatic If Left(.Cells(i, 2), 2) <> "IO" Then

Juste comme retour, cette ligne ne fonctionne pas mais @ausecour l'a apparemment remarqué immédiatement. Du coup voici le code légèrement remanié pour convenir à ce que j'avais écrit comme nommage dans mon 1er post.<p><br></p>

Cette ligne fonctionnait très bien sur le principe de ce que tu demandais initialement. Ne sachant pas ce que tu voulais pour de vrai, je t'avais dit qu'il fallait effectivement la modifier en fonction ...

Pour info, ce que donnait Ausecour était blanc bonnet et bonnet blanc.
Par contre, la modification que tu as effectuée ne donnera pas le résultat que tu escomptes...
@formatic If Left(.Cells(i, 2), 2) <> "IO" Then

Juste comme retour, cette ligne ne fonctionne pas mais @ausecour l'a apparemment remarqué immédiatement. Du coup voici le code légèrement remanié pour convenir à ce que j'avais écrit comme nommage dans mon 1er post.

Cette ligne fonctionnait très bien sur le principe de ce que tu demandais initialement. Ne sachant pas ce que tu voulais pour de vrai, je t'avais dit qu'il fallait effectivement la modifier en fonction ...

Pour info, ce que proposait Ausecour était blanc bonnet et bonnet blanc. Juste une autre façon d'écrire la même chose.
Par contre, la modification que tu as effectuée ne donnera pas le résultat que tu escomptes...

pratique quand on a édité 2 fois !

Loin de moi de vouloir blamer quelqu'un qui m'a aidé surtout avec mon niveau ... C'était juste pour faire un retour. En lançant le code je n'ai eu aucun résultat, en prenant la ligne d'ausecour, il y a eu un changement, hélas je n'ai pas les connaissances nécessaires pour savoir pourquoi.

Puis-je savoir pourquoi mes changements ne donneront pas le résultat que je souhaite si possible ? Je me suis contenté de faire des modifications qui m'ont donné ce que j'attendais mais peut-être que faire des changements en dur poseront problème pour plus tard ?

Merci à toi.

PS : Comment fait-on pour cité un message ? J'ai testé le bouton citation mais ca n'a pas fonctionné comme prévu

Pour le côté citation, j'ai l'impression qu'il est aussi instable que l'édition aujourd'hui.

Pour ce qui est de ta solution, j'ai lu trop vite. Je pensais que tu étais resté sur la structure avec left() et que tu n'avais pas adapté le nombre de caractères à vérifier. Donc en cherchant "IO_L" sur les 2 premiers caractères, il n'aurait jamais pris en compte le _L.
Mais, et j'en suis désolé, j'avais lu trop vite. Ce que tu as écrit te donnera la solution sans souci.
Reste à savoir pourquoi la proposition initiale n'allait pas ici, puisque ça fonctionnait très bien sur ton fichier sur mon ordinateur.

Tu as modifié également la plage de destination finale ?

Je n'ai pas modifié plage de destination (d'ailleurs j'ai vraiment apprécié le geste, je m'attendais à un résultat directement sur les valeurs d'origine), juste la condition et la valeur modifié finale.

Bonjour,

Je n'ai rien suivi des derniers échanges et n'ai absolument pas compris, sûrement à cause des citations et des éditions de message, du coup le problème est résolu ou pas du tout?

Bonjour,

J'ai eu mon élément de réponse par rapport à mon 1er post. J'essaye du coup maintenant de faire un tri décroissant des valeurs avec une double boucle mais je pense que je suis en train de me perdre, j'implore donc de nouveau votre aide.

La donné finale ressemble à ceci : IOBANK13_T1_L9P, j'aimerais que le tri se fasse sur la partie "T1" (2e groupe de caractère) dans un premier temps donc les T3 ensuite les T2, ensuite les T1 etc. Lorsque c'est fait de faire un tri sur le 3e groupe de caractère, les "L9P" par exemple. A la base je pensais que le Sort suffirait mais d'après ce que j'ai compris, cela ne fonctionne pas bien vu que comme les valeurs numériques sont considérés comme du texte on a un 9 qui se retrouve devant un 23 par tri décroissant.

DL = .Cells(.Rows.Count, 2).End(xlUp).Row
    ReDim t(1 To DL, 1 To 1)
    For I = LBound(t) To DL
    For J = I + 1 To DL
        If Not .Cells(I, 2) Like "IO_L*" Then 'si caractère différent de IO_L on copie l'original
            t(I, 1) = .Cells(I, 2)
        Else
         tableau = Split(.Cells(I, 2), "_")

            t(I, 1) = "IOBANK" & .Cells(I, 3) & "_" & tableau(2) & "_" & tableau(1)
        End If
        If tableau(I) < tableau(J) Then
        Temp = tableau(I)
        tableau(J) = tableau(I)
        tableau(J) = Temp
        End If
        Next J
        Next I
    .Cells(1, 7).Resize(UBound(t)).Value = t

J'étais parti sur quelque chose comme ça en partant du code solution (c'est juste un bout de code brouillon de départ et surement une catastrophe), comme un tri classique mais je pense qu'aussi peu de code ne suffira pas (et je reste bloqué dans la boucle J, je pense qu'il me manque une bonne compréhension des boucles VBA et même général)

Encore merci d'avance.

Bonjour,

Je pense en effet que vous êtes entrain de vous perdre,

A mon avis il ne faut pas mélanger la boucle de modification du texte avec le tri.

Surtout que dans ce cas, le tri n'est pas simple, il faut selon moi:

isoler le nombre dans T##, isoler le nombre dans L##P, L##N pour ensuite pouvoir les utiliser pour le tri.

Une proposition (je ne gère pas les N et les P):

2test-2.xlsm (66.61 Ko)

Merci pour la proposition, ca en fait des lignes comparé à ce que je pensais. Du coup j'ai légèrement changé le code pour tester et avoir ce que je voulais dans cette partie (c'est de ma faute vu que je n'ai pas tout énoncé)

    'recherche de la ligne à échanger
    For x = I + 1 To UBound(tableau, 1)
        If tableau(x, 1) < tableau(ligTri, 1) Then
            ligTri = x
        ElseIf tableau(x, 1) = tableau(ligTri, 1) Then
            If tableau(x, 2) > tableau(ligTri, 2) Then
            If tableau(x, 3) > tableau(ligTri, 3) Then
                ligTri = x
            End If
        End If
        End If

Problème, cela fait un tri complet de la colonne.

Le tableau final devrait être dans l'ordre des Banks, c'est à dire la colonne C, de 0 à X. Le tri doit se faire uniquement sur les lignes commençant par IO (et donc conserver les autres lignes comme elles sont si ce ne sont pas des IO). Les BANKX doivent être croissants, les TX doivent être décroissants et de même pour les LX et techniquement les P en 1er puis les N dans chaque paire mais bon ca à la limite je pourrais demander à ce qu'on swap ça manuellement si ce n'est pas possible par code.

Au vu du code et en essayant de comprendre, doit-on remettre une condition comme dans la partie d’initialisation :

If tableau(lig, 1) Like "IOBANK*" Then

dans la partie "Recherche de la ligne à chercher" ?

Merci d'avance.

D'accord je vois,

Pour l'histoire des P et N disons que ça rendrait le code encore plus complexe, en plus ça a l'air d'être déjà dans le bon sens, donc je n'y ai absolument pas pris en compte.

Cette fois je n'ai échangé les positions que des codes commençant par "IOBANK", dans les 4 colonnes on a: le code trié, le nombre après IOBANK, le nombre après T, le nombre après L. Ils m'ont servi pour le tri, je les ai fait apparaître à titre d'indication.

J'ai dû rajouter pas mal de choses pour faire le tri mais je pense que cette fois c'est bon.

le fichier:

5test-2.xlsm (66.66 Ko)

le code:

Sub tri()
Dim tableau As Variant, tabSplit As Variant
Dim ligFin As Long, ligTri As Long
Dim valeur, memoire
Dim texte As String
Dim IOBANK As Boolean

ligFin = Range("G" & Rows.Count).End(xlUp).Row
tableau = Range("G1", "G" & ligFin)

ReDim Preserve tableau(1 To UBound(tableau, 1), 1 To 4)

'initialisation du tableau de tri
For lig = LBound(tableau, 1) To UBound(tableau, 1)
    If tableau(lig, 1) Like "IOBANK*" Then
        tabSplit = Split(tableau(lig, 1), "_")

        tableau(lig, 2) = Val(Replace(tabSplit(0), "IOBANK", ""))
        For a = 1 To 2
            valeur = ""
            texte = tabSplit(a)
            For x = 1 To Len(texte)
                If Mid(texte, x, 1) Like "#" Then
                    valeur = valeur & Mid(texte, x, 1)
                End If
            Next x
            tableau(lig, 2 + a) = Val(valeur)
        Next a
    End If
Next lig

'tri
For i = 1 To UBound(tableau, 1) - 1
    ligTri = i
    If tableau(i, 1) Like "IOBANK*" Then
        'recherche de la ligne à échanger
        For x = i + 1 To UBound(tableau, 1)
            If tableau(x, 1) Like "IOBANK*" Then
                If tableau(x, 2) < tableau(ligTri, 2) Then
                    ligTri = x
                ElseIf tableau(x, 2) = tableau(ligTri, 2) Then
                    If tableau(x, 3) > tableau(ligTri, 3) Then
                        ligTri = x
                    ElseIf tableau(x, 3) = tableau(ligTri, 3) Then
                        If tableau(x, 4) > tableau(ligTri, 4) Then
                            ligTri = x
                        End If
                    End If
                End If
            End If
        Next x

        'échange des lignes
        For j = 1 To UBound(tableau, 2)
            memoire = tableau(i, j)
            tableau(i, j) = tableau(ligTri, j)
            tableau(ligTri, j) = memoire
        Next j
    End If
Next i

Range("I1").Resize(UBound(tableau, 1), UBound(tableau, 2)).Value2 = tableau
End Sub
Rechercher des sujets similaires à "modification caracteres detection certain caractere"