Se connecter avec
S'enregistrer | Connectez-vous

Coloration cases de planning

Dernière réponse : dans Programmation

bonjour à tous.

je dois actuellement réaliser un planning des taches.

sur la deuxième ligne du tableau excel se situent les numéros de semaines
ensuite, on remplit chaque ligne une par une , avec les différentes taches, la durées de la tâche, commentaires, etc.... et en fonction de la date souhaité, le numéro de semaine correspondante est automatiquement rempli.

pour le moment, j'ai réussi à remplir les cases se situant à l'intesection des numéros de semaines désirées de chaque tache , et de celle du planning en 2ème ligne

comme on peut le voir ici :

[

ceci est réalisé avec une formule du type si (...=...;"o";"") ainsi qu'une mise en forme conditionnelle qui colorie la case en jaune si la valeur o apparait.

ma question est simple:

Comment faire pour colorier les cases précédents la case coloriée ? le nombre de case à colorier étant celui indiqué dans la durée de la tache.

le but du jeu étant que tout se fasse automatiquement, sans appuyer sur un bouton. J'ai commencé une macro, mais je ne vois pas d'une part comment la déclencher, et d'autre part quoi mettre dedans exactement

  1. Dim i, j As Integer
  2. i = 48
  3. j = Worksheet.Range("Q&i").Value

i correspondant au numéro de la ligne , et j à la valeur de la durée de la tâche.



Merci d'avance

Autres pages sur : coloration cases planning

Lassé par la pub ? Créez un compte

Meilleure solution

Expert Programmation

Oulala.... Je ne devais pas être réveillé quand j'ai écrit ça. Désolé.
http://www.presence-pc.com/forum/ppc/Programmation/colo...

Pour t'avoir roulé dans la farine, je te propose de bien étudier ce morceau de code :
  1. Const n°col_semaine As Integer = 16
  2. Const n°col_duree As Integer = n°col_semaine + 1
  3. Const n°col_zone_1er As Integer = 18
  4. Const n°col_zone_der As Integer = 40
  5.  
  6. Dim cell As Range
  7. Dim cell_1er As Range
  8. Dim cell_der As Range
  9. Dim x As Integer
  10. Dim zone_jaune As Range
  11. Dim zone_blanche As Range
  12.  
  13. ' // Nettoyage
  14. Set zone_blanche = Me.Range(Target.EntireRow.Cells(n°col_zone_1er), _
  15. Target.EntireRow.Cells(n°col_zone_der))
  16. zone_blanche.Clear
  17.  
  18. ' // C'est parti
  19. For Each cell In Me.Range(Me.Cells(2, n°col_zone_1er), _
  20. Me.Cells(2, n°col_zone_der))
  21. If cell.Value = Target.EntireRow.Cells(n°col_semaine).Value Then
  22. ' // Trouvé la dernière.
  23. Set cell_der = Me.Cells(Target.Row, cell.Column)
  24.  
  25. ' // Cherchons la première.
  26. x = CInt(Target.EntireRow.Cells(n°col_duree).Value)
  27. Set cell_1er = cell_der.Offset(, 1 - x)
  28.  
  29. ' // Petite vérif
  30. If cell_1er.Column < n°col_zone_1er Then
  31. Set cell_1er = Target.EntireRow.Cells(n°col_zone_1er)
  32. End If
  33.  
  34. ' // Colorions la zone
  35. Set zone_jaune = Me.Range(cell_1er, cell_der)
  36. zone_jaune.Interior.ColorIndex = 6
  37. End If
  38. Next
Ça devrait te plaire ;) 
Expert Programmation

Salut,

Dis donc, tu ne serais pas en train de confondre Microsoft Excel avec Microsoft Project ? :heink: 

Bon, passons. C'est pas toi le coupable, c'est ton patron :sarcastic: 

-------------------------


Tu as donc commencé une macro ! Eh ben c'est déjà un début, un tout petit petit début :D 

Sache qu'on peut faire ça sans une ligne de code VB. Mais comme tu poses ta question ici, on va faire ça en VBA (macro).
Donc on va virer les formules "du type si" et les mises en forme conditionnelles.

Et on va faire de la programmation événementielle. C'est-à-dire qu'on va demander à Excel de réagir à certains stimuli. L'événement Change sur la feuille est un stimulus très intéressant que je te laisse un peu regarder.

