Se connecter / S'enregistrer
Votre question
Résolu

Copier Coller ligne complète si une condition est respectée

Tags :
  • Programmation
Dernière réponse : dans Programmation
25 Octobre 2016 14:39:17

Bondour !
Alors je suis une quille en VGA/macro blabla... Enfin j'ai jamais eu de cours... Mais je crois que c'est bien cette "chose" qu'il me faut pour un tableur excel car la ligne de code avec les SI OU ET imbriqués est imbuvable.

Alors du coup comment je peux faire pour que sur la feuille 2 de mon classeur, apparaissent toutes les lignes de mon classeur 1 dès lors qu'une cellule de la colonne G a une valeur supérieure ou égale à 80 ?
Sachant que les 2 premières lignes du classeur 2 sont des titres et que dans le tableau classeur 1 il y a aussi des parties (je sais pas si ça a une importance de le préciser).



Merci beaucoup par avance pour les gentilles personnes qui aideront la quille que je suis :D 

Autres pages sur : copier coller ligne complete condition respectee

a b L Programmation
25 Octobre 2016 14:54:00

Salut,
Vu ce que tu décris le "=SI(...)" ne paraît pas bien compliqué ...
m
0
l
25 Octobre 2016 15:08:50

Salut en effet c'est faisable mais très fastidieux...

J'ai une dizaine de colonnes et plusieurs centaines de lignes.
J'ai peut être pas été clair dans ma demande.
En gros :
ma colonne G contient un niveau sonore et chaque ligne constitue un point de mesure. Mon tableau du classeur 1 est donc une simple rentrée de données avec des mises en formes conditionnelles.
Ce que je souhaite c'est qu'à chaque fois que j'ai un niveau sonore supérieur ou égal à 80 (colonne G du classeur 1), la ligne complète soit retranscrite dans le classeur 2. Et uniquement les lignes là (qu'il n'y ait pas des trous lorsqu'il trouve une ligne avec une valeur inférieure à 80).

Si c'est faisable juste avec les si(et(ou machin, peut être un petit aperçu ne serait de refus car là j'ai en exemple cette ligne de code pour une seule colonne :

=SI(OU(ET('Carto 11-2012'!G46>80;ESTVIDE('Carto 11-2012'!F46));ET('Carto 11-2012'!G46<80;ESTVIDE('Carto 11-2012'!F46));ET('Carto 11-2012'!G46=80;ESTVIDE('Carto 11-2012'!F46)));"";'Carto 11-2012'!F46)

car là problèmes :

- je fais apparaitre des lignes vides lorsque la valeur en G est <80
- je dois récrire à chaque colonne un code différent car même si je fixe la cellule, bah en glissant avec le petit point noir de la cellule ça copie la même chose (normal en même temps)

Je pense (pour pas dire être sûr) que mes erreurs sont simples c'est juste que là je m'arrache les cheveux :/ 
m
0
l
Contenus similaires
a b L Programmation
25 Octobre 2016 15:16:50

Ouais en effet si tu veux pas les lignes vides ça complique ...
Alors en VBA c'est très simple à faire, mais tu n'as jamais ouvert VBA c'est bien ça ?

Une ou deux question quand même:
La macro doit être lancée comment (bouton, modification d'une des données/cellule, ...) ?
Est-il envisageable de complètement vider la feuille 2 et de la reconstruire entièrement à chaque exécution de la macro ? (si non ça va méchamment compliquer la donne ...)
m
0
l
25 Octobre 2016 15:26:00

Alors je sais ouvrir VBA (hourra) mais c'est tout :pt1cable: 

L'idéal serait que le classeur 2 se mette à jour seul lorsque je change des valeurs (donc modification des données/cellules si je fais l'analogie ?).

Ensuite ce serait bien de pouvoir garder une trace de cette feuille 2, qui me permettra de faire un suivi (pour voir si lors de prochaines mesures on a un niveau sonore plus ou moins élevé...).

Donc pour résumer :

- pas de lignes vides
- déclenchement automatique quand je change les données
- que ça se créée sur une nouvelle feuille à chaque fois

Je peux sauter par la fenêtre donc si j'ai bien compris ?


