Remplacement plusieurs valeurs + recopier colonne sous condition [Résolu/Fermé]

Signaler
Messages postés
38
Date d'inscription
jeudi 10 janvier 2013
Statut
Membre
Dernière intervention
5 avril 2018
-
Messages postés
16174
Date d'inscription
lundi 12 septembre 2005
Statut
Contributeur
Dernière intervention
6 août 2020
-
Bonjour à tous,

J'aurai deux questions à soumettre à la communauté:

1) Je cherche un moyen de rechercher et remplacer 28 valeurs différentes par une seule sans devoir faire les 28 remplacements à la main (j'ai 30 bases de données de plus de 300.000 lignes chacune, il faut faire du tri là-dedans ). Une idée ?
Dans le fichier joint en dessous, je dois remplacer 28 des valeurs en colonne D par PETIT et 28 autres valeurs par GRAND

2) Ensuite, j'aimerai construire une macro me permettant de recopier les données de la colonne P si les valeurs d'une colonne D sont égales à PETIT mais de recopier les données d'une colonne S si elles sont égales à GRAND.

Toute aide serait grandement appréciée,
Merci !

CL

Fichier exemple disponible ici: https://transvol.sgsi.ucl.ac.be/download.php?id=fc1e72550c816585

3 réponses

Messages postés
1491
Date d'inscription
vendredi 26 octobre 2012
Statut
Membre
Dernière intervention
28 janvier 2013
83
Bonjour cletess,

Les deux points peuvent être fait par VBA (macro)

1° Remplacer 28 valeurs par "PETIT" + 28 valeurs par "GRAND" SI la cellule est égale à quoi ??

2° :
Dim i As Long, PremiereLigne As Long, DerniereLigne As Long
'
PremiereLigne =1: DerniereLigne =20
For i=PremiereLigne To DerniereLigne 
    If(Cells(ligne,4).value = "PETIT") Then
        ValeurARecopier = Cells(ligne,16).value
    ElseIf (Cells(ligne,4).value = "GRAND")
        ValeurARecopier = Cells(ligne,19).value
    End If
Next i


Où i est le numéro de ligne, 4 vaut pour la colonne "D", 16 pour "P" et 19 pour "S"
Messages postés
38
Date d'inscription
jeudi 10 janvier 2013
Statut
Membre
Dernière intervention
5 avril 2018

Je cherche à remplacer les valeurs de la colonne D suivantes 2 3 5 6 7 8 12 14 16 18 20 23 24 26 30 31 35 36 37 39 41 42 44 46 47 49 53 et 55 par PETIT et les autres par GRAND.

Ensuite, si il est écrit PETIT dans la colonne D, que la macro recopie les valeurs de la colonne P et celle de la colonne S si il est écrit GRAND dans la colonne D !

Merci beaucoup pour ton aide
Messages postés
1491
Date d'inscription
vendredi 26 octobre 2012
Statut
Membre
Dernière intervention
28 janvier 2013
83
Pour ceci: Ensuite, si il est écrit PETIT dans la colonne D, que la macro recopie les valeurs de la co .. j'ai donné le code

Maintenant, la première partie:
Public Sub Fait() 
    Dim t(27) As Long 
    Dim i As Long, PremiereLigne As Long, DerniereLigne As Long 
    ' 
    PremiereLigne =1: DerniereLigne =20 
    For i=PremiereLigne To DerniereLigne 
    ' 
    t(0) = 2:t(1) = 3:t(2) = 5:t(3) = 6:t(4) = 7 
    t(5) = 8:t(6) = 12:t(7) = 14:t(8) = 16:t(9) = 18 
    t(10) = 20:t(11) = 23:t(12) = 24:t(13) = 26:t(14) = 30 
    t(15) = 31:t(16) = 35:t(17) = 36:t(18) = 37:t(19) = 39 
    t(20) = 41:t(21) = 42:t(22) = 44:t(23) = 46:t(24) = 47 
    t(25) = 49:t(26) = 53:t(27) = 55 
    ' 
    For i = PremiereLigne To DerniereLigne 
        For tElement = t(LBound(t)) To t(UBound(t)) 
            If (Cells(i,4).Value = t(tElement)) Then 
                Cells(i,4).Value = "PETIT" 
            Else 
                Cells(i,4).Value = "GRAND" 
            End If 
        Next tElement 
    Next i 
End Sub

Edit pour présentation.
Messages postés
38
Date d'inscription
jeudi 10 janvier 2013
Statut
Membre
Dernière intervention
5 avril 2018

Merci pour ton aide Heliotte ! Je commence seulement à essayer de déchiffrer le code en VBA donc désolé si mes interrogations semblent couler de source :)