Quand tu auras assouvi ta curiosité à cet endroit, dis-nous ce que tu en penses. Alors, on continuera...

en effet, mon patron est quelque peu... rétissant au changement on va dire ;)  et préfère des bonnes vieilles macro excel aux outils plus performants (mais qui coûtent certes aussi plus cher).

Je vais regarder cette fonction et je reviens vers vous dès que j'ai un souci.

dans l'architecture de ma macro, je pensais faire quelque chose du genre :

je me place à la première ligne, je teste si elle est vide, si c'est le cas, je me déplace d'un cran vers la droite, et ce jusqu'à ce que je trouve une case non vide ( celle ou le "o" a été rempli) . je viens ensuite récupérer la valeur de la durée de la tache, et je rempli de "o" le nombre de cases précédents ma case colorée initialement.
ensuite je passe à la ligne suivante et je recommence.

le problème qui risque de se poser est l'arret de la macro, car il risque d'aller jusqu'à la ligne 65000 , mais bon, c'est l'idée principale, après ça n'est qu'un "détail " ^^ .

maintenant si on enlève les mise en forme conditionnelles, l'action a réalmiser au lieu d'écrire "o" sera de colorer la cellule, ce qui revient au même (mais j'avoue, c'est un peu plus propre)

que pensez vous de la démarche de la macro ? feriez vous différemment ?
Expert Programmation

Salut,

Rhalala, ces patrons radins :sarcastic:  Du coup, j'espère qu'il te paye bien.
Excel est un tableur, pas une bonne à tout faire :pfff: 

------------------------------------------

Ben non, je ne ferais pas du tout comme ça.
Comme j'utiliserais l'événement Worksheet_Change, je n'aurais que la ligne concernée à traiter. T'as un peu regardé cette fonction ?

en tant que stagiaire, je suis exploité... enfin bref, ça n'est pas le sujet ^^

pour la fonction change , j'ai regardé un peu ce quelle fait. elle peut être utile en effet :) 

je peux utiliser l'attribut row de ma target pour définir le numéro de la ligne ( target.row j'imagine), ainsi mon paramètre que je nommais "i" sera renseigné

je sais donc sur quelle ligne je travaille. maintenant il me faut trouver le moyen d'identifier la cellule dont la valeur est identique dans la deuxième ligne de mon tableau excel ( correspondant aux numéros de semaine calendaires) et colorier les j cellules précédentes ( enfin les j-1 vu que la cellule intersection fait partie de la durée également)

que pensez vous d'un truc du style :



imaginons que l'on se place en "Ri" , on prend la valeur "Bi"( numéro de semaine calendaire) , si elle est différente de la valeur "Pi" ( numéro de semaine désiré), on se place sur la cellule suivante, et on recommence, jusqu'à ce qu'elle soit égale. là on colorie la case, et on colorie ensuite les cases en revenant "vers la gauche". on colorie autant de cases que le paramètre "j" l'indique ( on aurait un petit compteur décrémental dans cette fonction en se déplaçant )





Expert Programmation

Arrête de me dire vous, c'est agaçant. ;) 

Eh, ben c'est bien vu tout ça.
Il ne s'agit pas seulement de colorier des cellules, il faut aussi les effacer. En effet, si on change la durée, avec un nombre plus petit par exemple, il faut colorier les uns et effacer les autres.

Alors voilà comment je te propose de faire. On ne va réagir que sur les lignes 3 à 10 (arbitrairement, tu ajusteras) et sur les colonnes P et Q.

  1. Sub Worksheet_Change(Target As Range)
  2. If 3 <= Target.Row And Target.Row <= 10 And _
  3. 17 <= Target.Column And Target.Column <= 18 _
  4. Then
  5. ' // On est bon :)
  6. ...
  7. End If
  8. End Sub


Bon, maintenant qu'on a la ligne y, on va de la colonne R (20) à la fin (255).
Si on trouve Py dans la ligne 2, on a la fin de ta zone. Disons que c'est la colonne x.
Ensuite, le début est facilement calculable. C'est la ligne y, et la colonne x - Py. Attention, faut pas que ça dépasse R !

Je n'ai pas Excel sous la main, je te laisse réfléchir. A demain.