Remarque:
La macro se lance à chaque cellule que je modifie avec l'option "modification des données..." ? Si c'est le cas c'est juste infaisable alors autant faire la macro que je lance manuellement (car si je rentre les centaines de données et que la macro décide de créer une nouvelle feuille à chaque fois... bah voilà quoi :D 

En tout cas merci de ton intérêt ça fait plaisir ! :) 
m
0
l
a b L Programmation
25 Octobre 2016 15:36:46

Effectivement si tu veux chaque fois créer une nouvelle feuille on est mal partit pour le faire à chaque modif sur feuille1 ...

Dans le cas présent un lancement manuel me semble préférable.

Tu as déjà une idée de comment t'y prendre (en français, pour le vba on verra après).

N.B. mon but est de t'apprendre les rudiments du VBA, pas de faire la macro à ta place (même si je ferai sûrement le gros du travail en fin de compte), mais j'aimerais vraiment que tu aies appris qqch et compris ce qu'on aura réalisé. Ceci peut prendre pas mal de temps (même pour un problème simple)
m
0
l
25 Octobre 2016 15:55:51

une idée de comment m'y prendre... aucune idée :pt1cable: 


genre si g10>= 80 => alors copier la ligne associée entière (qui peut être ligne 12 à cause des titres), sinon ne rien copier


Je pense que je vais abandonner si c'est trop complexe et je ferai un vieux copy/paste, mais ça me prendra beaucoup plus de temps. Arghhh dilemme quand tu nous tiens
m
0
l
a b L Programmation
25 Octobre 2016 15:57:52

Comme tous les langages le VBA n'est pas "complexe" en soi, mais il peut le devenir si l'on ne respecte pas des fondamentaux précis concernant la structuration des opérations.

Si tu veux que l'aide soit efficace, je t'invite à préciser les règles de fonctionnement aussi finement que possible.

Par exemple
- Si la cellule est vide, ne pas copier
- Si la cellule contient "x" ou contient "y", faire ceci, sinon faire cela
- Si la somme des cellules "a" "b" "c" est comprise entre 10 et 40, ou entre 45 et 75 faire ceci/cela.

Etc
Cela rendra les règles exploitables, claires, et nous pourrons te donner des pistes.

Dans programmation, il y a une éthique simple:
- Pose toutes les questions que tu veux, aucune question n'est bête
MAIS
- N'escompte pas que l'on fasse le boulot à ta place, parce que tu es là pour comprendre ce que tu fais

:) 
m
0
l
25 Octobre 2016 16:06:44

eh bien justement ça va être là le souci je sens.
tout doit découler de la valeur des cellules dans une seule colonne.
Si cette cellule dépasse ou est égale à 80, il me faut la ligne complète qui sorte sur la nouvelle feuille car les autres colonnes me renseignent l'endroit de la mesure, le type d'appareil, les conditions blabla

A contrario pour toutes les cellules qui seront strictement inférieures à 80 de ladite colonne, je ne souhaite aucun report de la ligne sur ma feuille 2.

La feuille 2 est en fait un résumé de ce qu'il ne va pas sur mon site, et donc je pourrai prioriser les actions en conséquence.


D'ailleurs pour pousser le vice encore plus, on peut intégrer directement dans la macro qu'elle ordonne ensuite le tableau feuille 2 dans l'ordre décroissant par rapport à cette valeur tant étudiée ? (bien sûr en gardant les données associées à cette valeur, enfin la ligne quoi, que ça trie en ligne par rapport aux colonnes.... c'est vraiment pas clair je sais pas expliquer x) ).
m
0
l
a b L Programmation
25 Octobre 2016 16:24:38

Essayes d'exprimer en français du code:
un exemple qui n'a rien à voir avec ton problème:

  1. Pour toutes les lignes de 1 à 30:
  2. Si Valeur en A > Valeur en B ALORS:
  3. Valeur en C = 1
  4. Sinon
  5. Valeur en C = 0
m
0
l
25 Octobre 2016 16:28:48

eh bien des lignes 1 à 30, si ma cellule A > B => alors C = 1 et si A < B => C = 0

là ça va c'est compréhensible, je "panique" à la vue des autres topics quand je vois des .Rows machin truc x') parce que là ma compréhension s'élève au niveau de l'encéphalogramme d'une grenouille. Morte. Écrasée par un semi-remorque. Sur une route de campagne. En hiver.
m
0
l
25 Octobre 2016 16:32:59

