Tri de deux tableaux liés

Nplayer76

XLDnaute Nouveau
Bonjour,

j'espère que l'un de vous pourra m'éclairer, car là je sèche un peu.

Sur un onglet j'ai un tableau où sont rentrées des données.
Sur un 2ème onglet j'ai un second tableau, qui reprend certaines données du 1er, et qui est complété par des données rentrées manuellement.

Mon problème est que lorsque j'effectue un tri sur le 1er tableau, dans le 2e tableau seules les données liées au 1er sont triées, les données rentrées manuellement ne suivent pas, ce qui me casse le tableau.

Auriez-vous une solution (traditionnelle ou en VBA) pour que le tri s'effectue sur les 2 tableaux ?

Merci d'avance.
 

job75

XLDnaute Barbatruc
Bonjour Nplayer76, le forum,

S'il y a des formules volatiles dans la feuille "Copie" il suffit d'ajouter la 2ème ligne de code :
Code:
Private Sub Worksheet_Calculate()
If ActiveSheet.Name = Me.Name Then Exit Sub 'permet les entrées manuelles et le filtrage de la feuille
Dim colman1%, ncolman%, colmax%, sel As Range, t, d As Object, i&, x$, j%, a(), s
colman1 = 11 'n° de la 1ère colonne d'entrée manuelle, à adapter
ncolman = 44 'nombre de colonnes d'entrée manuelle jointives, à adapter
colmax = colman1 + ncolman - 1 'n° de la dernière colonne d'entrée manuelle
Application.ScreenUpdating = False
Application.EnableEvents = False 'désactive les évènements
On Error GoTo 1
If Me.FilterMode Then Me.ShowAllData 'si la feuille est filtrée
With [A1].CurrentRegion.Offset(1).Resize([A1].CurrentRegion.Rows.Count - 1) 'évite la ligne d'en-têtes
  Set sel = Selection 'mémorise
  Application.Undo
  t = .Resize(, colmax).Value2 'tableau précédent, .Value2 important pour les dates/heures
  Application.Undo
  sel.Select
  Set d = CreateObject("Scripting.Dictionary")
  For i = 1 To UBound(t)
    x = "" 'RAZ
    For j = colman1 To colmax
      x = x & Chr(1) & t(i, j)
    Next
    d(t(i, 1)) = Mid(x, 2) 'mémorise la concaténation
  Next
  t = .Columns(1).Value2 'colonne de référence du dernier tableau
  ReDim a(1 To UBound(t), 1 To ncolman)
  For i = 1 To UBound(t)
    s = Split(d(t(i, 1)), Chr(1))
    For j = 1 To ncolman
      a(i, j) = s(j - 1)
      If IsNumeric(a(i, j)) Then a(i, j) = CDbl(a(i, j))
  Next j, i
  .Columns(colman1).Resize(, ncolman) = a 'restitution
  .Rows.AutoFit 'ajustement hauteurs des lignes
End With
1 Application.EnableEvents = True 'réactive les évènements
Application.ScreenUpdating = True
End Sub
J'ai remis les Application.EnableEvents, il n'y a plus de problème.

Cette macro fonctionnant dans tous les cas de figure, utilisez-la qu'il y ait ou non des formules volatiles.

Edit : voyez aussi le code du ThisWorkbook.

Fichier (3).

Bon dimanche.
 

Pièces jointes

  • Tri lié sur tableau Excel(3).xlsm
    40.2 KB · Affichages: 41
Dernière édition:

Nplayer76

XLDnaute Nouveau
Bonjour,

ah oui effectivement phénomène curieux. Je n'avais pas essayé de rentrer de nouvelles données manuelles.
Ca montre la complexité d'une fonctionnalité qui parait relativement anodine (le tri de 2 tableaux liés).
Je ne comprends pas la ligne "activesheet.name" qui permet le filtrage de la feuille.

Bonne soiréee
 

Nplayer76

XLDnaute Nouveau
Bonjour,

je soumets une nouvelle interrogation. Les formats de cellules ne suivent pas le tri. Après plusieurs essais je ne trouve pas de solution.