Re bonjour,

en cette journée ensoleillée, j'ai pas mal avancé sur mon problème, mais rien ne se passe. :non:  ^^

voici mon code :

  1. Sub Worksheet_Change(Target As Range)
  2. Dim i, j, k As Integer
  3.  
  4.  
  5. If 3 <= Target.Row.Count And 16 <= Target.Column.Count And Target.Column.Count <= 17 _
  6. Then
  7. i = Target.Row.Count
  8. j = Worksheet.Range("Q&i").Value ' il s'agit ici de la durée de la tâche
  9.  
  10. ' pour info, Q correspond à la colonne 16, et R à la 17
  11.  
  12. Worksheet.Range("R&i").Select
  13.  
  14. k = Worksheet.ActiveCell.Column
  15.  
  16. ' On commence par effacer ce qu'il y a sur la ligne
  17.  
  18. Range("R&i:AN&i").Select
  19. Selection.ClearContents
  20. Selection.Interior.ColorIndex = xlNone
  21.  
  22. While Worksheet.Cells("i,16") <> Worksheet.Cells("2,k") ' On teste si les numéros de semaine correspondent afin de trouver le croisement "ligne-colonne"
  23.  
  24. Do
  25. ActiveCell.Offset(0, 1).Select ' si ce n'est pas le cas, on se déplace d'une cellule a droite et on recommence
  26.  
  27. k = Worksheet.ActiveCell.Column
  28. Loop
  29.  
  30. ' quand on est à l'intersection, on écrit dans la cellule et on la colorie
  31.  
  32. ActiveCell.FormulaR1C1 = "o"
  33. Selection.Font.ColorIndex = 6
  34. With Selection.Interior
  35. .ColorIndex = 6
  36. .Pattern = xlSolid
  37. End With
  38.  
  39. While j <> 0 ' on va ensuite se déplacer vers la gauche afin de colorier le nombre de cases necessaires
  40.  
  41. Do
  42. ActiveCell.Offset(0, -1).Select
  43. ActiveCell.FormulaR1C1 = "o"
  44. Selection.Font.ColorIndex = 6
  45. With Selection.Interior
  46. .ColorIndex = 6
  47. .Pattern = xlSolid
  48. End With
  49. j = j - 1
  50.  
  51.  
  52. Loop
  53.  
  54.  
  55. End If
  56. End Sub


Je pense qu'il ne s'agit que d'une petite subtilité, mais je n'arrive pas à la cerner. :??:  :fou:  :wahoo: 
Expert Programmation

C'est vraiment pas mal. +1
Mais il y a encore du boulot ;) 

Mettre Option Explicit au début du code.
C'est impératif et non négociable !
--> Déclarer et initialiser les variables.

Exercice
Comprendre la différence entre ces deux lignes :
  1. Msgbox "R&i"
  2. Msgbox "R" & i
--> Réécrire la ligne 12
Dans le cas des adresses de Range("...") à créer, préférer la syntaxe Cells(Row, Column).

Ligne 12 et 14. Ne pas utiliser de Select/Activate ni de Selection/ActiveTruc.
  1. ' // Code très moche qui ralentit très fortement les traitements
  2. Range("xx").Select
  3. ...Selection.Column...
  4.  
  5. ' // Code propre et efficace
  6. ... Range("xx").Column ...
--> Réécrire proprement le code.