ou genre ça :

AG.Range(iAG & ":" & iAG).Copy HO.Cells(iHO, 2)

ce moment de solitude que je me tape en lisant ces lignes
m
0
l
a b L Programmation
25 Octobre 2016 16:41:03

:D 

C'est comme une langue étrangère c'est juste une question de syntaxe, mais le fonds du problème tu peux le poser en français, essaye donc de faire pour ton problème ce que j'ai fais dans l'exemple, ensuite je pourrai jouer à google translator ...
m
0
l
a b L Programmation
25 Octobre 2016 16:43:30

Vous y en va parler la france :D 

Blague à part, applique ce que Drul t'indique, traduis ton besoin en étapes élémentaires en français afin qu'on s'amuse à voir si en code c'est envisageable, complexe, ou simplement impossible ;) 
m
0
l
25 Octobre 2016 16:44:48

Moi aussi au début je galérais je comprenais absolument rien mais Drul m'a aidé, je partais de 0 et y'a pas grand chose à apprendre c'est beaucoup de logique

Genre tu crées des variables

Par exemple X un entier, ou un range

Et tu te sers de cette variable qui sera dynamique sur ton tableur

Par exemple

Dim a as Integer
For a = 1 to 15
Cells(a, 20) = "blablabla"
Next

après y'a quelques trucs à apprendre par cœur
Bien sûr je vais pas faire le crack mais faire un code en Français littéraire puis essayer de le traduire en vba ça aide et y'a aussi plein de "formules" à apprendre mais avec les mots clés on les retrouve sur internet
Y'a aussi la syntaxe des fois le débogueur détecte pas mais ça se fait pas comme ça

Moi je suis un débutant c'est sûr mais je pars plus de 0 j'arrive à comprendre un code c'est déjà ça ^^
Le vba j'ai l'impression que c'est beaucoup de pratique de toute manière donc on peut pas trop demander à un débutant de se démerder il y arrivera jamais

Mais essayer en français au moins
m
0
l
a b L Programmation
25 Octobre 2016 16:53:22

N.B le macro recorder est outil très utile pour apprendre la syntaxe ! (même si le code pondu est une horreur au final :D )
m
0
l
25 Octobre 2016 16:55:58

alors pour toutes les lignes de 1 à 65536

Si valeur de cellule dans colonne G >= 80 Alors:

copier ligne correspondante dans feuille 2

sinon

ne rien copier



c'est nul c'est ce que j'ai écris plus haut x')


J'avais retranscris ce que j'avais pu avec ce code là piqué dans un autre topic

  1. Sub test()
  2.  
  3.  
  4.  
  5. Dim ligne_a_deplacer As Integer
  6.  
  7. Dim cel As Range
  8.  
  9. Dim vo
  10.  
  11.  
  12. ligne_a_deplacer = Worksheets("test").Range("a" & Worksheets("test").Rows.Count).End(xlUp).Row
  13.  
  14.  
  15. With Sheets("Carto 11-2012")
  16.  
  17. For Each cel In .Range("g3:g" & .Range("g" & .Rows.Count).End(xlUp).Row)
  18.  
  19. If cel.Value <> ">80" Then
  20.  
  21. .Rows(cel.Row).Copy Destination:=Worksheets("test").Cells(ligne_a_deplacer, 1)
  22.  
  23.  
  24. ligne_a_deplacer = ligne_a_deplacer + 1
  25.  
  26. End If
  27.  
  28.  
  29. If Not cel.Value <> "<80" Then
  30.  
  31.  
  32.  
  33.  
  34.  
  35.  
  36.  
  37. End If
  38.  
  39. Next
  40.  
  41. End With
  42.  
  43. End Sub




Seulement il me copie toutes les lignes bêtement. Il me réécrit pas non plus les "titres" des colonnes mais ça à la limite je peux les copy paste manuellement.
Je m'explique pour ces colonnes "titres" :
tout en haut sur les 2 premières lignes j'ai les gros titres "date, appareil, local, ..." et ensuite j'ai une 2 lignes fusionnées pour découper le tableau en différents bâtiments.