Avec les dernières macros, ça ne fonctionne plus pour une feuille supplémentaire. Quel(s) critère(s) est(sont) à modifier pour une feuille 3 ?
 
Dernière édition:

job75

XLDnaute Barbatruc
Re,
Les formats de cellules ne suivent pas le tri.
La question me paraît curieuse.

Il faut bien sûr que toutes les cellules d'une même colonne soient formatées de la même manière.

C'est même la règle quand on est en mode tableau.

N'oubliez pas d'activer le renvoi à la ligne pour tout le tableau.

Et si vous voulez mettre en évidence certaines cellules en les colorant il faut le faire par mise en forme conditionnelle (MFC).

En mode tableau c'est toujours ainsi qu'on procède.

A+
 
Dernière édition:

job75

XLDnaute Barbatruc
Re,
Avec les dernières macros, ça ne fonctionne plus pour une feuille supplémentaire. Quel(s) critère(s) est(sont) à modifier pour une feuille 3 ?
Bon je devine que vous voulez 2 feuilles liées "Copie1" et "Copie2".

Dans ce cas il faut traiter les 2 feuilles en parallèle dans une seule et même macro.

Il est logique de la placer dans ThisWorkbook, voici le code de ce module :
Code:
Private Sub Workbook_Open()
Me.Saved = True 'évite l'invite à la fermeture si aucune modification
End Sub

Private Sub Workbook_SheetCalculate(ByVal Sh As Object)
Dim F1 As Worksheet, F2 As Worksheet
Set F1 = Feuil2: Set F2 = Feuil3 'CodeNames des feuilles à traiter, à adapter
If Sh.Name <> F1.Name Then Exit Sub 'une seule feuille déclencheuse
If ActiveSheet.Name = F1.Name Or ActiveSheet.Name = F2.Name Then Exit Sub 'permet les entrées manuelles et le filtrage de la feuille
Dim colman1%, colman2%, ncolman1%, ncolman2%, colmax1%, colmax2%
Dim P1 As Range, P2 As Range, sel As Range, t1, t2, d As Object, i&, x$, j%, a(), s
colman1 = 11: colman2 = 11 'n° de la 1ère colonne d'entrée manuelle, à adapter pour chaque feuille
ncolman1 = 44: ncolman2 = 44 'nombre de colonnes d'entrée manuelle jointives, à adapter pour chaque feuille
colmax1 = colman1 + ncolman1 - 1 'n° de la dernière colonne d'entrée manuelle de la 1ère feuille
colmax2 = colman2 + ncolman2 - 1 'n° de la dernière colonne d'entrée manuelle de la 2ème feuille
Application.ScreenUpdating = False
Application.EnableEvents = False 'désactive les évènements
On Error GoTo 1
If F1.FilterMode Then F1.ShowAllData 'si la feuille est filtrée
If F2.FilterMode Then F2.ShowAllData 'si la feuille est filtrée
Set P1 = F1.[A1].CurrentRegion.Offset(1).Resize(F1.[A1].CurrentRegion.Rows.Count - 1) 'évite la ligne d'en-têtes
Set P2 = F2.[A1].CurrentRegion.Offset(1).Resize(F2.[A1].CurrentRegion.Rows.Count - 1) 'évite la ligne d'en-têtes
Set sel = Selection 'mémorise
Application.Undo
t1 = P1.Resize(, colmax1).Value2 'tableau précédent, .Value2 important pour les dates/heures
t2 = P2.Resize(, colmax2).Value2 'tableau précédent, .Value2 important pour les dates/heures
Application.Undo
sel.Select
'---traitement de la 1ère feuille---
Set d = CreateObject("Scripting.Dictionary")
For i = 1 To UBound(t1)
  x = "" 'RAZ
  For j = colman1 To colmax1
    x = x & Chr(1) & t1(i, j)
  Next
  d(t1(i, 1)) = Mid(x, 2) 'mémorise la concaténation
