Sélectionner/coller ligne en fonction cellule dans ligne

Bonjour à toutes et tous,

Comme beaucoup de personne sur ce forum, je me suis lancé récemment dans la magnifique aventure qu'est le visual basic.

Comme beaucoup j'ai cherché partout et comme beaucoup j'ai cru trouver la réponse, mais il me manque un piti quelque chose.

Je vous explique mon problème :

Je travaille à l'aide d'un tableau excel. Dans les lignes de ce tableau sont contenu des informations et des actions à mener.

Pour me simplifier la tâche, j'ai essayé de programmer un code me permettant, tout en ayant précedemment signalé les lignes importantes du dit tableau à l'aide d'un "!" dans la colonne finale, copier ces lignes et les coller sur la première feuille de mon classeur.

Je voudrais ainsi pouvoir tout les soirs signaler par un "!" les tâches à effectuer le lendemain et ainsi tout les matins activer la macro pour voir apparaître devant mes yeux ravis mon travail pour la journée.

Il faudrait donc que les lignes collées puissent s'organiser sans se superposer malgrès leur différent lieu de provenance.

Pour répondre à la fonction : copier/coller ligne en fonction du contenu d'une cellule j'ai codé cela ( un exemple) :

Sub test_1()

Dim i As Integer

For i = 1 To 200

If Cells(i, 10).Text = "!" Then

Rows(i).Select

Selection.Copy

Sheets("feuil2").Activate

Rows(i).Select

Selection.PasteSpecial

End If

Next i

End Sub

Le problème c'est que ce code ne renvoi que la première ligne comprenant un "!". Je pensais que la fonction For était la solution mais j'ai du me tromper quelque part.

Auriez vous une solution ?

Ensuite pour ce qui est de la fonction : organiser les lignes sur la première page de mon classeur sans qu'elles ne se chevauchent malgrès leur provenance de différent page de mon classeur ... bah la je patauge complet, je n'ai rien codé d'efficace.

Auriez vous des pistes sur ça ?

J'AIMERAI VRAIMENT REUSSIR CE CODE PAR MOI MEME : ainsi si vous pouviez me donner des pistes (fonction à utiliser, ligne où il y a une erreur, type d'erreur, etc) au lieu de me donner un code tout fait cela serait vraiment génial.

Si possible je posterai régulièrement mes avancées sur ce projet donc n'hésitez pas à venir commenter, aider si vous avez le temps.

Mesdames, messieurs, merci de votre disponibilité et de la mise à disposotion de vos connaissances.

Bonne journée à vous.

Alexis Az

Salut et bienvenue sur le Forum,

Ton code ressemble énormément à un tout premier code

Je pense que d’ici quelques mois tu riras bien en le revoyant.

Si tu ne désires qu’une toute première piste, je peux déjà te dire que tu dois revenir de temps en temps sur ta Feui1, selon la modification ci-dessous (nouvelle instruction Sheets("feuil1").Activate).

Mais bien entendu que ce va-et-vient entre les feuilles 1 et 2 est parfaitement inutile.

Cordialement.

Sub test_1()
Dim i As Integer
For i = 1 To 200
If Cells(i, 10).Text = "!" Then
Rows(i).Select
Selection.Copy
Sheets("feuil2").Activate
Rows(i).Select
Selection.PasteSpecial
Sheets("feuil1").Activate
End If
Next i
End Sub

NB : La prochaine fois fournis-nous un fichier exemple.

NB bis: Tu apprendrais également beaucoup si tu demandais à une autre personne comme elle traiterait le problème. Enfin, c'est comme cela que j'ai appris moi le peu que je sais

Amicalement.

Bonjour Yvouille,

Merci de ton aide. En effet, maintenant la fonction copier/coller ligne contenant "!" marche du tonnerre.

J'ai bien compris par ton

Mais bien entendu que ce va-et-vient entre les feuilles 1 et 2 est parfaitement inutile.

qu'il y a une technique pour copier toutes les lignes désirée d'un coup ... mais je n'y arrive pas pour l'instant.