Euh clair ? x')
m
0
l
25 Octobre 2016 16:59:12

(oui je n'ai absolument rien capté à ce que j'ai écris et je vois là qu'il y a un premier hic sur Dim vo --> j'ai pas changé le vo)
m
0
l
a b L Programmation
25 Octobre 2016 17:08:40

ben c'est déjà pas mal dis donc!
Déjà une chose : pas besoin du bloc
  1. If Not cel.Value <> "<80" Then
  2. End If

En gros: tu le testes déjà au-dessus, donc concrètement aucun besoin de le refaire:) 

par contre, tu peux traiter une exception pour la première ligne et la copier brute... La technique serait alors de faire un "else" et testant également si tu es sur la première ligne

Par exemple:

pour toute cellule sur ma zone
si(la ligne est la première de la série)
copier la ligne // on conserve ainsi l'entête
sinon
si(la colonne G >80)
copier la ligne // on copie alors les données.
fin de si
fin de si
fin boucle

[EDIT]j'ai rien dit pour ce qui est rayé... suis fatigué là...[/EDIT]
Par contre, là où j'ai systématiquement un doute, c'est à la copie des lignes à savoir la numérotation de position de ligne dans la feuille cible... ah mes souvenirs sont lointains, mais il me semble qu'il te manque une incrémentation qui dit
"Voilà le numéro de ligne cible" pour éviter des lignes vides à toute ligne non copiée.

m
0
l
25 Octobre 2016 17:13:38

eeeeeeeeeet c'est l'encéphalogramme de la grenouille... je n'ai rien compris hein c'est juste un code que j'ai trouvé dans un topic du forum et que j'ai essayé d'arranger à ma sauce en changeant 3 ou 4 mots :D 

mais oui je vois ce que tu dis en "rayé" je sais pas s'il faut prendre en compte le début des valeurs ou directement la 1ère ligne et la macro se débrouille
m
0
l
25 Octobre 2016 17:15:06

je dois vous laisser messieurs, je débauche et je ne peux pas prendre mon document sous le bras.

On reprend demain si vous êtes d'aplomb !

Bonne soirée et merci pour l'aide :) 
m
0
l
a b L Programmation
25 Octobre 2016 18:08:57

A demain...
m
0
l
26 Octobre 2016 08:29:25

Bien le bonjour, on est reparti pour la programmation ?

Est ce que le "dim" veut dire que l'on impose à un mot voulu une certaine "fonction" qui servira dans le code ?

et que veut dire en "français" le "a" et "End(xlUp) dans

Worksheets("test").Range("a" & Worksheets("test").Rows.Count).End(xlUp).Row
m
0
l
a b L Programmation
26 Octobre 2016 08:41:33

dim est le mot clé pour la déclaration d'une variable en VBA.

"a" représente la colonne "A"
Un objet "range" (une ou plusieurs cellule) peut-être décrit de plusieur manière en VBA, mais la plus commune est Range("A121") (représente la cellule A121)

la fonction "end" cherche la fin d'une plage de valeur (en fait elle marche exactement comme un double clique sur le bord d'une cellule, ou la combinaison CTRL + flèche de direction) dans une direction donnée (ici le haut)

Ce que l'auteur de la macro fait ici:

[code="vb"]
Worksheets("test").Range("a" & Worksheets("test").Rows.Count).End(xlUp).Row
[/code
]
C'est de checher la première cellule non vide depuis le bas dans la colonne A afin de n'effectuer sa boucle que sur la région "utile"
En fait il cherche la première cellule non vide (depuis le bas) dans la feuille de destination

J'espère que c'est clair ... :pt1cable: 
m
0
l
a b L Programmation
26 Octobre 2016 08:50:02

N.B. ce qui ne marche pas dans ta macro c'est:

  1. If cel.Value <> ">80" Then


Ce que tu dois écrire est:

  1. If cel.Value > 80 Then

m
0
l
26 Octobre 2016 09:01:34

drul a dit :


Ce que l'auteur de la macro fait ici:

[code="vb"]
Worksheets("test").Range("a" & Worksheets("test").Rows.Count).End(xlUp).Row
[/code
]
C'est de checher la première cellule non vide depuis le bas dans la colonne A afin de n'effectuer sa boucle que sur la région "utile"
En fait il cherche la première cellule non vide (depuis le bas) dans la feuille de destination