Next
t1 = P1.Columns(1).Value2 'colonne de référence du dernier tableau
ReDim a(1 To UBound(t1), 1 To ncolman1)
For i = 1 To UBound(t1)
  s = Split(d(t1(i, 1)), Chr(1))
  For j = 1 To ncolman1
    a(i, j) = s(j - 1)
    If IsNumeric(a(i, j)) Then a(i, j) = CDbl(a(i, j))
Next j, i
P1.Columns(colman1).Resize(, ncolman1) = a 'restitution
P1.Rows.AutoFit 'ajustement hauteurs des lignes
'---traitement de la 2ème feuille---
d.RemoveAll 'RAZ
For i = 1 To UBound(t2)
  x = "" 'RAZ
  For j = colman2 To colmax2
    x = x & Chr(1) & t2(i, j)
  Next
  d(t2(i, 1)) = Mid(x, 2) 'mémorise la concaténation
Next
t2 = P2.Columns(1).Value2 'colonne de référence du dernier tableau
ReDim a(1 To UBound(t2), 1 To ncolman2)
For i = 1 To UBound(t1)
  s = Split(d(t1(i, 1)), Chr(1))
  For j = 1 To ncolman1
    a(i, j) = s(j - 1)
    If IsNumeric(a(i, j)) Then a(i, j) = CDbl(a(i, j))
Next j, i
P2.Columns(colman2).Resize(, ncolman2) = a 'restitution
P2.Rows.AutoFit 'ajustement hauteurs des lignes
1 Application.EnableEvents = True 'réactive les évènements
Application.ScreenUpdating = True
End Sub
Noter que comme il n'y a qu'une feuille déclencheuse (Feuil2) on pourrait mettre la macro dans le code de cette feuille.

Fichier (4).

A+
 

Pièces jointes

  • Tri lié sur tableau Excel(4).xlsm
    50.2 KB · Affichages: 21
Dernière édition:

job75

XLDnaute Barbatruc
Re,

Petite dernière, on peut alléger le code avec la macro paramétrée Traitement :
Code:
Private Sub Workbook_Open()
Me.Saved = True 'évite l'invite à la fermeture si aucune modification
End Sub

Private Sub Workbook_SheetCalculate(ByVal Sh As Object)
Dim F1 As Worksheet, F2 As Worksheet
Set F1 = Feuil2: Set F2 = Feuil3 'CodeNames des feuilles à traiter, à adapter
If Sh.Name <> F1.Name Then Exit Sub 'une seule feuille déclencheuse
If ActiveSheet.Name = F1.Name Or ActiveSheet.Name = F2.Name Then Exit Sub 'permet les entrées manuelles et le filtrage de la feuille
Dim colman1%, colman2%, ncolman1%, ncolman2%, colmax1%, colmax2%, P1 As Range, P2 As Range, sel As Range, t1, t2
colman1 = 11: colman2 = 11 'n° de la 1ère colonne d'entrée manuelle, à adapter pour chaque feuille
ncolman1 = 44: ncolman2 = 44 'nombre de colonnes d'entrée manuelle jointives, à adapter pour chaque feuille
colmax1 = colman1 + ncolman1 - 1 'n° de la dernière colonne d'entrée manuelle de la 1ère feuille
colmax2 = colman2 + ncolman2 - 1 'n° de la dernière colonne d'entrée manuelle de la 2ème feuille
Application.ScreenUpdating = False
Application.EnableEvents = False 'désactive les évènements
On Error GoTo 1
If F1.FilterMode Then F1.ShowAllData 'si la feuille est filtrée
If F2.FilterMode Then F2.ShowAllData 'si la feuille est filtrée
Set P1 = F1.[A1].CurrentRegion.Offset(1).Resize(F1.[A1].CurrentRegion.Rows.Count - 1) 'évite la ligne d'en-têtes
Set P2 = F2.[A1].CurrentRegion.Offset(1).Resize(F2.[A1].CurrentRegion.Rows.Count - 1) 'évite la ligne d'en-têtes
Set sel = Selection 'mémorise
Application.Undo
t1 = P1.Resize(, colmax1).Value2 'tableau précédent, .Value2 important pour les dates/heures
t2 = P2.Resize(, colmax2).Value2 'tableau précédent, .Value2 important pour les dates/heures
Application.Undo
sel.Select
'---traitement de chaque feuille---
Traitement colman1, ncolman1, colmax1, t1, P1
Traitement colman2, ncolman2, colmax2, t2, P2
1 Application.EnableEvents = True 'réactive les évènements
Application.ScreenUpdating = True
End Sub