Tu essaies de me réécrire ça ?

  1. Sub Worksheet_Change(Target As Range)
  2. Option Explicit
  3.  
  4. Dim i, j, k As Integer
  5.  
  6.  
  7. If 3 <= Target.Row.Count And 16 <= Target.Column.Count And Target.Column.Count <= 17 _
  8. Then
  9. i = Target.Row.Count
  10. j = Worksheet.Cells("i, 17").Value ' il s'agit ici de la durée de la tâche
  11.  
  12. ' pour info, Q correspond à la colonne 16, et R à la 17
  13.  
  14. k = Worksheet.Cells("i, 18").Column
  15.  
  16. ' On commence par effacer ce qu'il y a sur la ligne
  17.  
  18. 'Range("R&i:AN&i").Select
  19. Range("Cells(i,18):Cells(i,45)").Select
  20.  
  21. Selection.ClearContents
  22. Selection.Interior.ColorIndex = xlNone
  23.  
  24. While Worksheet.Cells("i,16") <> Worksheet.Cells("2,k") ' On teste si les numéros de semaine correspondent afin de trouver le croisement "ligne-colonne"
  25.  
  26. Do
  27. ActiveCell.Offset(0, 1).Select ' si ce n'est pas le cas, on se déplace d'une cellule a droite et on recommence
  28.  
  29. k = Worksheet.ActiveCell.Column
  30. Loop
  31.  
  32. ' quand on est à l'intersection, on écrit dans la cellule et on la colorie
  33.  
  34. ActiveCell.FormulaR1C1 = "o"
  35. Selection.Font.ColorIndex = 6
  36. With Selection.Interior
  37. .ColorIndex = 6
  38. .Pattern = xlSolid
  39. End With
  40.  
  41. While j <> 0 ' on va ensuite se déplacer vers la gauche afin de colorier le nombre de cases necessaires
  42.  
  43. Do
  44. ActiveCell.Offset(0, -1).Select
  45. ActiveCell.FormulaR1C1 = "o"
  46. Selection.Font.ColorIndex = 6
  47. With Selection.Interior
  48. .ColorIndex = 6
  49. .Pattern = xlSolid
  50. End With
  51. j = j - 1
  52.  
  53.  
  54. Loop
  55.  
  56.  
  57. End If
  58. End Sub


voici mon code un peu plus propre ... même motif, même punition, rien ne se passe. :??:  :pt1cable: 

pour info, j'ai essayé de faire ton petit exercice juste après la déclaration des variables , c'est à dire après le
  1. i = Target.Row.Count
  2. j = Worksheet.Cells("i, 17").Value ' il s'agit ici de la durée de la tâche
,
et rien ne se passe lors de la modification des cellules, le message Box n'apparait même pas ...
Expert Programmation

T'as vraiment fait l'exercice, et t'as toujours pas compris :ouch: 
M'enfin !Recommence :
  1. Msgbox "i, 17"
  2. Msgbox i & " " & 17


Bon, sinon, première erreur de ma part, ce n'est pas
  1. Sub Worksheet_Change(Target As Range)
mais
  1. Sub Worksheet_Change(ByVal Target As Range)
La différence est subtile.

Maintenant, regarde l'aide de Option Explicit. Le môssieu à dit "Au début du code".

  1. Sub Worksheet_Change(ByVal Target As Range)
  2.  
  3. ' // Pas bien. Seul k est entier.
  4. Dim i, j, k As Integer
  5.  
  6. ' // Bien.
  7. Dim i As Integer, j As Integer, k As Integer
  8.  
  9. If 3 <= Target.Row.Count And 16 <= Target.Column.Count And Target.Column.Count <= 17 _
  10. Then
  11. i = Target.Row.Count
  12. j = Worksheet.Cells("i, 17").Value ' il s'agit ici de la durée de la tâche
  13.  
  14. ' pour info, Q correspond à la colonne 16, et R à la 17
  15. ' // VIRE LES GUILLEMETS !
  16. k = Worksheet.Cells("i, 18").Column
  17.  
  18. ' On commence par effacer ce qu'il y a sur la ligne
  19.  
  20. 'Range("R&i:AN&i" ).Select
  21. ' // VIRE LES GUILLEMETS, et au passage, relis l'aide sur Range et remplace les : en conséquence
  22. ' // VIRE LE SELECT
  23. Range("Cells(i,18):Cells(i,45)").Select
  24. ' // VIRE LE SELECTION
  25. Selection.ClearContents
  26. ' // VIRE LE SELECTION
  27. Selection.Interior.ColorIndex = xlNone
  28.  
  29. ' // VIRE LES GUILLEMETS !
  30. ' // While Do, ça n'exite pas en VB. Relis l'aide
  31. While Worksheet.Cells("i,16") <> Worksheet.Cells("2,k") ' On teste si les numéros de semaine correspondent afin de trouver le croisement "ligne-colonne"
  32. Do
  33. ' // VIRE LE SELECT
  34. ActiveCell.Offset(0, 1).Select ' si ce n'est pas le cas, on se déplace d'une cellule a droite et on recommence
  35. ' // VIRE LE ACTIVETRUC
  36. k = Worksheet.ActiveCell.Column
  37. Loop
  38. ' quand on est à l'intersection, on écrit dans la cellule et on la colorie
  39. ' // VIRE LE ACTIVETRUC
  40. ActiveCell.FormulaR1C1 = "o"
  41. ' // VIRE LE SELECTION
  42. Selection.Font.ColorIndex = 6
  43. ' // VIRE LE SELECTION
  44. With Selection.Interior
  45. .ColorIndex = 6
  46. .Pattern = xlSolid
  47. End With
  48.  
  49. ' // While Do, ça n'exite pas en VB. Relis l'aide
  50. While j <> 0 ' on va ensuite se déplacer vers la gauche afin de colorier le nombre de cases necessaires
  51. Do
  52. ' // VIRE LE ACTIVETRUC
  53. ActiveCell.Offset(0, -1).Select
  54. ' // VIRE LE ACTIVETRUC
  55. ActiveCell.FormulaR1C1 = "o"
  56. ' // VIRE LE SELECTION
  57. Selection.Font.ColorIndex = 6
  58. ' // VIRE LE ACTIVETRUC
  59. With Selection.Interior
  60. .ColorIndex = 6
  61. .Pattern = xlSolid
  62. End With
  63. j = j - 1
  64.  
  65.  
  66. Loop
  67.  
  68.  
  69. End If
  70. End Sub