J'espère que c'est clair ... :pt1cable: 


Mais mais mais, c'est quoi le but de trouver la première cellule pleine depuis le BAS... quel est ce monde :pt1cable: 


Je viens de changer en remplaçant comme tu me l'as suggéré : c'est mieux. Mais il me vire mes 2 premières valeurs supérieures à 80. Je change le "g3" en "g1" ? C'est pas possible de mettre tout simplement g pour prendre en compte la colonne entière si gx:g = colonne à partir de la cellule gx

m
0
l
26 Octobre 2016 09:04:30

ah mais dans la feuille de destination en plus ! du coup ça va copier les lignes à partir de la ligne 65536 en toute logique mais c'est pas ce qui se passe x)

ce monde me fascine, vraiment
m
0
l
a b L Programmation
26 Octobre 2016 09:21:43

ben non, on regarde depuis la dernière ligne de la page destination (depuis office 2007 c'est 1048576 et plus 65536) quel est la dernière ligne vide (et pas la première non vide, me suis trompé avant ...) afin de savoir depuis ou copier les données sans effacer ce qui a été fait précédemment ...
Dans ton cas je pense que ce n'est toutefois pas la bonne solution (ça créera des doublons à chaque fois que tu lances ta macro)

on pourrais évidement chercher dans toute la colonne, mais pour une plus grande rapidité d’exécution de la macro il est largement préférable de ce concentré sur la plage "utile". Dans ton cas, si les premières données sont en ligne 1, alors oui utilise g1 au lieu de g3.
m
0
l
26 Octobre 2016 09:28:13

Justement ma première ligne d'entrées est G5 !
Les premières cellules >80 (il y en a plusieurs à la suite) commencent en G21 mais la macro ne reporte pas les deux premières (elle reporte à partir de G23)

et ps : j'ai bien excel 2007 mais le bout du bout reste 65536 :heink: 
m
0
l
a b L Programmation
26 Octobre 2016 09:37:19

surement un classeur .xls alors ... (mode compatibilité), mais peut importe, Rows.count donne le nombre de ligne présente dans ta feuille.

Tu as quoi comme valeur en G21 ?
m
0
l
26 Octobre 2016 09:44:35

G21 : 87,5
G22 : 90,5

Même pas un petit bug du genre c'est à 80 pile et donc j'aurais oublié un signe =

bissare
m
0
l
26 Octobre 2016 09:53:29

bon j'avais effectivement oublié un petit = que j'ai mis là
If cel.Value >= 80 Then

G22 apparait mais il manque la cellule G21 :kaola: 
m
0
l
a b L Programmation
26 Octobre 2016 10:01:35

Hum pas sûr.
tu désires afficher 80.0 ?

sinon c'est 87,5 ou 87.5 ?
En gros c'est du texte ou une valeur ...

essaie ça stp
  1. Sub retest()
  2. MsgBox IsNumeric(Range("G21"))
  3.  
  4. MsgBox Val(Range("G21"))
  5. End Sub

et donne moi le résultat des deux msgbox
m
0
l
26 Octobre 2016 11:37:42

Vrai et 93

et c'est bien en valeur (87,5)
m
0
l
a b L Programmation
26 Octobre 2016 12:08:40

93 ou 87.5 ???
T'étais bien sur la feuille Carto quand tu as lancé la macro ?
m
0
l
26 Octobre 2016 12:35:20

ah non je savais pas que la feuille importait.
alors ça fait Vrai et 87

et d'ailleurs G21 sur l'onglet de "test" où j'étais c'est 93,5 et non 93 comme indiqué dans la boite de message qui apparait
m
0
l
a b L Programmation
26 Octobre 2016 13:13:37

Mouais donc tu es en texte (bien que je soient surpris de isnumeric ...)...
Bon vu ton seuil, on s'en fout de la ","
essaie ça:
  1. If val(cel.Value) > 80 Then
m
0
l
a b L Programmation
26 Octobre 2016 13:38:25

HS: Le isnumeric , il me semble, convertit implicitement en numérique toute zone qui entre (un "cast") puis analyse la valeur castée... N'oublions pas que vba est plutôt ouvert d'esprit sur la qualité de déclaration et de formatage des variables ;) 
m
0
l
26 Octobre 2016 14:00:01

