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.
- Messages
- 3'581
- Excel
- 2013, 2019, 365
- Inscrit
- 11/04/2020
- Emploi
- Formateur bureautique, dvpt fichiers
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.
- Messages
- 3'581
- Excel
- 2013, 2019, 365
- Inscrit
- 11/04/2020
- Emploi
- Formateur bureautique, dvpt fichiers
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
- Messages
- 3'581
- Excel
- 2013, 2019, 365
- Inscrit
- 11/04/2020
- Emploi
- Formateur bureautique, dvpt fichiers
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 :)
- Messages
- 3'581
- Excel
- 2013, 2019, 365
- Inscrit
- 11/04/2020
- Emploi
- Formateur bureautique, dvpt fichiers
Apparemment l'édition de message bug aujourd'hui.
- Messages
- 3'581
- Excel
- 2013, 2019, 365
- Inscrit
- 11/04/2020
- Emploi
- Formateur bureautique, dvpt fichiers
@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...
- Messages
- 3'581
- Excel
- 2013, 2019, 365
- Inscrit
- 11/04/2020
- Emploi
- Formateur bureautique, dvpt fichiers
@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...
- Messages
- 3'581
- Excel
- 2013, 2019, 365
- Inscrit
- 11/04/2020
- Emploi
- Formateur bureautique, dvpt fichiers
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
- Messages
- 3'581
- Excel
- 2013, 2019, 365
- Inscrit
- 11/04/2020
- Emploi
- Formateur bureautique, dvpt fichiers
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):
Merci pour la proposition, ca en fait des lignes comparé à ce que je pensais
'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:
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