Macro à adapter

Bonjour à tous,

Etant novice dans le "codage" sur VBA, j'aimerais avoir vos lumières pour réaliser le modèle de mes rêves. Je vous explique mon besoin :

- A chaque fois que dans mon onglet "Travaux" je remplis les cellules de la colonne M avec un "S" comme "subventionnable", je veux copier la ligne entière sur une nouvelle feuille "subventions". J'ai adapté une macro existante à mon cas. La voilà :

Sub Filtre()

Dim Lig As Long

Dim Col As String

Dim NbrLig As Long

Dim NumLig As Long

Sheets("Subventions").Activate ' feuille de destination

Col = "M" ' colonne de la donnée non vide à tester

NumLig = 1

With Sheets("Travaux") ' feuille source

NbrLig = .Cells(65536, Col).End(xlUp).Row

For Lig = 2 To NbrLig

If .Cells(Lig, Col).Value = "S" Then

.Range("B" & Lig & ":G" & Lig).Copy

NumLig = NumLig + 1

Cells(NumLig, 1).Select

ActiveSheet.Paste

End If

Next

End With

End Sub

Cela fonctionne. Mais j'aimerais aller plus loin :

1. comment puis-je faire à partir de cette macro pour faire en sorte que cette commande s'applique pas seulement sur la feuille "Travaux" mais qu'elle s'applique à la feuille "travaux" et "études". Voire encore plus de feuilles dans l'absolu car je compte utiliser cette macro sur plusieurs projets.

2. J'aimerais créer sur la feuille "subventions" une colonne supplémentaire, qui à partir de la colonne "G" des feuilles "travaux" et études" (montant TTC), me calcule le montant HT (Montant TTC/1.20).