Je veux pas être tatillon mais la virgule est importante du point de vue qualité, et surtout qu'après j'ai des calculs qui peuvent soit être conformes vis à vis de la loi soit qu'ils me mettent en écart alors pas génial :/ 
m
0
l
26 Octobre 2016 14:03:31

(parce que là c'est du 87,5, mais ça veut dire que quelque part il y a potentiellement du 81,5 que la macro m'a supprimé :/  )
m
0
l
a b L Programmation
26 Octobre 2016 14:11:03

T'as essayé avec Val (...) >= 80 ?
m
0
l
26 Octobre 2016 14:14:18

If Val(cel.Value) >= 80 Then

et même sans le = j'ai essayé --> il me refait disparaitre G21 et G22 (valeurs de 97,5 et 90,5)
m
0
l
a b L Programmation
26 Octobre 2016 14:30:57

Tu pourrais re-poster le code que tu utilises et un printscreen de ta feuille Carto :??: :
m
0
l
a b L Programmation
26 Octobre 2016 14:38:52

Question tu pourrais tester ça:
  1. Sub test()
  2.  
  3. Dim cel As Range
  4. Dim source As Range
  5. Dim destination As Range
  6.  
  7. Worksheets("test").UsedRange.Clear
  8. Set destination = Worksheets("test").Range("A1")
  9.  
  10. With Sheets("Carto 11-2012")
  11. For Each cel In .Range("g1:g" & .Range("g" & .Rows.Count).End(xlUp).Row)
  12.  
  13. If cel.Value >= 80 Then
  14. If source Is Nothing Then
  15. Set source = cel.EntireRow
  16. Else
  17. Set source = Union(source, cel.EntireRow)
  18. End If
  19.  
  20. End If
  21.  
  22. Next
  23.  
  24. End With
  25. source.Copy destination
  26. Worksheets("Carto 11-2012").Activate
  27. Worksheets("Carto 11-2012").Range("A1").Select
  28. End Sub
m
0
l
26 Octobre 2016 14:52:55

mon code :
Sub test()


Dim ligne_a_deplacer As Integer

Dim cel As Range

Dim vo


ligne_a_deplacer = Worksheets("test").Range("a" & Worksheets("test").Rows.Count).End(xlUp).Row


With Sheets("Carto 11-2012")

For Each cel In .Range("g1:g" & .Range("g" & .Rows.Count).End(xlUp).Row)

If Val(cel.Value) >= 80 Then

.Rows(cel.Row).Copy Destination:=Worksheets("test").Cells(ligne_a_deplacer, 1)


ligne_a_deplacer = ligne_a_deplacer + 1

End If


Next

End With

End Sub


je peux pas faire de printscreen :3

par contre avec ton code j'ai une erreur qui s'affiche "erreur d’exécution '1004' : Impossible de modifier une cellule fusionnée" et en faisant débogage il me surligne en jaune la ligne "source.Copy destination" avec un message en survolant mais il part trop vite j'arrive pas à lire x')
m
0
l
26 Octobre 2016 14:54:11

je crois que je viens de trouver

Dim vo ==> j'avais toujours pas remplacé u__u
m
0
l
26 Octobre 2016 14:59:32

non ça y'est j'ai compris !
En fait il veut pas se décaler comme je le souhaite dans la feuille destination. Il copie les valeurs derrières mes deux lignes de titre !
si je les enlève les valeurs apparaissent, mais dès que je les mets, il décale pas de deux ligne vers le bas !

Du coup comment je peux faire ? je mets 3 et +3 sur les "ligne_a_deplacer" ?
m
0
l
a b L Programmation
26 Octobre 2016 15:33:33

J'abuse et te demande encore un screen de la feuille "test"
m
0
l
26 Octobre 2016 15:39:00

https://i.imgsafe.org/0b1e568099.png

sur cette feuille c'est moi qui ai copié collé les deux lignes de titre. je pense que le problème vient de là mais du coup comment faire pour que la macro copie ces deux lignes toute seule, et aussi les autres double-lignes de partie (Divers sur mon premier screen) ?
m
0
l
      • 1 / 2
      • 2
      • Dernier