Je ne vais pas faire ton boulot, mais je vais aider à te le faire faire.
A la fin, ce sera ton code, et il fonctionnera. ;) 
Il fonctionnera bien en plus :sol: 

En effet, je n'avais pas pu faire l'exercice, car comme je l'ai dit précédemment, les message box ne se lancaient pas ( je les avait mis dans ma macro, se déclenchant au changement de le cellule). Je l'ai refait dansune autre macro, et tout à marché, et j'ai compris l'erreur ;)  avec les guillemets, cela correspond à la lettre i , alors que sans, a chaque fois qu'il croisera la lettre i , il la remplacera par sa valeur; :) 

j'ai cependant toujours le même problème de déclenchement de ma macro , rien ne se passe au changement des valeurs concernées.... :??: 

voici mon code , version 3 ^^

  1. Option Explicit
  2.  
  3. Sub Worksheet_Change(ByVal Target As Range)
  4.  
  5.  
  6. Dim i As Integer, j As Integer, k As Integer
  7.  
  8. If 3 <= Target.Row.Count And 16 <= Target.Column.Count And Target.Column.Count <= 17 _
  9. Then
  10. i = Target.Row.Count
  11. j = Worksheet.Cells(i, 17).Value ' il s'agit ici de la durée de la tâche
  12.  
  13.  
  14.  
  15. k = Worksheet.Cells(i, 18).Column
  16.  
  17. ' On commence par effacer ce qu'il y a sur la ligne
  18.  
  19. 'Range("R&i:AN&i").Select
  20. Range(Cells(i, 18), Cells(i, 45)).ClearContents
  21. Range(Cells(i, 18), Cells(i, 45)).Interior.ColorIndex = xlNone
  22.  
  23.  
  24. While Worksheet.Cells(i, 16) <> Worksheet.Cells(2, k) ' On teste si les numéros de semaine correspondent afin de trouver le croisement "ligne-colonne"
  25.  
  26.  
  27. Offset(0, 1).Select ' si ce n'est pas le cas, on se déplace d'une cellule a droite et on recommence
  28.  
  29. k = Worksheet.ActiveCell.Column
  30. Wend
  31.  
  32. ' quand on est à l'intersection, on écrit dans la cellule et on la colorie
  33.  
  34. FormulaR1C1 = "o"
  35. Font.ColorIndex = 6
  36. With Interior
  37. .ColorIndex = 6
  38. .Pattern = xlSolid
  39. End With
  40.  
  41. While j <> 0 ' on va ensuite se déplacer vers la gauche afin de colorier le nombre de cases necessaires
  42.  
  43.  
  44. Offset(0, -1).Select
  45. FormulaR1C1 = "o"
  46. Font.ColorIndex = 6
  47. With Interior
  48. .ColorIndex = 6
  49. .Pattern = xlSolid
  50. End With
  51. j = j - 1
  52.  
  53.  
  54. Wend
  55.  
  56.  
  57. End If
  58. End Sub