3. pouvez vous m'expliquer le passage Range("B" & Lig & ":G" & Lig).Copy car j'ai du mal avec le &. De plus, si je ne veux pas la ligne entière mais uniquement les colonne A,B,C,E,G,J,O de mes feuilles "travaux" et "études" (c'est un exemple) pour les coller sur ma feuille "subventions", comment dois-je faire ?

4. si vous n'êtes pas rassasié, pouvez-vous, à coté des lignes de codes, m'expliquer ce que cela veut dire en français pour que je comprenne bien mieux ce que je fabrique. Là, je fonctionne un peu par mimétisme...

J'ai bien conscience d'en demander beaucoup ! Je compte apprendre de vous tous les manip sur VBA. J'ai un peu suivi les cours VBA mais sans pratiquer au quotidien on oublie trop vite...

Merci à vous et très bonne journée !

Je vous joins un fichier test pour plus de concret ! Merci !

22test.xlsm (27.68 Ko)

Bonjour et bienvenue sur le forum

Quelques remarques :

Tu écris :

A chaque fois que dans mon onglet "Travaux" je remplis les cellules de la colonne M avec un "S" comme "subventionnable", je veux copier la ligne entière sur une nouvelle feuille "subventions".

  • En regardant ta macro, il ne s’agit pas de la colonne M mais de la colonne E
  • Ce n’est pas à chaque fois que tu remplis la cellule que la macro se déclenche : tu dois la déclencher toi-même
  • Si après avoir mis un S dans la colonne E et déclenché la macro tu te ravises, et que tu enlèves le S mis par erreur, après un nouveau lancement de la macro, ton tableau Subventions a la dernière ligne en double : c’est d’autant plus gênant que les doublons vont définitivement rester…
Pour ce qui est de faire la même opération sur la feuille Subventions et sur la feuille Etudes, il est regrettable que ces 2 feuilles n’aient pas la même structure : cela allonge l’écriture de la macro, et surtout, il faudra adapter la macro à chaque nouvelle feuille créée.

Je te propose néanmoins de tester un essai de mon cru : la mise à jour des deux feuilles se fait lorsque tu valides un « S » en colonne E de la feuille Travaux.

Qu’en penses-tu ?

Une dernière remarque : les macros détestent les cellules fusionnées. J’ai dû en « défusionner » plusieurs.

A te lire.

Bye !

28test-v1.xlsm (41.73 Ko)

Bonjour,

Merci à toi pour ton travail. Cela fonctionne et c'est bien là l'essentiel.

Effectivement, mon fichier de base est plus complexe que celui là. J'ai voulu le simplifier le plus possible d'où le problème de colonne !

Tu as raison pour les doublons et c'était aussi l'un des défauts identifiés.

Par contre, je ne comprends pas ta remarque pour la structure car les 2 feuilles sont construites de la même façon. Justement pour la raison que tu as évoqué de simplification de la macro !

Pour le calcul automatique du montant ht, on ne peut pas l'inclure directement dans la macro. Après en faisant glisser les cellules, ça marche aussi

Enfin, pour recopier uniquement certaines colonnes, as-tu une astuce ?

C'est vraiment aimable de ta part d'avoir pris la peine de m'aider. J'essayerai d'adapter ta macro lundi ou mardi au boulot car je n'ai pas mon fichier source ici !

Bonne journée


Bonjour,

Merci à toi pour ton travail. Cela fonctionne et c'est bien là l'essentiel.

Effectivement, mon fichier de base est plus complexe que celui là. J'ai voulu le simplifier le plus possible d'où le problème de colonne !

Tu as raison pour les doublons et c'était aussi l'un des défauts identifiés.

Par contre, je ne comprends pas ta remarque pour la structure car les 2 feuilles sont construites de la même façon. Justement pour la raison que tu as évoqué de simplification de la macro !

Pour le calcul automatique du montant ht, on ne peut pas l'inclure directement dans la macro. Après en faisant glisser les cellules, ça marche aussi

Enfin, pour recopier uniquement certaines colonnes, as-tu une astuce ?

C'est vraiment aimable de ta part d'avoir pris la peine de m'aider. J'essayerai d'adapter ta macro lundi ou mardi au boulot car je n'ai pas mon fichier source ici !

Bonne journée

Tu écris :

, je ne comprends pas ta remarque pour la structure car les 2 feuilles sont construites de la même façon.

Les « Tiers » et Libellés » sont :

  • Sur la feuille Travaux en colonne B et C
  • Sur la feuille Etudes en colonne B et C
  • Sur la feuille Subvention en colonne A et B
De plus, la feuille Etudes a une colonne « Année » en A qu’on ne retrouve pas sur Subventions

La macro ne peut donc pas appliquer la même routine pour copier des données sur la feuille Travaux puis les coller sur la feuille Etudes et sur la feuille Subventions. Mais ce n’est pas grave, on l’adapte.

Pour le calcul automatique du montant ht, on ne peut pas l'inclure directement dans la macro.

On peut l’inclure mais uniquement pour les travaux que tu déclares subventionnés en mettant un « S ».

Pour les autres, j’ai fait une macro déclenchée à demande par un double-clic sur le titre de la colonne. Tout cela est pris en compte dans la nouvelle version.

Enfin, pour recopier uniquement certaines colonnes, as-tu une astuce ?

Je n’ai pas d’astuce mais dis-moi exactement ce que tu veux faire.

A te relire.

Bye !

15test-v2.xlsm (43.55 Ko)

Bonjour,

Une nouvelle fois merci.

Pour rendre les choses concrètes, j'ai rajouté une colonne avec la date. J'aimerais que dans la feuille "subventions", la colonne avec les "S" n’apparaisse pas mais que la date apparaisse à la place. Cela implique d'enlever la colonne "subv?" et donc de choisir les colonnes A, B, C, D et F pour les coller dans mon onglet "subventions".

Si cela simplifie la macro, cela me semble bien de reprendre la structure des feuilles "études" et "travaux" en "subventions" et donc de démarrer en colonne B et non A pour la feuille "subventions" (ou alors à remettre les années en colonne A).

Enfin, en ouvrant l'outil développeur, j'ai vu qu'il y avait pas mal de "modules" ouverts. Déjà que je galère pour comprendre une, là c'est beaucoup pour un seul homme ! Peut-on simplifier et ne faire qu'un seule module ?

Parce que je compte proposer cette façon de fonctionner à plusieurs services et donc comprendre et m'approprier la macro pour éventuellement assurer le "service après-vente" en cas de pépin.

Merci à toi et bonne journée,

12test-v2.xlsm (37.49 Ko)

Bonjour

Tu écris :

J'aimerais que dans la feuille "subventions", la colonne avec les "S" n’apparaisse pas mais que la date apparaisse à la place.

La version 3 tient compte de cette modification.

Si cela simplifie la macro, cela me semble bien de reprendre la structure des feuilles "études" et "travaux" en "subventions"

Maintenant que la macro est écrite, cela ne me semble pas indispensable, mais si tu veux le faire, il faudrait que tu décides, pour les trois feuilles la même dispositions dans les titres de colonnes. Et que la colonne « Subv ? » qui ne concerne que la feuille Travaux soit à l’extrême droite. De plus, la colonne Année ne me semble pas très utile s’il y a une colonne Date.

Peut-on simplifier et ne faire qu'un seule module ?

La macro qui permet d’ajouter une ligne dans le tableau de la feuille Subvention lorsque tu valides un « S » dans la colonne « Subv ? » de la feuille Travaux est une macro événementielle qui doit être écrite sur une feuille de code rattachée à la feuille Travaux.

Idem pour la macro qui par un double-clic met à jour les formules de la feuille « Subventions ». Elle doit être dans la feuille de code rattachée à la feuille Subventions

J’ai fait le ménage mais je ne puis regrouper ces 2 macros.

A te relire.

27test-v3.xlsm (36.94 Ko)

Merci gmd !

Par contre je n'ai pas le bouton d'action pour déclencher la macro ! Je suis perdu sans .

Et dans l'onglet "subventions", je ne retrouve pas les données de la feuille "études".

Peut-être que la simplification des feuilles a fait perdre des infos.

Par ailleurs, je vois que tu aides plein de gens comme moi et c'est très rare et appréciable ! Tu fais vivre ce site et cela est une partie de ton boulot ou bien c'est du "bénévolat" pur et dur ?

Bonjour

Tu écris :

je n'ai pas le bouton d'action pour déclencher la macro ! Je suis perdu sans .

De quelle macro parles-tu ?

Comme je te l’ai indiqué dans mon dernier message, il y a 2 macros événementielles liées au fichier Test V3.

Elles n’ont pas besoin de bouton pour se déclencher puisque c’est :

  • la validation du « S » en colonne E sur la feuille Travaux qui ajoute la ligne de données concernée par ce « S » à la liste de la feuille Subventions
  • le double-clic sur la cellule E1 qui déclenche la réécriture des formules dans toute la colonne E sur la feuille Subventions.
Si ce n’est pas ce que tu désires, explique-moi exactement ce que tu veux.

dans l'onglet "subventions", je ne retrouve pas les données de la feuille "études".

Je n’ai pas touché aux données de cette feuille. Ce sont celles de ton fichier de départ : « Test.xlm »

Il ne tient qu’à toi de l’initialiser avec les données que tu voudras, qu’elles soient ou non sur la feuille Travaux

cela est une partie de ton boulot ou bien c'est du "bénévolat" pur et dur ?

Comme pour tous les intervenants de ce site, c’est, comme tu dis « du bénévolat pur et dur », rémunéré (en général…) par un remerciement.

Bye !

C'est juste que lorsqu'il y a un "s" dans la feuille "études", la ligne n'apparaît pas dans la feuille "subventions". Elle recense uniquement les "S" de la feuille travaux.

Comme je te le disais, c'est vrai que c'est vraiment sympa d'entraider les gens ! Après cette dernière demande, je vais tenter de me débrouiller seul à partir de ton travail. j'ai passé un peu de temps sur le didacticiel pour comprendre davantage. Un grand merci donc pour ta contribution et ta connaissance de "excel" mise à profit pour les autres. J'apprécie grandement.

Bye !

Bonjour

Nouvelle version.

Un "S" en colonne E de la feuille Etudes entraine la mise à jour de la feuille Subventions et de la feuille Travaux si ces travaux y figurent déjà.

17test-v4.xlsm (40.03 Ko)

Merci gmb ! Dernières petites questions et après je ne t'embête plus, promis ! Peux-tu m'expliquer certaines codes de VBA. Je te surligne en gras ce que je n'arrive vraiment pas à comprendre.

Option Explicit

Dim Onglets, Onglet, Année, Tiers, Libellé, Cell

Dim Lgn1, DerLgn, C, Plage, Flag

Private Sub Worksheet_Change(ByVal Target As Range)

Application.EnableEvents = False

Onglets = Array("Etudes", "Subventions", "Travaux")

If Not Intersect(Target, Cells(1, "A").CurrentRegion.Offset(3, 4).Resize(Cells(1, "A").CurrentRegion.Rows.Count - 3, 1)) Is Nothing Then

Année = Cells(Target.Row, "A").End(xlUp).Value

Tiers = Target.Offset(0, -3).Value

Libellé = Target.Offset(0, -2).Value

For Each Onglet In Onglets

If Sheets(Onglet).Name = "Etudes" Then

'On s'occupe de la feuille Etudes

Set Cell = Sheets(Onglet).Range("A:A").Find(Année)

If Not Cell Is Nothing Then

Lgn1 = Cell.Row + 1

With Sheets(Onglet).Cells(Cell.Row, 1).CurrentRegion

DerLgn = .Row + .Rows.Count - 1

End With

With Sheets(Onglet)

Set Plage = .Range(.Cells(Lgn1, "C"), .Cells(DerLgn, "C"))

For Each C In Plage

If C.Value = Libellé And C.Offset(0, -1).Value = Tiers Then

Range(Cells(Target.Row, "B"), Cells(Target.Row, "E")).Copy

C.Offset(0, -1).PasteSpecial xlPasteValues

End If

Next C

End With

End If

'On s'occupe de la feuille Subventions

ElseIf Sheets(Onglet).Name = "Subventions" Then

With Sheets(Onglet)

DerLgn = .Cells(1, "A").CurrentRegion.Rows.Count

Set Plage = .Range(.Cells(2, "B"), .Cells(DerLgn, "B"))

Flag = 0

For Each C In Plage

If C.Value = Libellé And C.Offset(0, -1).Value = Tiers Then

Flag = 1

If UCase(Target) <> "S" Then

'les travaux doivent ête supprimés car non subventionnés

.Rows(C.Row).Delete Shift:=xlUp

End If

End If

Next C

If Flag = 0 Then

'Les travaux doivent être àjoutés car on vient de les déclarer subventionnés

If UCase(Target) = "S" Then

Range(Cells(Target.Row, "B"), Cells(Target.Row, "D")).Copy

.Cells(DerLgn + 1, "A").PasteSpecial xlPasteValues

Cells(Target.Row, "F").Copy .Cells(DerLgn + 1, "D")

.Cells(DerLgn + 1, "E").FormulaR1C1 = "=RC[-2]/1.2"

End If

End If

End With

End If

Next Onglet

End If

Application.CutCopyMode = False

Application.EnableEvents = True

End Sub

Sub ess()

Application.EnableEvents = True

End Sub

Enfin, comment définis-tu Target, même si j'ai bien compris qu'il s'agit de ma colonne E.

Lgn1, c'est bien la première ligne (en gros tu vires les en-têtes) et DerLgn, la dernière ligne à prendre en compte, c'est bien ça ?

Par contre, à quoi correspondent C, Plage et Flag ?

Avec ces quelques explications, je devrais enfin parvenir à recoller les pièces du puzzle et tendre à voler de mes propres ailes sur VBA ! Merci à toi et très bonne soirée.

Bonjour

Tu écris :

Peux-tu m'expliquer certaines codes de VBA.

Je le ferai certainement moins bien que sur le cours VBA de ce forum (que je te recommande) mais je vais essayer ;

A -

« Target » est un mot réservé de VBA, c’est-à-dire que Excel lui attribue certaines propriétés.

Il intervient dans les macros événementielles, celles qui se déclenchent lorsque, par exemple on fait un double clic sur une cellule ou qu’on valide une cellule, ou qu’on clique sur une cellule….

Il désigne la cellule qui est à l’origine de l’événement.

Par exemple, dans la macro de ton message, il s’agit d’une macro qui se déclenche quand tu valides un « S ». Cette cellule est la cellule Target.

L’intérêt ? Quand tu as validé, la cellule active peut être à gauche, ou au-dessous de la cellule du S, ou même au dessus, selon le paramétrage de ton PC. Mais Target sera toujours la cellule qui était active juste avant que tu valides.

Donc, pour la 2° ligne de code à expliquer, si tu as bien compris,

Target.Row

donne le numéro de la ligne où se trouve le S que tu viens de valider

B -

Pour exliquer la première ligne surlignée en gras :

If Not Intersect(Target, Cells(1, "A").CurrentRegion.Offset(3, 4).Resize(Cells(1, "A").CurrentRegion.Rows.Count - 3, 1)) Is Nothing Then

Là, c’est plus compliqué pour moi à expliquer. Je vais décortiquer car il y a plusieurs fonctions imbriquées.

Quand on a :

If not intersect(Target, « Plage de cellules ») is nothing then

Cela veut dire : Est-ce que l’intersection de Target et de « Plage de cellules » n’est pas vide ? Autrement dit : Est-ce que Target est une des cellules de « Plage de cellules » ?

Ensuite :

Cells(1, "A").CurrentRegion

Cela me définit la plage que l’on obtiendrait sur une feuille de calcul en sélectionnant la cellule A1 puis en faisant : « Accueil – Rechercher et sélectionner – Atteindre – Cellules – Zone en cours »

Cells(1, "A").CurrentRegion.Offset(3, 4)

Je décale cette plage de 3 lignes et 4 colonnes, pour que la première cellule de cette plage soit en D4, première ligne de données pour la colonne Subventions.

Mais je ne veux conserver que cette colonne D et, mieux encore que la plage des données de cette colonnes. Il me faut donc redimentionner la plage obtenue en lui donnant 1 colonne et en lui retranchant deux lignes, dues au décalage précédent

Cells(1, "A").CurrentRegion.Rows.Count – 3 

me donne le nombre de lignes que je veux avoir et

….Resize(Cells(1, "A").CurrentRegion.Rows.Count - 3, 1))

