OVH Cloud OVH Cloud

Une matricielle peut être à optimiser

3 réponses
Avatar
Frédo P.
Bonsoir
Ma question est simple: elle se résume à l'objet
Je n'ai pas réussi à faire mieux càd diviser une matricelle par une autre.

Private Sub Worksheet_Change(ByVal Cl As Excel.Range)
On Error GoTo gesterr
Dim lg As Double, lg2 As Double, grp As Object, AdTots As String,
AdPrds As String, _
AdQtes As String, AdAns As String, AdNoms As String, res As Single
Co=Cl.Column
lg=Cl.Row
Application.EnableEvents = False
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
lg2 = [A65000].End(xlUp).Row 'dernière ligne utilisée
If Co = 12 Or Co = 8 Or Co = 13 Then
Set Pxpr = Range("L" & lg)
If Pxpr.Value <> 0 And Pxpr.Offset(0, -4) <> 0 Then
Pxpr.Offset(0, 1) = Pxpr.Value / Pxpr.Offset(0, -4).Value
Pxpr.Offset(0, 2) = Pxpr.Offset(0, 1) * 6.55957
Pxpr.Offset(0, 1).NumberFormat = "#,##0.00 €"
Pxpr.Offset(0, 2).NumberFormat = "#,##0.00 F"
AdNoms = Sheets("Achats").Range("A2:A" & lg2).Address '
critère 1 ex:nom des fournisseurs
AdAns = Sheets("Achats").Range("C2:C" & lg2).Address '
critère 2 ex:années des achats
AdPrds = Sheets("Achats").Range("E2:E" & lg2).Address '
critère 3 ex:noms des produits
AdQtes = Sheets("Achats").Range("H2:H" & lg2).Address '
division :Quantitées
AdTots = Sheets("Achats").Range("L2:L" & lg2).Address '
somme :Montants des achats
'--------Formule matricielle de calcul de moyenne
result = Evaluate("SUM((" & AdNoms & "=A" & lg & ")*(" & AdAns & "=C" & lg
_
& ")*(" & AdPrds & "=E" & lg & ")*" & AdTots & ")/SUM((" & AdNoms &
"=A" & lg & ")* _
(" & AdAns & "=C" & lg & ")*(" & AdPrds & "=E" & lg & ")*" & AdQtes & ")")
'--------Voir la formule dans la cellule:
'Range("M"&lg).FormulaArray=("=SUM((" & AdNoms & "=A" & lg & ")*(" & AdAns &
"=C" & lg _
& ")*(" & AdPrds & "=E" & lg & ")*" & AdTots & ")/SUM((" & AdNoms &
"=A" & lg & ")* _
(" & AdAns & "=C" & lg & ")*(" & AdPrds & "=E" & lg & ")*" & AdQtes & ")")
End If
gesterr:
Application.EnableEvents = True
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub
--

Fred

3 réponses

