Forum Clubic

Excel vba calcul avec référence matriciel

:hello: à tous

Voilà, j’ai une petite question qui peut paraitre simple pour certains, mais pas pour moi.

Comment utiliser le calcul matriciel en VBA en utilisant une fonction SumProduct avec une fonction Radians ou Signe intégré à l’intérieur même d’une fonction Sumproduct ?

Un simple exemple:

Marche:


...
With Application.WorksheetFunction
[AY32:AY34] = .SumProduct([BB37:BB39], ([BD37:BD39]))
End With

Ne marche pas:


...
With Application.WorksheetFunction
[AY32:AY34] = .SumProduct([BB37:BB39], .Radians([BD37:BD39]))
End With

ou


...
With Application.WorksheetFunction
[AY32:AY34] = .SumProduct([BB37:BB39], Sgn([BD37:BD39]))
End With

Erreur d’exécution ‘13’:
Incompatibilité de type

Les fonctions .Radians ou Sgn n’accepte pas plusieurs cellules en même temps alors que la fonction principale (maîtresse j’ai envie de dire) est ici une fonction SOMMEPROD qui est censé utiliser le calcul matriciel. Les calculs en Excel (hors VBA) fonctionnent correctement pourtant. Je cherche une méthode qui pourrai faire accepter un Range (Matriciel) à une fonction basique non matriciel tel qu’un simple Radians, Sin, Cos ou autre.

Merci :slight_smile: .

:hello:

Peut être qu’un modérateur pourrai déplacer ce sujet en Programmation ? Ça serai plus adapté je pense.

Merci :jap:

sumproduct a pour résultat une unique valeur et non un tableau. Si on était dans le cadre de Perl, je dirais que sumproduct fournit un résultat scalaire et non une liste.

Du coup il y a inadéquation de dimension entre le Range dans lequel tu espères obtenir plusieurs résultats et l’unique valeur de retour de sumproduct.

Bonjours,

Merci pour cette réponse.

Cependant, la fonction (du moins en Excel) SOMMEPROD est une fonction Matriciel qui remplace avantageusement les accolades utilisé pour les autres fonctions. La Fonction SOMMEPROD en Excel (hors VBA) fonctionne comme suit, exemple:

$A…$B…$C (ici, la lettre des colonnes) : La 1ère, 2ème et 3ème valeurs sont A10, B10, C10 et les 3 dernières valeurs sont en A13, B13, C13

An......Fn......?n
10......7........-55	
25......10......-23	
35......2........68	
20......25......-12	
40......14......-35	

En D20: D100, tu as:


t
0
1
2
3
4
5
...
80

En faisant en E20:E100