Pour éviter l'acharnement et rester efficace je suis passé à la fonction :"organiser les lignes copiées sans qu'elles ne se surperposent". Je pense n'être pas trop loin de la solution mais quelque chose cloche.

Comme demandé je joins le fichier correspondant à mes essais.

41test-vba.xlsm (14.63 Ko)

Aurais-tu (auriez-vous) une solution ?

Pour répondre à ta question

Tu apprendrais également beaucoup si tu demandais à une autre personne comme elle traiterait le problème. Enfin, c'est comme cela que j'ai appris moi le peu que je sais

, je compte faire rentrer ce projet et tout ceux qui suivront (j'ai de nombreuses idées) dans le cadre de mes études.

Je suis actuellement alternant et j'aimerais inscrire l'étude et l'application du vba à des fins industriels comme un des axes de ma soutenance. Je préfère donc éviter de trop en demander, me contentant donc d'indice et de piste pour ne pas récupérer des honneurs que je ne mériterais pas totalement. J'espère que tu comprend.

Merci de ton aide en tout cas.

Salutations.

Alexis Az

Salut,

Pour moi on peut sans problème se tutoyer, c’est un Forum, après tout.

Si tu apprends le langage VBA, je ne pense pas que tu serais malhonnête en récupérant des codes créés par d’autres ; je le fais tous les jours et une fois par semaine quelqu’un profite de l’un de mes codes. Où est le problème ?

J’avais préparé un fichier en attendant que tu me montres le tien. Comme ils se ressemblent beaucoup, je te montre le mien (il contient déjà un bout de macro).

Tu peux copier, couper, supprimer des plages sans les sélectionner. Donc au lieu d’écrire

Rows(i).Select
Selection.Copy

Tu peux raccourcir ainsi

Rows(i).Copy

Tu peux copier une plage et la copier sur la même ligne d’instruction en précisant la destination de cette manière, sans devoir – s’il s’agit d’une autre feuille – activer cette feuille.

Rows(i).Copy Destination:=Sheets("feuil2").Range("A1")

Comme l’instruction Destination:= est facultative, la ligne ci-dessous fait le même travail

Rows(i).Copy  Sheets("feuil2").Range("A1")

En utilisant la même variable i pour trouver les lignes à copier-coller et pour les coller sur la Feuil2, tu places tes lignes sur la Feuil2 avec des lignes vides inutiles entre deux.

Je te montre une manière de résoudre ce problème à l’aide d’une autre variable Compteur (nom choisi au hasard).

Si tu ne laisses pas ton code aligné sur la gauche, mais que tu effectues des tabulations pour chaque groupe d’instructions, tu vois mieux ce qui va avec quoi. Dans la macro ci-dessous, tu vois aisément que For va avec Next, que If va avec End If, etc.

Dans mon code, au lieu de placer une nouvelle sélection à la suite d’une autre déjà en place, j’efface à chaque fois les anciennes lignes avec l’instruction Sheets("feuil2").Range("A1:J" & Rows.Count).ClearContents (sans sélectionner cette feuille).

Il y a bien entendu d’autres choses qui pourraient être améliorées, mais allons-y gentiment.

Sub test_1()
Dim i As Integer, Compteur As Integer

Application.ScreenUpdating = False

Sheets("feuil2").Range("A1:J" & Rows.Count).ClearContents

For i = 1 To Range("A" & Rows.Count).End(xlUp).Row
    If Cells(i, 10).Text = "!" Then
        Compteur = Compteur + 1
        Rows(i).Copy Destination:=Sheets("feuil2").Range("A" & Compteur)
    End If
Next i

Sheets("feuil2").Select

End Sub

J’ai regardé un peu ton code et je ne sais pas du tout si l’on pourrait utiliser tes instructions pour ton besoin. Je te propose alors de déjà travailler avec des instructions qui fonctionnent et de voir par la suite, d'ici quelques mois, ces autres instructions spéciales (ou peut-être absolument incorrectes).

A te relire.

40alexisaz-v1.xlsm (20.23 Ko)

Re-bonjour Yvouille,

Après lecture de ton message, c'est vrai que le fait de récupérer des bouts de codes ou des solutions n'a rien de malhonnête ou de dégradant, je pense que c'est plutot au niveau de la fierté que cela a joué mais force m'a été de constater que le VBA était un langage bien trop compliqué et pointu pour être maitrisé seul sans s'inspirer. J'espère que mes propos n'ont pas été mal interprété dans mon ancien message : ce que tu fais est génial et force le respect. Peu sont près à aider les autres comme toi et les gens sur ce forum.

Et justement, grâce à tes conseils j'ai pu avancer dans mon projet. L'organisation des lignes laisse encore à désirer mais elles ne se chevauchent pas, du moins sur mon fichier exemple.

Seulement lorsque que j'essaye de l'appliquer à mon véritable fichier de travail j'obtiens une réponse "erreur 13 : incompatibilité" lorsque j'utilise End(xlup) et ... rien quand j'utilise end(xldown).

J'ai cherché partout mais sans trouver pourquoi. As-tu une solution ? Je te joints le document exemple (qui est cette fois-ci l'exemple type du fichier que j'utilise et imaginant toutes les cellules complétées et avec plus d'onglets).