petits problèmes persistent dans la macro: dans la première partie de la macro, j'obtiens un message d'erreur "erreur d'exécution 9 : l'indice n'appartient pas à la sélection" avec la ligne
 If (Cells(i,4).Value = t(tElement)) Then
qui semble problématique.
Ensuite, il me note "Variable de contrôle For déjà utilisée", je suppose qu'il s'agit de la deuxième itération de la ligne
For i = PremiereLigne To DerniereLigne
qui cause le problème donc je l'ai supprimée et l'erreur n'apparaît plus.
Ensuite, je suppose que je dois rajouter un "Then" à la fin de
 ElseIf (Cells(ligne,4).value = "GRAND")

Est-ce correcte de procéder de la sorte ?

Et puis-je rassembler les deux parties de la macro en une seule ? Dois-je y apporter une quelconque modification ?

Merci pour tout !
Messages postés
1491
Date d'inscription
vendredi 26 octobre 2012
Statut
Membre
Dernière intervention
28 janvier 2013
83
Toutes mes excuses, j'ai fait ce code trop vite sans le tester ..

"erreur d'exécution 9 : l'indice n'appartient pas à la sélection" avec la ligne
- If (Cells(i,4).Value = t(tElement)) Then ..
.. il faut faire For tElement = t(LBound(t)) To (t(UBound(t)-1))

2° J'ai omis la déclaration : Dim tElement As Long .. à ajouter en début de procédure

3° Ajouter ElseIf (Cells(ligne,4).value = "GRAND") Then
Messages postés
16174
Date d'inscription
lundi 12 septembre 2005
Statut
Contributeur
Dernière intervention
6 août 2020
3 000
Bonjour

décidément !...

Est ce indispensable de passer par l'étape "petit " et "grand" ou peut on incorporer directement les valeurs des colonnes P et S dans D ?
Messages postés
38
Date d'inscription
jeudi 10 janvier 2013
Statut
Membre
Dernière intervention
5 avril 2018

Bonjour (encore une fois) Michel :)

L'idée est de simplifier les analyses que je dois effectuer sur ces bases de données en créant la variable catégorielle Petit/Grand

Ensuite, en fonction de ça, qu'il me recopie directement les valeurs SmllObj Z (Petit) ou LgObj Z (Grand) dans une autre colonne tout en gardant leur label respectif repris en colonne D (Malgré que les deux colonnes P et S soient fusionnées, je saurais toujours lesquelles font référence à SmllObj Z et à LgObj Z).

Merci
Messages postés
16174
Date d'inscription
lundi 12 septembre 2005
Statut
Contributeur
Dernière intervention
6 août 2020
3 000
et voilà
dommage qu'il n'y ait que 2 frame pour mesurer la durée :o)
pour terminer: Dans quelle colonne faut il reporter les mesures P et S ?

Sub petitougrand() 
Dim Cptr As Byte, Derlig As Integer, Nbre As Byte 
Dim Debut As Integer, Fin As Integer, frame As Integer

Application.ScreenUpdating = False 
Derlig = Columns("D").Find("*", , , , , xlPrevious).Row 
Nbre = Application.Max(Range("D2:D" & Derlig)) 
For Cptr = 1 To Nbre 
     frame = Choose(Cptr, 0, 2, 3, 0, 5) '  a terminer (poil dans la main) 
     Debut = Columns("D").Find(Cptr).Row 
     Fin = Application.CountIf(Range("D2:D" & Derlig), Cptr) + Debut - 1 
     With Range(Cells(Debut, "D"), Cells(Fin, "D")) 
          If frame = 0 Then 
               .Value = "grand" 
           Else 
               .Value = "petit" 
          End If 
     End With 
Next 
End Sub
Messages postés
38
Date d'inscription
jeudi 10 janvier 2013
Statut
Membre
Dernière intervention
5 avril 2018

Bonjour Michel !

Pour ce qui est du report, la colonne V me semble toute indiquée !
"dommage qu'il n'y ait que 2 frames pour mesurer la durée " que veux-tu dire par là ? Si jamais, l'appareil qui prend ces mesures fonctionnent à du 240 Hrtz donc une nouvelle ligne est enregistrée toute les 1000/240 millisecondes (4,1666..). Je ne sais pas si c'est à ceci que faisait référence ton commentaire :)

Pour ce qui est de ta procédure, j'obtiens le message "dépassement de capacité" en référence à cette ligne ci
Derlig = Columns("D").Find("*", , , , , xlPrevious).Row
. Des suggestions ?

Merci encore
Messages postés
1491
Date d'inscription
vendredi 26 octobre 2012
Statut
Membre
Dernière intervention
28 janvier 2013
83
Bonsoir à tous,

Remplacer dans la déclaration (en début de procédure) :