Sub Traitement(colman%, ncolman%, colmax%, t, P As Range)
Dim d As Object, i&, x$, j%, a(), s
Set d = CreateObject("Scripting.Dictionary")
For i = 1 To UBound(t)
  x = "" 'RAZ
  For j = colman To colmax
    x = x & Chr(1) & t(i, j)
  Next
  d(t(i, 1)) = Mid(x, 2) 'mémorise la concaténation
Next
t = P.Columns(1).Value2 'colonne de référence du dernier tableau
ReDim a(1 To UBound(t), 1 To ncolman)
For i = 1 To UBound(t)
  s = Split(d(t(i, 1)), Chr(1))
  For j = 1 To ncolman
    a(i, j) = s(j - 1)
    If IsNumeric(a(i, j)) Then a(i, j) = CDbl(a(i, j))
Next j, i
P.Columns(colman).Resize(, ncolman) = a 'restitution
P.Rows.AutoFit 'ajustement hauteurs des lignes
End Sub
Fichier (4 bis).

Bonne fin de soirée.
 

Pièces jointes

  • Tri lié sur tableau Excel(4 bis).xlsm
    50.2 KB · Affichages: 31
Dernière édition:

Nplayer76

XLDnaute Nouveau
Bonjour le forum,

je reviens vers vous pour un nouvel approfondissement, en me disant que toute cette discussion pourra aider quelqu'un ultérieurement, et moi dans l'immédiat ^^.

Je n'arrive pas à adapter le code pour pouvoir rajouter une colonne manuelle à traiter, qui n'est pas adjacente aux autres.

De plus je viens de me rendre compte d'une anomalie. Une fois le tri effectué, ou même un filtre, les données rentrées dans les colonnes manuelles mais obtenues via une formule se transforment en données brutes.

Voici le code élaboré par job75 :

Code:
Private Sub Workbook_Open()
Me.Saved = True 'évite l'invite à la fermeture si aucune modification
End Sub

Private Sub Workbook_SheetCalculate(ByVal Sh As Object)
Dim F1 As Worksheet, F2 As Worksheet
Set F1 = Feuil2: Set F2 = Feuil3 'CodeNames des feuilles à traiter, à adapter
If Sh.Name <> F1.Name Then Exit Sub 'une seule feuille déclencheuse
If ActiveSheet.Name = F1.Name Or ActiveSheet.Name = F2.Name Then Exit Sub 'permet les entrées manuelles et le filtrage de la feuille
Dim colman1%, colman2%, ncolman1%, ncolman2%, colmax1%, colmax2%, P1 As Range, P2 As Range, sel As Range, t1, t2
colman1 = 11: colman2 = 11 'n° de la 1ère colonne d'entrée manuelle, à adapter pour chaque feuille
ncolman1 = 44: ncolman2 = 44 'nombre de colonnes d'entrée manuelle jointives, à adapter pour chaque feuille
colmax1 = colman1 + ncolman1 - 1 'n° de la dernière colonne d'entrée manuelle de la 1ère feuille
colmax2 = colman2 + ncolman2 - 1 'n° de la dernière colonne d'entrée manuelle de la 2ème feuille
Application.ScreenUpdating = False
Application.EnableEvents = False 'désactive les évènements
On Error GoTo 1
If F1.FilterMode Then F1.ShowAllData 'si la feuille est filtrée
If F2.FilterMode Then F2.ShowAllData 'si la feuille est filtrée
Set P1 = F1.[A1].CurrentRegion.Offset(1).Resize(F1.[A1].CurrentRegion.Rows.Count - 1) 'évite la ligne d'en-têtes
Set P2 = F2.[A1].CurrentRegion.Offset(1).Resize(F2.[A1].CurrentRegion.Rows.Count - 1) 'évite la ligne d'en-têtes
Set sel = Selection 'mémorise
Application.Undo
t1 = P1.Resize(, colmax1).Value2 'tableau précédent, .Value2 important pour les dates/heures
t2 = P2.Resize(, colmax2).Value2 'tableau précédent, .Value2 important pour les dates/heures
Application.Undo
sel.Select
'---traitement de chaque feuille---
Traitement colman1, ncolman1, colmax1, t1, P1
Traitement colman2, ncolman2, colmax2, t2, P2
1 Application.EnableEvents = True 'réactive les évènements
Application.ScreenUpdating = True
End Sub