En tout cas merci pour l'explication pas à pas, j'ai vraiment bien compris avec toutes tes indications !

Salutations !

Alexis Az

Re,

Je n’ai rien pris mal du tout, la preuve c’est que la première fois j’ai accepté de ne te fournir que le tout petit bout d’explication demandé alors que j’aurais pu ne pas te répondre du tout

Maintenant c’est très difficile de t’aider sur la base du fichier que tu me fournis. Tout d’abord car tu n’as placé aucune données-exemple sur tes feuilles et que l’on ne peut pas comprendre en quoi consiste ton travail. Ensuite tu n’as pas placé de bouton sur une de tes feuilles et que je ne sais donc pas logiquement quelle est la feuille de départ, celle concernée par certaines de tes références dans le code.

Par exemple est-ce que ton instruction Range("B" & Rows.Count).End(xlDown).Rows se rapporte à la feuille ‘Importants’, à la feuille ‘Usine 1’ ou ‘Usine 2’ ??

Ce que je peux déjà te dire sur la base de ce que j’ai à disposition :

Tu effectues une boucle de 1 à 6 et tu actives à chaque fois une feuille portant l’un de ces numéros. Comme ton fichier ne comporte que 3 feuilles, au 4ème passage, ça bloque.

Tu pourrais contourner le problème en effectuant ta boucle sur le nombre de feuilles contenues dans le fichier en les comptants à l’aide de l’instruction sheets.count. Ca donnerait un tel code : For changement_page = 1 To Sheets.Count. Mais est-ce que cette activation de chaque feuille l’une après l’autre est vraiment utile ?

Et avec un tel code, tu effectues les mêmes opérations sur toutes les feuilles ; ne devrais-tu pas effectuer des opérations différentes selon les feuilles concernées ?

Ton instruction Range("B" & Rows.Count).End(xlDown).Rows comporte un s de trop tout à la fin. Tu recherches UNE ligne particulière et non pas plusieurs. De plus, comme tu ne précises pas sur quelle feuille il faut appliquer ton code, je présume que si tu corriges ce s final et que tu lances à nouveau le code, ça va rechercher sur une feuille imprécise. A voir plus tard, lorsque l’on sera un peu plus avancé.

Ton instruction Range("B" & Rows.Count).End(xlDown).Rows actuelle ne trouvant jamais de valeur (et pour cause) ; tu effectues donc pour l’instant tes boules For i de 1 à 0 (!!) et ça ne passe jamais par le code au centre de ta boucle.

Pour plus d’aide, merci alors de me fournir un fichier un peu plus explicite (3 ou 4 lignes exemples par feuille concernée suffisent amplement) et précise moi en deux mots le résultat désiré.

A propos, connais-tu le mode pas-à-pas ?

A te relire.

Re,

Alors je te joints le document rempli :

Toutes les lignes entourées de gras sont remplies de la même manière donc basiquement l'action à reproduire est la même peu importe la feuille seléctionnée.