redimentionne la plage aux nombre de lignes souhaitées et à 1 colonne

Voilà. Et l’instruction complète veut dire, en clair pour la macro : si la cellule qui vient d’être validée est dans la plage de la colonne D susceptible de recevoir un S, tu exécutes ce qui suit, sinon tu sautes jusqu’au prochain else ou end

C –

Next C

C est une variable que j’ai posée et c' est aussi une cellule

Elle me permet de définir une boucle qui est dans la macro :

For each C in Plage
    ….
Next C

Cela me permet de tester toutes les cellules de Plage et de faire la copie de la ligne si la cellule C contient le Libellé et la cellule de la colonne d’a coté, sur la même ligne, contient le Tiers. Ces deux valeurs qui ont été définies précédemment par celles de la ligne de Target

D -

Application.CutCopyMode = False

Cette instruction permet de supprimer le clignotement des cellules que l’on vient de copier. Avant de finir une macro, on la met si besoin, pour une meilleure présentation.

E –

Application.EnableEvents = True

Pour des macros événementielles un peu longues, il m’arrivait de les voir se planter sans raison, tourner dans le vide puis quitter Excel.

Un crack du forum m’a donné le truc (merci à lui) : commencer par désactiver le déclenchement automatique, écrire la macro et la finir en réactivant.

C’est pour cela qu’en tout début de macro tu as l’instruction avec = false et à la fin avec =true

Et si par hasard on arrête la macros avant la fin, c’en est fini des macros évenementielles…

C’est pour cela qu’il y a en fin de feuille une petite macro pour les réactiver car quand on met au point, on sort souvent d’une macro avant la fin.

Bye !

Rechercher des sujets similaires à "macro adapter"