Avatar
AV
Qques remarques/réponses :
* Pour faire une moyenne conditionnelle, pas besoin de faire une divison de la
somme des valeurs correspondant aux critères par le nbre de valeurs
correspondant à ces mêmes critères
La fonction MOYENNE (sous forme matricielle) ficellée comme suit fait très bien
l'affaire :
=MOYENNE(SI((Champ1= x)*(Champ2= y)*(Champ3= z);ChampDesValeurs))
* Tu gagnerais à définir tes plages de façon dynamique par la fonction DECALER
plutôt que d'utiliser, dans ton code, une variable pour la dernière ligne
renseignée.
Avantages : Allègement du code et non-nécessité de préciser le nom de la feuille
(si ce n'est pas celle active) dans la chaîne de caractères que tu soumets à
l'Evaluate

Exemple (simplifié) avec tes critères et tes plages
Moyenne des "AdQtés"(H2:Hx) pour les "AdNoms"(A2:Ax) = "A"
et les "AdAns"(C2:Cx) = "C"
et les "AdPrds"(E2:Ex) = "E"

Si la feuille active active est celle contenant les champs d'examen :
lg2 = [A65000].End(xlUp).Row
MsgBox Evaluate("average(if((A2:A" & lg2 & "=""A"")*(C2:C" & lg2 &
"=""C"")*(E2:E" & lg2 & "=""E""),H2:H" & lg2 & "))")

Si la feuille active active n'est pas celle contenant les champs d'examen :
lg2 = [Achats!A65000].End(xlUp).Row
MsgBox Evaluate("average(if((Achats!A2:A" & lg2 & "=""A"")*(Achats!C2:C" & lg2 &
"=""C"")*(Achats!E2:E" & lg2 & "=""E""),Achats!H2:H" & lg2 & "))")

Avec des plages nommées (fonction DECALER) et quelle que soit la feuille active
:
MsgBox [average(if((AdNoms="A")*(AdAns="C")*(AdPrds="E"),AdQtés))]

Plus simple et plus clair non ?

AV
Avatar
Frédo P.
Rebonjour Alain
il fait triste chez nous.

"AV" a écrit dans le message de news:
#
Qques remarques/réponses :
* Pour faire une moyenne conditionnelle, pas besoin de faire une division
de la

somme des valeurs correspondant aux critères par le Nbr de valeurs
correspondant à ces mêmes critères
La fonction MOYENNE (sous forme matricielle) ficelée comme suit fait très
bien

l'affaire :
=MOYENNE(SI((Champ1= x)*(Champ2= y)*(Champ3= z);ChampDesValeurs))
* Tu gagnerais à définir tes plages de façon dynamique par la fonction
DECALER

plutôt que d'utiliser, dans ton code, une variable pour la dernière ligne
renseignée.
Avantages : Allègement du code et non-nécessité de préciser le nom de la
feuille

(si ce n'est pas celle active) dans la chaîne de caractères que tu soumets
à

l'Evaluate

Exemple (simplifié) avec tes critères et tes plages
Moyenne des "AdQtés"(H2:Hx) pour les "AdNoms"(A2:Ax) = "A"
et les "AdAns"(C2:Cx) = "C"
et les "AdPrds"(E2:Ex) = "E"

Si la feuille active active est celle contenant les champs d'examen :
lg2 = [A65000].End(xlUp).Row
MsgBox Evaluate("average(if((A2:A" & lg2 & "=""A"")*(C2:C" & lg2 &
"=""C"")*(E2:E" & lg2 & "=""E""),H2:H" & lg2 & "))")

Si la feuille active active n'est pas celle contenant les champs d'examen
:

lg2 = [Achats!A65000].End(xlUp).Row
MsgBox Evaluate("average(if((Achats!A2:A" & lg2 & "=""A"")*(Achats!C2:C" &
lg2 &

"=""C"")*(Achats!E2:E" & lg2 & "=""E""),Achats!H2:H" & lg2 & "))")

Avec des plages nommées (fonction DECALER) et quelle que soit la feuille
active

:
MsgBox [average(if((AdNoms="A")*(AdAns="C")*(AdPrds="E"),AdQtés))]

Plus simple et plus clair non ?

AV
Oui cela va m'être utile mais dans tes exemples, Il manque un champ, j'ai

bien trois conditions + un champ de nombre de pieces achetées + un champ du
montant total (sur la même ligne) de l'achat, ,je recalcule le prix moyen
unitaire sur la totalité des achats en pièces et montants: voici la
disposition
A:A Fournisseurs | C:C Années de l'achat | H:H quantités | L:L Montants |
M:M Px unitaire(sur la ligne) | N:N Px moyens (champ à calculer)
Je ne pense pas qu'elle puisse trouver le px moyens sans lui donner les
montants non ? ou alors, ou c'est surnaturel ou j'ai mal compris.
je procède de cette manière parce qu'il y a encore 3 colonnes consacrées aux
ristournes qui viennent modifier les montants totaux sur la ligne.
Avec tes ex, je vais essayer de caser la division du total des montants par
le Nbr de pièces totales
Encore merci ,j'avance, je progresse,ça devient une drogue.
Fred



Avatar
Frédo P.
--
Fred


"AV" a écrit dans le message de news:
#
Qques remarques/réponses :
* Pour faire une moyenne conditionnelle, pas besoin de faire une divison
de la

somme des valeurs correspondant aux critères par le nbre de valeurs
correspondant à ces mêmes critères
La fonction MOYENNE (sous forme matricielle) ficellée comme suit fait très
bien

l'affaire :
=MOYENNE(SI((Champ1= x)*(Champ2= y)*(Champ3= z);ChampDesValeurs))
* Tu gagnerais à définir tes plages de façon dynamique par la fonction
DECALER

plutôt que d'utiliser, dans ton code, une variable pour la dernière ligne
renseignée.
Avantages : Allègement du code et non-nécessité de préciser le nom de la
feuille

(si ce n'est pas celle active) dans la chaîne de caractères que tu soumets
à

l'Evaluate

Exemple (simplifié) avec tes critères et tes plages
Moyenne des "AdQtés"(H2:Hx) pour les "AdNoms"(A2:Ax) = "A"
et les "AdAns"(C2:Cx) = "C"
et les "AdPrds"(E2:Ex) = "E"

Si la feuille active active est celle contenant les champs d'examen :
lg2 = [A65000].End(xlUp).Row
MsgBox Evaluate("average(if((A2:A" & lg2 & "=""A"")*(C2:C" & lg2 &
"=""C"")*(E2:E" & lg2 & "=""E""),H2:H" & lg2 & "))")

Si la feuille active active n'est pas celle contenant les champs d'examen
:

lg2 = [Achats!A65000].End(xlUp).Row
MsgBox Evaluate("average(if((Achats!A2:A" & lg2 & "=""A"")*(Achats!C2:C" &
lg2 &

"=""C"")*(Achats!E2:E" & lg2 & "=""E""),Achats!H2:H" & lg2 & "))")

Avec des plages nommées (fonction DECALER) et quelle que soit la feuille
active

:
MsgBox [average(if((AdNoms="A")*(AdAns="C")*(AdPrds="E"),AdQtés))]

Plus simple et plus clair non ?

AV
Oui cela va m'être utile mais dans tes exemples, Il manque un champ, j'ai

bien trois conditions + un champ de nombre de pieces achetées + un champ du
montant total (sur la même ligne) de l'achat, ,je recalcule le prix moyen
unitaire sur la totalité des achats en pièces et montants: voici la
disposition
A:A Fournisseurs | C:C Années de l'achat | E:E noms des Produits | H:H
quantités | L:L Montants |
M:M Px unitaire(sur la ligne) | N:N Px moyens (champ à calculer)
Je ne pense pas qu'elle puisse trouver le px moyens sans lui donner les
montants non ? ou alors, ou c'est surnaturel ou j'ai mal compris.
je procède de cette manière parce qu'il y a encore 3 colonnes consacrées aux
ristournes qui viennent modifier les montants totaux sur la ligne.
Avec tes ex, je vais essayer de caser la division du total des montants par
le Nbr de pièces totales
Encore merci ,j'avance, je progresse,ça devient une drogue.
Fred