Macro synthétique (Copier coller somme en fonction de plusieurs critères)
Bonjour à tous tout d'abord joyeuse fête de Noel à tous et une très bonne année à venir
Je viens vous solliciter votre appui pour un projet hyper important j'ai mis toutes les remarques en expliquant point par point directement sur le fichier excel joint.
Please aidez moi
Bonjour
Je ne comprends pas bien la différence entre ta feuille Achat-Vente et ta feuille Synthèse. Je dois être stupide.
Les lignes que tu as remplies pour ton exemple ne semblent pas correspondre à ce que tu dmandes ???
Merci de m'éclairer un peu plus si tu veux que j'essaie de t'aider
A+
Bonjour
Bonjour à tous
Un essai à tester. Te convient-il ?
...Je dois être stupide...
Oh que non !
Les valeurs données en exemple ne sont pas bonnes alors, il faut s'arracher quelques cheveux pour comprendre...sans être sûr du résultat !
Bye !
Bonsoir gmb
Tu me rassures
Bonnes fêtes de fin d'année
Cordialement
Bonsoir à tous,
Pour remplir la feuille "Achat-Vente" :
Option Explicit
Sub test()
Dim dico As Object, i As Long, n As Long, w(), e, s
Application.ScreenUpdating = False
Set dico = CreateObject("Scripting.Dictionary")
'la feuille source en 1ère position dans le classeur
With Sheets(1).Range("a8").CurrentRegion
For i = 2 To .Rows.Count
If Not dico.exists(.Cells(i, 1).Interior.ColorIndex) Then
Set dico(.Cells(i, 1).Interior.ColorIndex) = CreateObject("Scripting.Dictionary")
dico(.Cells(i, 1).Interior.ColorIndex).CompareMode = 1
End If
If Not dico(.Cells(i, 1).Interior.ColorIndex).exists(.Cells(i, 1).Value) Then
ReDim w(1 To 4, 1 To 1)
Else
w = dico(.Cells(i, 1).Interior.ColorIndex)(.Cells(i, 1).Value)
ReDim Preserve w(1 To 4, 1 To UBound(w, 2) + 1)
End If
w(1, UBound(w, 2)) = .Cells(i, 1).Value
w(2, UBound(w, 2)) = .Cells(i, 5).Value
w(3, UBound(w, 2)) = .Cells(i, 4).Value
w(4, UBound(w, 2)) = .Cells(i, 4).Value * .Cells(i, 5).Value
dico(.Cells(i, 1).Interior.ColorIndex)(.Cells(i, 1).Value) = w
Next
End With
'restitution dans la feuille cible
With Sheets("Achat-Vente")
'achat ---> bleu = 23
'vente ---> rouge = 46
For Each e In Array(Array(23, "a3"), Array(46, "g3"))
With .Range(e(1))
.CurrentRegion.Offset(2).ClearContents
For Each s In dico.Item(e(0))
With .Offset(n).Resize(UBound(dico.Item(e(0)).Item(s), 2), _
UBound(dico.Item(e(0)).Item(s), 1))
.Value = Application.Transpose(dico.Item(e(0)).Item(s))
End With
n = n + UBound(dico.Item(e(0)).Item(s), 2)
Next
End With
n = 0
Next
End With
Set dico = Nothing
Application.ScreenUpdating = True
End Sub
Bonjour
Je ne comprends pas bien la différence entre ta feuille Achat-Vente et ta feuille Synthèse. Je dois être stupide.
Les lignes que tu as remplies pour ton exemple ne semblent pas correspondre à ce que tu dmandes ???
Merci de m'éclairer un peu plus si tu veux que j'essaie de t'aider
A+
Effectivement les données ne sont pas juste j'ai mal calculer dsl
En fait la feuille Synthèse fera le total des quantités de mémé titre et et mémé cours, puisque sur la feuille Achat vente; il peut y avoir plusieurs lignes. Je m'explique d'avantage dans la capture d’écran.
Bonsoir à tous,
Pour remplir la feuille "Achat-Vente" :
Option Explicit Sub test() Dim dico As Object, i As Long, n As Long, w(), e, s Application.ScreenUpdating = False Set dico = CreateObject("Scripting.Dictionary") 'la feuille source en 1ère position dans le classeur With Sheets(1).Range("a8").CurrentRegion For i = 2 To .Rows.Count If Not dico.exists(.Cells(i, 1).Interior.ColorIndex) Then Set dico(.Cells(i, 1).Interior.ColorIndex) = CreateObject("Scripting.Dictionary") dico(.Cells(i, 1).Interior.ColorIndex).CompareMode = 1 End If If Not dico(.Cells(i, 1).Interior.ColorIndex).exists(.Cells(i, 1).Value) Then ReDim w(1 To 4, 1 To 1) Else w = dico(.Cells(i, 1).Interior.ColorIndex)(.Cells(i, 1).Value) ReDim Preserve w(1 To 4, 1 To UBound(w, 2) + 1) End If w(1, UBound(w, 2)) = .Cells(i, 1).Value w(2, UBound(w, 2)) = .Cells(i, 5).Value w(3, UBound(w, 2)) = .Cells(i, 4).Value w(4, UBound(w, 2)) = .Cells(i, 4).Value * .Cells(i, 5).Value dico(.Cells(i, 1).Interior.ColorIndex)(.Cells(i, 1).Value) = w Next End With 'restitution dans la feuille cible With Sheets("Achat-Vente") 'achat ---> bleu = 23 'vente ---> rouge = 46 For Each e In Array(Array(23, "a3"), Array(46, "g3")) With .Range(e(1)) .CurrentRegion.Offset(2).ClearContents For Each s In dico.Item(e(0)) With .Offset(n).Resize(UBound(dico.Item(e(0)).Item(s), 2), _ UBound(dico.Item(e(0)).Item(s), 1)) .Value = Application.Transpose(dico.Item(e(0)).Item(s)) End With n = n + UBound(dico.Item(e(0)).Item(s), 2) Next End With n = 0 Next End With Set dico = Nothing Application.ScreenUpdating = True End Sub
Bonne fêtes à tous
klin89
Merci bien c'est super!
Bonjour
Bonjour à tous
Un essai à tester. Te convient-il ?
...Je dois être stupide...
Oh que non !
Les valeurs données en exemple ne sont pas bonnes alors, il faut s'arracher quelques cheveux pour comprendre...sans être sûr du résultat !
Bye !
Effectivement les valeurs ne sont pas juste j'ai fais un mauvais calcul
Aussi j'ai tester en copiant les données d'un autre rapport et coller (à partir de la cellule A9 sur le fichier que tu m'envoyé; ça mets ''débogage". je mets un autre rapport pour test
re bidexcel,
Pour remplir la feuille "Synthese" :
Option Explicit
Sub test2()
Dim dico As Object, i As Long, n As Long, w(), e, s, v
Application.ScreenUpdating = False
Set dico = CreateObject("Scripting.Dictionary")
'la feuille source doit etre placee en 1ère position dans le classeur
With Sheets(1).Range("a8").CurrentRegion
For i = 2 To .Rows.Count
If Not dico.exists(.Cells(i, 1).Interior.ColorIndex) Then
Set dico(.Cells(i, 1).Interior.ColorIndex) = CreateObject("Scripting.Dictionary")
dico(.Cells(i, 1).Interior.ColorIndex).CompareMode = 1
End If
If Not dico(.Cells(i, 1).Interior.ColorIndex).exists(.Cells(i, 1).Value) Then
Set dico(.Cells(i, 1).Interior.ColorIndex)(.Cells(i, 1).Value) = CreateObject("Scripting.Dictionary")
End If
If Not dico(.Cells(i, 1).Interior.ColorIndex)(.Cells(i, 1).Value).exists(.Cells(i, 4).Value) Then
ReDim w(1 To 4)
w(1) = .Cells(i, 1).Value: w(3) = .Cells(i, 4).Value
Else
w = dico(.Cells(i, 1).Interior.ColorIndex)(.Cells(i, 1).Value)(.Cells(i, 4).Value)
End If
w(2) = w(2) + .Cells(i, 5).Value
w(4) = w(2) * w(3)
dico(.Cells(i, 1).Interior.ColorIndex)(.Cells(i, 1).Value)(.Cells(i, 4).Value) = w
Next
End With
'restitution dans la feuille cible
With Sheets("Synthese")
'achat ---> bleu = 23
'vente ---> rouge = 46
For Each e In Array(Array(23, "a3"), Array(46, "g3"))
With .Range(e(1))
.CurrentRegion.Offset(2).ClearContents
For Each s In dico(e(0))
For Each v In dico(e(0))(s)
With .Offset(n).Resize(1, UBound(dico(e(0))(s)(v), 1))
.Value = dico(e(0))(s)(v)
End With
n = n + 1
Next
Next
End With
n = 0
Next
End With
Set dico = Nothing
Application.ScreenUpdating = True
End Sub
La dernière boucle pourrait être retranscrite comme ceci, Item étant la propriété par défaut du dictionnaire
For Each e In Array(Array(23, "a3"), Array(46, "g3"))
With .Range(e(1))
.CurrentRegion.Offset(2).ClearContents
For Each s In dico.Item(e(0))
For Each v In dico.Item(e(0)).Item(s)
With .Offset(n).Resize(1, UBound(dico.Item(e(0)).Item(s).Item(v), 1))
.Value = dico.Item(e(0)).Item(s).Item(v)
End With
n = n + 1
Next
Next
End With
n = 0
Next
Salut comprends pas trop j'ai coller ta formule mais le débogage est la encore
A qui t'adresses tu bidexcel
Le code fonctionne dans le premier fichier joint, puisque je me base sur les 2 couleurs pour déterminer les clés du dictionnaire.
Dans le dernier code, on peut simplifier en supprimant une boucle imbriquée
For Each e In Array(Array(23, "a3"), Array(46, "g3"))
With .Range(e(1))
.CurrentRegion.Offset(2).ClearContents
For Each s In dico(e(0))
.Offset(n).Resize(UBound(Application.Transpose(dico(e(0))(s).items), 2), _
UBound(Application.Transpose(dico(e(0))(s).items), 1)).Value = _
Application.Transpose(Application.Transpose(dico(e(0))(s).items))
n = n + dico(e(0))(s).Count
Next
End With
n = 0
Next
Re bidexcel,
On peut déterminer les clés du dictionnaire parent sans tenir compte des 2 couleurs.
Le code réajusté :
Option Explicit
Sub test2()
Dim dico As Object, cle As String, i As Long, n As Long
Dim a, w(), e, s
Set dico = CreateObject("Scripting.Dictionary")
'la feuille source doit etre placee en 1ere position dans le classeur
With Sheets(1).Range("a8").CurrentRegion
a = .Value
For i = 2 To UBound(a, 1)
If Not IsEmpty(a(i, 8)) Then
If IsEmpty(a(i, 13)) Then
cle = "achat"
Else
cle = "achatetvente"
End If
Else
cle = "vente"
End If
If Not dico.exists(cle) Then
Set dico(cle) = CreateObject("Scripting.Dictionary")
dico(cle).CompareMode = 1
End If
If Not dico(cle).exists(a(i, 1)) Then
Set dico(cle)(a(i, 1)) = CreateObject("Scripting.Dictionary")
End If
If Not dico(cle)(a(i, 1)).exists(a(i, 4)) Then
ReDim w(1 To 4)
w(1) = a(i, 1): w(3) = a(i, 4)
Else
w = dico(cle)(a(i, 1))(a(i, 4))
End If
w(2) = w(2) + a(i, 5)
w(4) = w(2) * w(3)
dico(cle)(a(i, 1))(a(i, 4)) = w
Next
End With
Application.ScreenUpdating = False
'restitution dans la feuille cible
With Sheets("Synthese")
For Each e In Array(Array("achat", "a3"), Array("vente", "g3"))
With .Range(e(1))
.CurrentRegion.Offset(2).ClearContents
For Each s In dico(e(0))
.Offset(n).Resize(UBound(Application.Transpose(dico(e(0))(s).items), 2), _
UBound(Application.Transpose(dico(e(0))(s).items), 1)).Value = _
Application.Transpose(Application.Transpose(dico(e(0))(s).items))
n = n + dico(e(0))(s).Count
Next
End With
n = 0
Next
End With
Set dico = Nothing
Application.ScreenUpdating = True
End Sub
Je te rappelle que les données de la feuille source commencent en A8 dans ton exemple
klin89
Salut Klin89 grand merci pour le fichier il fonctionne bien mais j'ai remarque qu il ne prenait pas en compte les transactions croisées de type "C'' (pour ces transactions il y a fois 'sur la ligne de la transaction ''203' dans la colonne des achats ainsi que des ventes
comme le montre le fichier que j'ai joint.
Si tu peux m'aider pour ce dernier détail ça serait super super cool
Re bidexcel
Faut te suivre
Il faut donc simplement boucler sur la colonne 8 et 13
Option Explicit
Sub test2()
Dim dico As Object, cle As String, i As Long, n As Long
Dim a, w(), e, s
Set dico = CreateObject("Scripting.Dictionary")
'la feuille source doit etre placee en 1ere position dans le classeur
With Sheets(1).Range("a8").CurrentRegion
a = .Value
For Each e In Array(Array(8, "achat"), Array(13, "vente"))
For i = 2 To UBound(a, 1)
If Not IsEmpty(a(i, e(0))) Then
cle = e(1)
If Not dico.exists(cle) Then
Set dico(cle) = CreateObject("Scripting.Dictionary")
dico(cle).CompareMode = 1
End If
If Not dico(cle).exists(a(i, 1)) Then
Set dico(cle)(a(i, 1)) = CreateObject("Scripting.Dictionary")
End If
If Not dico(cle)(a(i, 1)).exists(a(i, 4)) Then
ReDim w(1 To 4)
w(1) = a(i, 1): w(3) = a(i, 4)
Else
w = dico(cle)(a(i, 1))(a(i, 4))
End If
w(2) = w(2) + a(i, 5)
w(4) = w(2) * w(3)
dico(cle)(a(i, 1))(a(i, 4)) = w
End If
Next
Next
End With
Application.ScreenUpdating = False
'restitution dans la feuille cible
With Sheets("Synthese")
For Each e In Array(Array("achat", "a3"), Array("vente", "g3"))
With .Range(e(1))
.CurrentRegion.Offset(2).ClearContents
For Each s In dico(e(0))
.Offset(n).Resize(UBound(Application.Transpose(dico(e(0))(s).items), 2), _
UBound(Application.Transpose(dico(e(0))(s).items), 1)).Value = _
Application.Transpose(Application.Transpose(dico(e(0))(s).items))
n = n + dico(e(0))(s).Count
Next
End With
n = 0
Next
End With
Set dico = Nothing
Application.ScreenUpdating = True
End Sub
Il ne faut pas placé le code dans le Thisworkbook mais dans un module standard
Le code du bouton doit aussi figuré dans le module de la feuille concernée
Là, tu m'as embrouillé
klin89