au passage, merci beaucoup de m'aider à ce point :bounce:  :ange: 
Expert Programmation

Citation :
au passage, merci beaucoup de m'aider à ce point
Je t'en prie.

Pas mal.

Il reste un activetruc en ligne 29 et un Select en ligne 44.

Les While Do .. Loop, ça n'existe pas. Les While .. Wend, ça ne devrait plus exister. Utilise des Do While .. Loop. Là encore, la différence est subtile ;) 

Quand je te dis de virer un truc, il faut sans doute le remplacer par quelque chose.

Bon, et puis Target.Row.Count et Target.Column.Count, ça n'existe pas. Il fallait lire Target.Rows.Count et Target.Columns.Count. On le compte pas une ligne, une colonne mais des lignes, des colonnes. Mea Culpa.

EDIT : Il fallait lire Target.Row et Target.Column. Re-Mea Culpa.

Bon, maintenant, on va vérifier le déclenchement :
  1. Sub Worksheet_Change(ByVal Target As Range)
  2. MsgBox "Changement"
  3. If 3 <= Target.Row And 16 <= Target.Column And Target.Column <= 17 _
  4. Then
  5. MsgBox "Et on est dans la bonne zone !"
  6. End If
  7. End Sub
Qu'est-ce que ça donne ?

le active truc en ligne 29 me permet de spécifier le numéro de colonne de la cellule active. pourquoi le supprimer ? à ce moment là je pourrais laisser k en tant que variable compteur et l'incrémenter à chaque fois que je passe d'une cellule à l'autre.

Pour ce qui est du select de la ligne 44, c'est bien l'opération que je veux faire, me placer (selectionner) la cellule précédente. j'ai du mal à cerner en quoi c'est un problème en fait.


Pour ce qui est du déclenchement... rien ne se passe. le premier msgbow "changement" n'apparait pas . :s pourtant mes macros sont actives dans le classeur et la syntaxe est correcte .... c'est étrange....
Expert Programmation

Non, tu ne veux pas sélectionner une cellule. Tu veux y faire référence.
(Comment ça je sais mieux que toi ce que tu veux faire ?! ;)  )

  1. ' // Pas bien
  2. ... Offset(0, 1).Select
  3. k = Worksheet.ActiveCell.Column
  4.  
  5. ' // Bien
  6. k = ... Offset(0, 1).Column

Tu comprends ?

Tu peux aussi pointer la cellule par une variable :
  1. Dim ma_cellule As Range
  2. Set ma_cellule = ... Offset(0, 1)
  3. k = ma_cellule.Column


Citation :
Pour ce qui est du déclenchement...
Où as-tu enregistré ton code ?

j'avais enregistré mon code dans... module 1, ça ne risquait pas de fonctionner , en effet ^^

je l'ai remis dans la bonne feuille, et il se déclenche ^^ . par contre il ne déclenche pas le second message box indiquant que l'on se trouve dans la bonne zone. les colonnes 16 et 17 sont pourtant bel et bien celles qui m'intéressent (comportant respectivement les numéro de semaine et durée des tâches)

  1. If 3 <= Target.Rows.Count And 16 <= Target.Columns.Count And Target.Columns.Count <= 17 Then
  2.  
  3. MsgBox "Et on est dans la bonne zone !"
  4. End If

l'architecture est totalement différente, mais certainement plus propre ;) 

au niveau de la coloration de la case en jaune, il me mettait une erreur, je l'ai corrigé en rajoutant ceci:

  1. zone_jaune.Font.ColorIndex = 6


Cependant, le code ne fonctionne pas totalement. Il m'éfface bien la zone blanche entière( y compris le quadrillage,mais bon, ce n'est qu'un détail ) , mais il ne me colorie pas la jaune.

j'effectue quelques tests pour essayer d'identifier le problème
Expert Programmation

Ah oui, j'ai utilisé Clear à la ligne 16. C'est un peu violent, je te l'accorde. Soit on met un peu de lessive :
  1. Range.Interior.ColorIndex = xlNone

Soit on y va à l'eau de javel concentrée [:patch]
  1. Range.Clear
.

Désol', je suis un bourrin [:nospheratu].

Choisis la moins mauvaise des réponses pour passer ce topic à [Résolu].
Lassé par la pub ? Créez un compte