= SOMMEPROD($A$10:$A$13;Sin(2*PI()*$B$10:$B$13*[@[t]] + RADIANS($C$10:$C$13))

Tu obtiens:
E20 = 10 * Sin(2pi7*0+Rad(-55)) + 25 * Sin(2pi10*0+Rad(-23)) + 35 * Sin(2pi2*0+Rad(68 )) + 20 * Sin(2pi25*0+Rad(-12)) + 40 * Sin(2pi14*0+Rad(-35))

E21 = 10 * Sin(2pi7*1+Rad(-55)) + 25 * Sin(2pi10*1+Rad(-23)) + 35 * Sin(2pi2*1+Rad(68 )) + 20 * Sin(2pi25*1+Rad(-12)) + 40 * Sin(2pi14*1+Rad(-35))

E80 = 10 * Sin(2pi7*80+Rad(-55)) + 25 * Sin(2pi10*80+Rad(-23)) + 35 * Sin(2pi2*80+Rad(68 )) + 20 * Sin(2pi25*80+Rad(-12)) + 40 * Sin(2pi14*80+Rad(-35))

Ici, c’est simplifié puisqu’il n’y a que 5 valeurs de An, 5 de fn et 5 de ?n.

La fonction SOMMEPROD multiplie en colonne (A1B1C1) et additionne en ligne. Voilà ce que ça peut donner (c’est juste un simple exemple fait avec 20 An, Fn et ?n et 4096 valeurs de t):
[spoiler]
http://image.clubic.com/01208767-photo-photo.jpg
[/spoiler]

La fonction SOMMEPROD est parmis les fonctions les plus puissante de Excel. :slight_smile:

Et je n’arrive pas à l’utiliser en VBA mais marche au poil en Excel (sans VBA) et comme dit plus haut, la 1ère solution marche, mais pas les autres car elles font appel à des fonctions qui par définition sont non matriciel, cependant, elles sont utilisées à l’intérieur d’une fonction SOMMEPROD qui elle est matriciel et le VBA ne le voit pas, donc il doit manqué quelque chose pour que le VBA arrive à voir que je veux utiliser une structure matriciel. :slight_smile:


[quote="Jaidee"]

Du coup il y a inadéquation de dimension entre le Range dans lequel tu espères obtenir plusieurs résultats et l’unique valeur de retour de sumproduct.
[/quote]
Dans l’exemple cité plus haut, je devrai avoir les même valeurs dans les cellules [AY32:AY34] c’est à dire dans AY32, AY33 et AY34.

P.S.: Je vois ce que tu veux dire, au lieu de mettre [AY32:AY34] = …, mettre [AY32] tout court, puis [AY33] sur une autre ligne en incrémentant ? Mais ça ne marche pas non plus. Il doit y avoir un truc. Une petite subtilité.
Edité le 06/06/2013 à 19:31

En parlant d’accolade, c’est exactement ce qu’il faudrai mettre aux fonction Sin ou Rad mais des accolades en VBA. Donc la question reviendrai peut être à : Qu’est-ce qui remplace les accolades en VBA ?

OK. J’ai capté le problème.

Malheureusement, je ne crois pas que VBA permette la définition en mémoire de formules-tableau. Ca oblige donc à ajouter 1 colonne dans Excel pour y mettre tes radians, de la façon suivante :


With Application.WorksheetFunction 
  [AZ32:AZ34].FormulaArray = "=RADIANS(BD37:BD39)"
  [AY32:AY34] = .SumProduct([BB37:BB39], [AZ32:AZ34]) 
End With

…assurément ça alourdit le calcul. Mais ça reste peut-être acceptable pour ton utilisation ?

Sinon, dans ta formule tu as mentionné un [@[t]]. Je comprends sa signification dans ton explication mais cela ne fonctionne pas dans mon Excel. Si tu as une référence à me fournir sur le sujet, je suis curieux.
Edité le 06/06/2013 à 22:40

Si, on peux utiliser un espace mémoire en utilisant (par exemple) un:

Dim VariableQuelqonque(2,1) As Variant

Où 2 est le nombre de ligne et 1 est le nbres de colonne (espace attribuer en mémoire vive): On peut tout faire avec Excel :smiley:
C’est d’ailleurs comme ça qu’il faudrai systématiquement le programmer (du moins en x64).

Merci bien pour ta réponse. L’utilisation des Array à l’air intéressante (je ne m’en suis encore jamais servi, je suis assez novice en VBA). Il y a juste le .formula que je ne veux pas, mais les array seront à tester.

Hélas non, je ne veux pas de formule. Je peux créer les formules hors VBA sinon.

Oui, c’est normal, il s’agit du t d’un tableau (référence structurée). Si tu n’as pas créer un tableau avec une colonne t et que ton calcul n’est pas fait à l’intérieur même du tableau, ça ne pourra marcher. Je me suis trompé, c’est [@t].
A l’extérieur d’un tableau, ça serai Tableau1[@t] au lieu de [@t] tout court.

En fait, la question s’avère beaucoup plus simple finalement:
Qu’est-ce qui remplace les accolades en VBA ?

Si je fait en Excel avec ces données en A1:A3:

-2
3
4

en A4, je fait:

=SIGNE(A1:A3)

Cela ne marche pas car SIGNE n’est pas une fonction matricielle, en revanche, si je sélectionne la plage A4:A6 et entre la formule matricielle suivante:

{=SIGNE(A1:A3)}

Cela marche et j’obtient ici (en A4:A6):

-1
1
1

Finalement, la question concerne l’équivalent des accolades en version VBA. Car il n’y a que les fonctions matricielle qui fonctionne nativement en matricielle, et elle sont très peu nombreuses, elles doivent représenter 2 ou 3% des fonctions d’Excel en tout. Il y a les SOMME, les PRODUIT, les SOMMEPROD, les PRODUIT. (PRODUIT.MAT par exemple), les SOMME. (SOMME.SERIES par exemple) et quelques autres qui sont natives, mais sinon, il faut systématiquement des accolades (pas pratique dutout d’ailleurs) pour rendre les fonctions sous forme matricielles.

Sinon, j’ai vu ça (Magnifique) www.generation-nt.com…

En VBA, ça donne :

With Application.WorksheetFunction
[AY32:AY34] = Application.Radians([BC26:BC28])
End With

Il fallait la trouver celle là. Mettre 2 fois “Application”.

Cela dit, les fonctions basique hors Application.WorksheetFunction (Sin, Cos, Sgn etc…) ne fonctionne pas. Donc c’est un petit bordel ce Excel en version VBA.
Bon, de toute façon, ce n’ai pas important, j’essai d’apprendre petit à petit le VBA, mais si je n’arrive pas à faire mieux qu’avec Excel, l’intérêt du VBA en devient limité. :slight_smile:
Edité le 07/06/2013 à 10:28