Dim Cptr As Byte, Derlig As Integer, Nbre As Byte
par
Dim Cptr As Byte, Derlig As Long, Nbre As Byte
Messages postés
16174
Date d'inscription
lundi 12 septembre 2005
Statut
Contributeur
Dernière intervention
6 août 2020
3 000
Bonjour,

Probleme ce matin pour accéder: Google semble tout retarder avec son animation...

J'ai noté pour la colonne V, je regarde dans la journée
dommage qu'il n'y ait que 2 frames pour mesurer la durée.... Non c'est pour le temps que prend la macro pour exécuter le boulot comme dans la précédente discussion, tu avais 56 frames....
Messages postés
16174
Date d'inscription
lundi 12 septembre 2005
Statut
Contributeur
Dernière intervention
6 août 2020
3 000
re,

création colonne V avec si "grand" valeur col S sinon col P
Sub petitougrand()
Dim Cptr As Byte, Derlig As Integer, Nbre As Byte
Dim Debut As Integer, Fin As Integer, frame As Byte

Application.ScreenUpdating = False
Derlig = Columns("D").Find("*", , , , , xlPrevious).Row
Nbre = Application.Max(Range("D2:D" & Derlig))
For Cptr = 1 To Nbre
     frame = Choose(Cptr, 0, 2, 3, 0, 5) '  a terminer (poil dans la main)
     Debut = Columns("D").Find(Cptr).Row
     Fin = Application.CountIf(Range("D2:D" & Derlig), Cptr) + Debut - 1
     With Range(Cells(Debut, "D"), Cells(Fin, "D"))
          If frame = 0 Then
               .Value = "grand"
               Range(Cells(Debut, "V"), Cells(Fin, "V")) = Range(Cells(Debut, "S"), Cells(Fin, "S")).Value
           Else
               .Value = "petit"
               Range(Cells(Debut, "V"), Cells(Fin, "V")) = Range(Cells(Debut, "P"), Cells(Fin, "P")).Value
          End If
     End With
Next
End Sub

Messages postés
38
Date d'inscription
jeudi 10 janvier 2013
Statut
Membre
Dernière intervention
5 avril 2018

Bonjour à tous les deux,

Voilà ce que j'ai en final:

Sub petitougrand()
Dim Cptr As Byte, Derlig As Long, Nbre As Byte
Dim Debut As Integer, Fin As Integer, frame As Byte
Dim start As Single
start = Timer 'pour essai rapidité à supprimer

Application.ScreenUpdating = False
Derlig = Columns("D").Find("*", , , , , xlPrevious).Row
Nbre = Application.Max(Range("D2:D" & Derlig))
For Cptr = 1 To Nbre
     frame = Choose(Cptr, 0, 2, 3, 0, 5, 6, 7, 8, 0, 0, 0, 12, 0, 14, 0, 16, 0, 18, 0, 20, 0, 0, 23, 24, 0, 26, 0, 0, 0, 30, 31, 0, 0, 0, 35, 36, 37, 0, 39, 0, 41, 42, 0, 44, 0, 46, 47, 0, 49, 0, 0, 0, 53, 0, 55, 0) '  
     Debut = Columns("D").Find(Cptr).Row
     Fin = Application.CountIf(Range("D2:D" & Derlig), Cptr) + Debut - 1
     With Range(Cells(Debut, "D"), Cells(Fin, "D"))
          If frame = 0 Then
               .Value = "grand"
               Range(Cells(Debut, "V"), Cells(Fin, "V")) = Range(Cells(Debut, "S"), Cells(Fin, "S")).Value
           Else
               .Value = "petit"
               Range(Cells(Debut, "V"), Cells(Fin, "V")) = Range(Cells(Debut, "P"), Cells(Fin, "P")).Value
          End If
     End With
Next
MsgBox Timer - start 'pour essai rapidité à supprimer
End Sub


La macro tourne en 1,035 sec et effectue la tâche jusqu'au frame 41 (dépassement de capacité)
Des idées ?

Dans tous les cas, merci pour votre aide !
Messages postés
38
Date d'inscription
jeudi 10 janvier 2013
Statut
Membre
Dernière intervention
5 avril 2018

J'ai tenté de définir Debut et fin en temps que "As Long" au lieu d'integer et ça semble régler le problème. Le changement effectué n'a pas d'autres implications ??

ça semble fonctionner à merveille en tout cas: 19,2 seconde sur le fichier complet qui comporte 488 000 lignes, c'est magnifique !

Merci infiniment !
Messages postés
16174
Date d'inscription
lundi 12 septembre 2005
Statut
Contributeur
Dernière intervention
6 août 2020
3 000
content pour toi :o)

et à bientôt pour de nouvelles aventures !


Cordialement