Mon objectif serait de mettre un "!" au bout des lignes qui m'interessent dans les feuilles "usine" pour ensuite à l'aide d'une macro les copier/coller sur la feuille "important".

Je te fais le détail du code pour que tu puisses comprendre mon raisonnement quand je l'ai fais:

Sub Actualisation_tâches()

Dim i As Integer, changement_ligne As Integer, changement_page As Integer jusque là je pense que ça va ^^

Application.ScreenUpdating = False d'après ce que j'ai compris ça permet d'empêcher la mise à jour des données

Sheets(1).Range("A1:U" & Rows.Count).ClearContents nettoyage de la plage de travail sur la feuille "important

For changement_page = 1 To 6 à la base mon fichier contient 6 onglets

Sheets(changement_page).Activate je lance une boucle qui permet une recherche page par page (mon erreur est peut être d'avoir mis la page "important" (1) dans la boucle

For i = 1 To Range("B" & Rows.Count).End(xlDown).Rows pour chaque page séléctionnée dans ma première boucle, je relance une boucle

If Cells(i, 21).Text = "!" Or Cells(i, 20).Text = "!" Or Cells(i, 19).Text = "!" Then dans chacune des pages "usines" je vérifie dans les celulles citées si elles contiennent un "!". Je fais ça car parfois mes tableaux sont décalés, certains commence sur la colonne A et d'autre sur la colonne C ou B

changement_ligne = changement_ligne + 1 là c'est toi qui m'a tout appris

Rows(i).Copy Destination:=Sheets(1).Range("A" & changement_ligne) idem

End If

Next i

Next changement_page je ferme la boucle changement de page

End Sub

Sachant que tout les tableaux font le même nombre de colonnes.

Cela et-il plus clair ?

Merci de ton aide et de ta réactivité en tout cas !

Au plaisir!

Re,

Je t’ai conseillé de ne pas effectuer les mêmes opérations sur toutes les feuilles (d’après moi ce n’est pas une bonne idée de passer en revue la feuille ‘Importants’ de la même manière que les autres) et tu me réponds que ‘basiquement l'action à reproduire est la même peu importe la feuille seléctionnée’. Je prends note que mon conseil ne t’intéresse pas trop et effectivement que pour ce fichier précisément, ça n’a aucune importance, la feuille ‘Importants’ étant par hasard vide lorsque tu la visite par ton code et que tu tentes d’y effectuer les mêmes actions que sur tes autres feuilles.

Mais la prochaine fois que tu auras un gros problème dans une situation similaire, rappelle-toi du conseil que t’avais donné Yvouille en juillet 2014.

Je suis un peu surpris que tu m’expliques ton code en détail, alors que je t’en ai fourni une copie corrigée hier soir ; je pense donc avoir compris ce qu’il faisait.

Je te demandais plutôt une explication sur ton fichier Excel puisqu’il était vide et là je comprends un peu mieux sur la base du nouveau fichier reçu.

Ton fichier a quand même un sacré problème ; il s’agit des cellules fusionnées. Ces cellules fusionnées sont du poison pour Excel en général et pour VBA en particulier et elles sont à éviter au maximum. Il y a 36 manières différentes de les éviter. Il y a également des solutions VBA aux problèmes de cellules fusionnées, mais pourquoi se compliquer la vie pour rien ?

En l’état actuel, j’ai à nouveau modifié ton code et j’y ai mis quelques commentaires dont je te laisse prendre connaissance. Afin que ce soit plus facile à t’expliquer quelques détails, j’ai également mis des données spécifiques sur tes feuilles, dans les colonnes D, E et R.

Tout d’abord, je n’ai pas compris pourquoi tu as placé un ! sur la ligne 8 de la feuille ‘Usine 1’. Mais bon, cette ligne vide est reportée, y compris sa mise en forme.

Ensuite, à cause du signe ! placé en S14 de la feuille ‘Usine 1’, la ligne 14 de cette feuille est reportée. Mais comme par exemple la cellule D14 est fusionnée avec la cellule D13, tu as l’impression que le texte ‘Usine1 D13’ sera reporté alors qu’il en sera rien. Idem pour toutes les colonnes A à H et J de cette ligne.

Quant au signe ! placé en S15 de la feuille ‘Usine 1’, il ne permet que le report du texte de la colonne R, tout le reste reporté étant des cellules vides.

Ton fichier est aussi assez mal foutu dans ce sens que les pages des usines n’ont pas une structure identique, ce qui complique toujours beaucoup les choses.

Autre problème : Tu élimines à chaque fois le contenu de la feuille ‘Importants’ mais pas sa mise en forme. Donc si une fois tu reportes 100 lignes avec des mises en forme spéciales et que la fois d’après tu n’en reportes que 50, tu auras 50 lignes vides vers le bas avec des couleurs de fonds et des bordures inutiles. Il y a 36 solutions pour cela, mais on ne peut pas tout faire à la fois.

Je ne sais pas si j’aurais encore l’envie de m’investir beaucoup sur ce fichier presque catastrophique. A voir comment tu es d’accord de le modifier pour l’améliorer.

Bonjour Yvouille,

Juste un petit message pour te dire que je suis en déplacement cette semaine et je n'ai pas accès à VBA.

Je n'abandonne pas sache le, je pense qu'enfaite on s'est mal compris : je pensais juste devoir t'envoyer des codes originaux à chaque fois pour que tu puisses pointer les erreurs.

A côté de ça je compilais les réponses que tu me donnais pour faire un code parfait.

Si tu décides d'abandonner je comprends tout à fait, merci de m'avoir porter jusque là en tout cas.

Merci à toi et je te souhaite le meilleur pour la suite.

Cordialement.

Alexis Az

Salut Alexis,

Si mes réponses t’intéressent, je continue à bien vouloir te les donner.

Si tu veux bien mettre un peu du tien, je te promets d’en mettre au moins le double

Relis mon dernier message et si tu désires continuer la discussion, bien volontiers. Pour moi il n'y a bien entendu aucune urgence.

Amicalement.

Salut Yvouille !

J'espère que ça va !

Bon personnellement je me suis remis à travailler sur mon projet VBA.

Donc je t'ai écouté à la lettre : j'ai modifier tout mon document pour qu'il n'y ait plus de cases fusionnées, j'ai aussi remis tout les tableaux des différentes feuilles de calcul à la même position. Rien que ça, une fois le travail fait je voyais déjà la différence.

Donc après je me suis mis au code avec deux missions : annuler la mise en page de la page "important" et transporter les lignes en conservant contenu + mise en forme. A ce niveau là pas de souci : j'utilise clearformat pour effacer la mise en forme puis pastespecial xlpasteformats pour le reste. Le problème c'est que ce code copie la mise en forme mais pas le contenu de la ligne. Je compte bien trouver une solution ce soir.

Sub Actualisation_tâches()

Dim i As Integer, changement_ligne As Integer, changement_page As Integer

Application.ScreenUpdating = False

Sheets(1).Range("B1:U" & Rows.Count).ClearContents
Sheets(1).Range("B1:U" & Rows.Count).ClearFormats

'For changement_page = 1 To 6
For changement_page = 4 To Sheets.Count

    Sheets(changement_page).Activate

    'For i = 1 To Range("B" & Rows.Count).End(xlDown).Rows
    For i = 1 To Range("B" & Rows.Count).End(xlUp).Row 
        If Cells(i, 17).Text = "!" Then
            changement_ligne = changement_ligne + 1
            Rows(i).Copy
            Sheets(1).Range("A" & changement_ligne).PasteSpecial xlPasteFormats
        End If
    Next i
Next changement_page
End Sub

Je n'ai pas pu beaucoup avancé niveau code mais j'ai une autre idée que je vais essayer de mettre en place demain.

Je t'enverrai le code dès demain.

Merci de ton aide en tout cas ! Tu m'as déjà beaucoup aidé !

Amicalement

Alexis Az

Rechercher des sujets similaires à "selectionner coller ligne fonction"