Lien entre plusieurs tableaux
Bonjour,
J’ai un problème d’utilisation de VBA. Mon fichier Excel (en pièce jointe) correspond à un tableau de gestion d’avancement (en feuil1) et un tableau de réserve (en feuil2).
Mon problème est que j’aimerais lier ces tableaux afin de faire apparaitre dans le premier tableau d’avancement lorsqu’il y a une réserve dans un logement.
Lorsque l’on double clic sur une cellule (D3 :I12) un userform apparait, lorsque l’on complète l’userform une ligne est ajouté au tableau de réserve. J’aimerais d’une part que les 3 premières lignes de l’userform se remplissent automatiquement en fonction de l’endroit où l’on clique (par exemple si on clique en E5, il apparait : 3 ;RdC ;A02) ; et d’autre part j’aimerais qu’une mise en forme (cellule rayé) soit appliqué lorsque une réserve est présente. Dans l’idéal, il faudrait que lorsque la colonne « état de la réserve » soit vide, la cellule correspondante dans la feuille « avancement » soit rayé, et lorsque au contraire « état de la réserve » est remplis, la mise en forme s’annule.
Ça fait beaucoup de demande d’un coup, je ne sais pas si je suis claire dans mes explications ? Ça m’aiderait énormément de trouver une solution, car je bloque dessus depuis plusieurs semaines maintenant… J’ai mis en pièce joint une partie de mon fichier pour illustrer mes propos et montrer ce que j’ai déjà fait.
Je vous remercie de votre aide par avance !
Audrey
Bonjour Audrey,
Voici une proposition de code dans la pièce jointe :
Si cela vous convient, n'hésitez pas à m'en faire part !
Samuel
Bonjour, je vous remercie pour le fichier renvoyé, il correspond parfaitement à ce que je cherchais à faire.
J'essaie donc maintenant de comprendre les codes, pour les adapter à mon fichier, et pouvoir le refaire plus tard.
Tous les codes que vous avez mis dans "macro1" ont-il une utilité ou c'est juste un brouillon ? Si ils ont une utilité, j'ai du mal à les comprendre et à trouver à quel moment est-ce qu'ils servent ?
Merci pour votre réponse qui à été très rapide et surtout efficace.
Audrey,
Le module1 peut être supprimé. Il n'a aucun intérêt.
Sinon, voici ce que j'ai ajouté :
Module Ajout_reverse :
A enlever les MsgBox qui étaient là pour "debugguer" et qui n'ont plus d'utilité.
Dim Logement As String
Dim Etage As String
Dim Tache As String
/* Pour récupérer la tâche, je prends la valeur la plus à gauche de la ligne de la cellule sélectionnée */
Tache = Target.End(xlToLeft).End(xlToLeft)
/* Pour récupérer la valeur logement, je remonte à la première cellule qui contient une donnée au-dessus de la cellule sélectionnée */
Logement = Target.End(xlUp).Value
/* Pour récupérer l'étage, je remonte au plus haut. Comme il y a des cellules fusionnées, il faut prendre la première valeur la plus à gauche */
Etage = Target.End(xlUp).End(xlUp).Value
If (Etage = "") Then
Etage = Target.End(xlUp).End(xlUp).End(xlToLeft).Value
End If
/* MsgBox : A supprimer */
MsgBox (Tache)
MsgBox (Logement)
MsgBox (Etage)
/* Affectation des valeurs initialisées précédemment */
Ajout_de_reserve.TextBox1.Text = Tache
Ajout_de_reserve.TextBox2.Text = Logement
Ajout_de_reserve.TextBox3.Text = Etage
Module Feuil2 (Réserves)
Private Sub Worksheet_Change(ByVal Target As Range)
Dim WatchRange As Range
Dim IntersectRange As Range
Dim c As Range
Dim r As Range
Set WatchRange = Range("G:G")
Set IntersectRange = Intersect(Target, WatchRange)
On Error Resume Next
If (Target.Value <> "") Then
If (Target.End(xlToLeft).Value <> "" And Target.End(xlToLeft).Offset(rowOffset:=0, columnOffset:=1).Value <> "") Then
With Worksheets(1).Range("A:A")
Set c = .Find(Target.End(xlToLeft).Value, LookIn:=xlValues)
If Not c Is Nothing Then
MsgBox (c.Row)
End If
End With
With Worksheets(1).Rows(2)
Set r = .Find(Target.End(xlToLeft).Offset(rowOffset:=0, columnOffset:=1).Value, LookIn:=xlValues)
If Not r Is Nothing Then
MsgBox (r.Column)
End If
End With
Worksheets(1).Cells(c.Row, r.Column).Borders(xlDiagonalDown).LineStyle = xlNone
Worksheets(1).Cells(c.Row, r.Column).Borders(xlDiagonalUp).LineStyle = xlNone
With Worksheets(1).Cells(c.Row, r.Column).Borders(xlEdgeLeft)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With Worksheets(1).Cells(c.Row, r.Column).Borders(xlEdgeTop)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With Worksheets(1).Cells(c.Row, r.Column).Borders(xlEdgeBottom)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
With Worksheets(1).Cells(c.Row, r.Column).Borders(xlEdgeRight)
.LineStyle = xlContinuous
.ColorIndex = 0
.TintAndShade = 0
.Weight = xlThin
End With
Worksheets(1).Cells(c.Row, r.Column).Borders(xlInsideVertical).LineStyle = xlNone
Worksheets(1).Cells(c.Row, r.Column).Borders(xlInsideHorizontal).LineStyle = xlNone
End If
End If
End Sub
D'accord, je comprend mieux avec ces explications.
Il me reste un dernier point de blocage, et après mon tableau sera terminé. C'est au moment d'affecter l'emplacement des tâches, logements, et étages.
" 'Pour récupérer la tâche, je prends la valeur la plus à gauche de la ligne de la cellule sélectionnée
Tache = Target.End(xlToLeft).End(xlToLeft)
'Pour récupérer la valeur logement, je remonte à la première cellule qui contient une donnée au-dessus de la cellule sélectionnée */
Logement = Target.End(xlUp).Value
'Pour récupérer l'étage, je remonte au plus haut. Comme il y a des cellules fusionnées, il faut prendre la première valeur la plus à gauche */
Etage = Target.End(xlUp).End(xlUp).Value
If (Etage = "") Then
Etage = Target.End(xlUp).End(xlUp).End(xlToLeft).Value
End If "
J'ai compris la manière dont c'est fait, mais j'aimerais trouver un autre moyen de sélectionner l'emplacement avec la colonne en variable et la ligne en fixe. Je ne sais pas si c'est possible ?
J'aimerais faire ça car mon tableau final est plus complexe que celui envoyé, et il y a donc beaucoup plus de lignes, et les 3 formules que vous m'avez proposé ne peuvent pas être adapter dans mon cas.
Mes explications sont-elles compréhensible ou vous avez besoin d'un exemple en tableau ?
Audrey,
Vous pouvez essayer cela :
Tache = ActiveSheet.Cells(Target.Row, 1)
'Tache prend la valeur de la ligne de la cellule ciblée et la première colonne
Logement = ActiveSheet.Cells(2, Target.Column)
'Logement prend la valeur de la colonne de la cellule ciblée et la deuxième ligne
Etage = ActiveSheet.Cells(1, Target.Column)
If (Etage = "") Then
Etage = ActiveSheet.Cells(1, Target.Column).End(xlToLeft).Value
End If
'Etage prend la valeur de la colonne de la cellule ciblée et la première ligne. Si celle-ci est vide, c'est que c'est une cellule fusionnée, on prend donc la première valeur de la cellule fusionnée.
C'est exactement ce que je cherchais à faire !
J'ai bien réussi à adapter toutes les formules à mon tableau qui est maintenant terminé.
Merci beaucoup pour le temps passé et les explications très claire qui m'ont beaucoup aidé !