Sub Traitement(colman%, ncolman%, colmax%, t, P As Range)
Dim d As Object, i&, x$, j%, a(), s
Set d = CreateObject("Scripting.Dictionary")
For i = 1 To UBound(t)
   x = "" 'RAZ
   For j = colman To colmax
     x = x & Chr(1) & t(i, j)
   Next
   d(t(i, 1)) = Mid(x, 2) 'mémorise la concaténation
Next
t = P.Columns(1).Value2 'colonne de référence du dernier tableau
ReDim a(1 To UBound(t), 1 To ncolman)
For i = 1 To UBound(t)
   s = Split(d(t(i, 1)), Chr(1))
   For j = 1 To ncolman
     a(i, j) = s(j - 1)
     If IsNumeric(a(i, j)) Then a(i, j) = CDbl(a(i, j))
Next j, i
P.Columns(colman).Resize(, ncolman) = a 'restitution
P.Rows.AutoFit 'ajustement hauteurs des lignes
End Sub
 
Dernière édition:

job75

XLDnaute Barbatruc
BonjourNplayer76,
Je n'arrive pas à adapter le code pour pouvoir rajouter une colonne manuelle à traiter, qui n'est pas adjacente aux autres.
Bah depuis le post #7 les colonnes manuelles sont toujours jointives, ne comptez pas sur moi pour traiter tous les cas de figure possibles.
De plus je viens de me rendre compte d'une anomalie. Une fois le tri effectué, ou même un filtre, les données rentrées dans les colonnes manuelles mais obtenues via une formule se transforment en données brutes.
Ce n'est pas une anomalie, en toute logique des colonnes "manuelles" ne contiennent pas de formules.

Maintenant s'il y en a dans certaines colonnes il suffit de les restituer à la fin.

Ce fichier (5) traite le cas d'une seule colonne avec formule : L pour la feuille "Copie1", N pour la feuille "Copie2".

A+
 

Pièces jointes

  • Tri lié sur tableau Excel(5).xlsm
    51.1 KB · Affichages: 16

Nplayer76

XLDnaute Nouveau
Bonjour job75.


Bah depuis le post #7 les colonnes manuelles sont toujours jointives, ne comptez pas sur moi pour traiter tous les cas de figure possibles.

Je ne vous demandez pas ça ne vous inquiétez pas. C'était juste si ce n'était qu'une question de paramétrage simple. Je vais contourner le problème en déplaçant ma colonne.

Ce n'est pas une anomalie, en toute logique des colonnes "manuelles" ne contiennent pas de formules.

Oui ma terminologie prêtait à confusion. Je parlais de données manuelles car elles étaient indépendants de la 1ere feuille, mais certaines se remplissaient en combinant plusieurs cellules de la feuille 2. Votre fichier 5 marche très bien, et j'ai pu rajouter des colonnes supplémentaires. C'était, j'espère, mon dernier problème rencontré à ce sujet.

Merci beaucoup pour toute l'aide et votre réactivité.
 

job75

XLDnaute Barbatruc
Re,

Ce fichier (6) va mieux, on peut mettre maintenant des formules dans toutes les colonnes "manuelles" que l'on veut.

Il suffisait de remplacer .Value2 par .FormulaR1C1, sauf pour la colonne (1) de référence.

A+
 

Pièces jointes

  • Tri lié sur tableau Excel(6).xlsm
    51.2 KB · Affichages: 21

Discussions similaires

Statistiques des forums

Discussions
312 276
Messages
2 086 713
Membres
103 377
dernier inscrit
fredy45