Rechercher : dans
Par :

[VBA EXCEL] besoin d'aide pour une macro

Dernière réponse le 28 nov 2007 à 16:01:58 Nyck0las, le 22 nov 2007 à 12:03:51 
 Signaler ce message aux modérateurs

Bonjour,

voila je suis super débutant en VBA et j'essaie de programmer une fonction complémentaire.
Mon but est de prendre comme argument une plage de cellules (plusieurs cellules sur une meme ligne ou sur une meme colone), de déterminer le nombre de cellules. A partir de là, je construis un vecteur colonne en prenant les données de la plage de cellules et une matrice.
On termine ensuite par un ou 2 petits calculs.

Je vous mets ce que j'ai écrit pour me dire ce qui ne va pas ...

Function Note(E)
' E correspond à une plage de cellules

Dim n As Integer
Dim an
Dim A, Am
Dim i As Integer, j As Integer
Dim lg As Integer, cl As Integer

Set P = Range("E")
lg = P.Rows.Count
cl = P.Columns.Count
'mes données sont sur une meme ligne ou sur une meme colonne
' et je souhaite le déterminer
If cl = 1 Then
n = lg
ElseIf lg = 1 Then
n = cl
End If

an = 2 * Pi / n

'définition de ma matrice et de mon vecteur
Dim M(n - 1, n - 1)
Dim X(n - 1, 0)

If cl = 1 Then
For i = 0 To n - 1
X(i - 1, 0) = R(i - 1, 0)
Next i
ElseIf lg = 1 Then
For i = 0 To n - 1
X(i - 1, 0) = R(0, i - 1)
Next i
End If

For i = 0 To n - 1
For j = 0 To n - 1
M(i, j) = 0
Next j
Next i

M(n - 1, 0) = 1
For i = 0 To n - 2
M(i, i + 1) = 1
Next i

'quelques petits calculs
A = 1 / 2 * Sin(an) * Transpose(X) * M * X
Am = 1 / 2 * Sin(an) * 100 ^ 2 * n
Note = A / Am

End Function


merci bp

Configuration: Windows XP
Internet Explorer 6.0

1

le père, le 22 nov 2007 à 12:13:50

Bonjour,

Set P = Range("E") 

avec ça, tu travailles sur la colonne E et non pas sur la plage E passée en paramètre
travaille directement avec E si c'est un objet range ou à la rigueur fais set P=E

Répondre à le père

2

Nyck0las, le 22 nov 2007 à 12:58:44

J'ai donc supprimé la ligne

Set P = Range("E")

et je travaille directement avec E, c'est à dire que j'ai remplacé P par E partout (d'ailleurs je ne rends compte que dans les lignes de code il ne faut pas lire R mais P)

le message d'erreur est alors le suivant : "constante requise" en me surlignant le second n dans :

Dim M(n - 1, n - 1)

Répondre à Nyck0las

3

Nyck0las, le 22 nov 2007 à 15:09:48

Quand je sélectionne une ou plusieurs plages de cellules en argumant de ma fonction, est-ce qu'elle le comprend ? Mon argument est bien un objet de type Range ? parce que j'ai essayé un truc tout simple :

Function Test(Z)

Test = Z.Areas.Count

End Function

et çà marche pas ...

Répondre à Nyck0las

4

ShaBoo, le 22 nov 2007 à 15:19:12

Bonjour,

Quel erreur as tu ?

Répondre à ShaBoo

6

Nyck0las, le 22 nov 2007 à 15:43:10

Soit il me renvoie 0 quand il devrait me sortir 1 et #valeur pour 2 ou plus

Répondre à Nyck0las

5

le père, le 22 nov 2007 à 15:29:09
  • +1

Bonjour,

Dim M(n - 1, n - 1) ne marche pas, les dimensions doivent être constantes. Pour céer un tableau de dimensions variables il faut faire :
Dim M()
Redim M(n-1,n-1)

Quand à savoir si l'argument passé est bien de type range... Il n'y a que toi qui peux le savoir, c'est toi qui sais comment tu appelles ta fonction ! Comment fais-tu pour l'appeler ?

S'il te plaît quand tu dis "ça ne marche pas", précise : as-tu un message d'erreur,lequel, le résultat est-il faux ?...

Répondre à le père

7

Nyck0las, le 22 nov 2007 à 16:56:51

Mais si n est correctement défini avant, les dimensions sont constantes.

Bien sur que je sais comment j'appelle ma fonction, ce que je voulais c'était m'assurer qu'une plage de données est bien un objet de type range et savoir comment l'utiliser après.

Répondre à Nyck0las

9

ShaBoo, le 22 nov 2007 à 17:05:05

A quel niveau est défini ton n ? Feuille, Module, ... ???

Répondre à ShaBoo

10

le père, le 22 nov 2007 à 17:58:22

Bonjour,

Mais si n est correctement défini avant, les dimensions sont constantes.

Dans ton exemple initial Dim M(n-1, n-1) n est une variable puisque tu définis n par Dim n as integer.
Attention, en informatique, une variable dont on ne change jamais la valeur n'est pas la même chose qu'une constante.

Répondre à le père

8

ShaBoo, le 22 nov 2007 à 17:03:49

Bonjour,

Je viens de tester l'utilisation d'une constante dans la definition de dimension d'un tableau et ça marche (idem pour 2 dimensions)

Const cN = 10


Sub test()

Dim aTab(cN - 1, cN)

Debug.Print UBound(aTab())

End Sub


(Je suis en Excel 2000)

Répondre à ShaBoo

11

le père, le 22 nov 2007 à 18:00:09
  • +1

Bonjour,

ça ne marche même QUE avec des constantes

Répondre à le père

12

Nyck0las, le 23 nov 2007 à 09:52:22

Je définis n comme constante mais je lui affecte une valeur avant de l'utiliser donc normalement çà ne devrait pas poser de problème ...

j'ai modifié un peu mon code, voici la nouvelle version. A mon avis je crois qu'il y a un pb avec la plage de données en argument, son traitement ...

Function Note(P)
' P correspond à une plage de cellules

Dim n As Integer
Dim an
Dim A, Am
Dim i As Integer, j As Integer
Dim E As Range

E = P.Select

n = 0

For i = 1 To E.Areas.Count
n = n + E.Areas(i).Columns.Count
Next i

an = 2 * Pi / n

'définition de ma matrice et de mon vecteur
Dim M(n - 1, n - 1)
Dim X(n - 1, 0)

If cl = 1 Then
For i = 0 To n - 1
X(i - 1, 0) = E(i - 1, 0)
Next i
ElseIf lg = 1 Then
For i = 0 To n - 1
X(i - 1, 0) = E(0, i - 1)
Next i
End If

For i = 0 To n - 1
For j = 0 To n - 1
M(i, j) = 0
Next j
Next i

M(n - 1, 0) = 1
For i = 0 To n - 2
M(i, i + 1) = 1
Next i

'quelques petits calculs
A = 1 / 2 * Sin(an) * Transpose(X) * M * X
Am = 1 / 2 * Sin(an) * 100 ^ 2 * n
Note = A / Am

End Function

Répondre à Nyck0las

13

ShaBoo, le 23 nov 2007 à 10:14:51

Quelques petites réflexions ... ;p

Function Note(P)
' P correspond à une plage de cellules

Dim n As Integer
Dim an
Dim A, Am
Dim i As Integer, j As Integer
Dim E As Range

E = P.Select 'est ce bien utile ?

n = 0

'je ne vois pas pourquoi tu fais une boucle ici
' si P est une plage tu n'auras qu'un Area
For i = 1 To E.Areas.Count
  n = n + E.Areas(i).Columns.Count
Next i

an = 2 * Pi / n

'définition de ma matrice et de mon vecteur
Dim M(n - 1, n - 1)
Dim X(n - 1, 0) ' tu devrais le définir comme ceci : Dim X(n - 1)

If cl = 1 Then  'comment est initialisé cl ?
  For i = 0 To n - 1
    X(i - 1, 0) = E(i - 1, 0)  
  Next i
ElseIf lg = 1 Then 'comment est initialisé lg ?
  For i = 0 To n - 1
    X(i - 1, 0) = E(0, i - 1)
  Next i
End If

For i = 0 To n - 1
  For j = 0 To n - 1
    M(i, j) = 0
  Next j
Next i

M(n - 1, 0) = 1
For i = 0 To n - 2
  M(i, i + 1) = 1
Next i

'quelques petits calculs
A = 1 / 2 * Sin(an) * Transpose(X) * M * X
Am = 1 / 2 * Sin(an) * 100 ^ 2 * n
Note = A / Am

End Function


Sinon, quels sont les erreurs que tu as ??

Répondre à ShaBoo

14

Nyck0las, le 23 nov 2007 à 10:28:10

En fait çà peut etre un ensemble de plages du type A1:C1;G1:J1 donc il peut y avoir plusieurs areas

pour lg et cl, c'est une erreur de ma part, il faut remplacer le paragraphe par

For i = 0 To n - 1
X(i - 1, 0) = E(0, i - 1)
Next i

Répondre à Nyck0las

15

ShaBoo, le 23 nov 2007 à 10:33:03

en fait çà peut etre un ensemble de plages du type A1:C1;G1:J1 donc il peut y avoir plusieurs areas

Peut etre ... mais un ensemble de plage fait une plage.

Fais un :

Debug.Print E.Areas.Count


Pour t'en rendre compte

Répondre à ShaBoo

16

Nyck0las, le 23 nov 2007 à 11:39:22

J'ai fait cette petite macro

Sub Try()

Dim z As Range

Worksheets("Feuil1").Activate

Set z = ActiveSheet.Range("B2:C2", "E2")

Debug.Print z.Rows.Count

End Sub

et quand je la lance çà semble fonctionner mais rien ne s'affiche ...

Répondre à Nyck0las

17

ShaBoo, le 23 nov 2007 à 11:42:42

Remplace :

Debug.Print z.Rows.Count

Par :

MsgBox z.Rows.Count

Répondre à ShaBoo

18

Nyck0las, le 23 nov 2007 à 11:53:32

Hiihaaaaaaaaaaaaaa

enfin quelque chose qui marche !!!!!!!!!!!

il m'affiche bien 1 comme résultat donc tu as raison un ensemble de plage = 1 plage

Répondre à Nyck0las

19

ShaBoo, le 23 nov 2007 à 11:53:59

Lol

Répondre à ShaBoo

20

ShaBoo, le 23 nov 2007 à 11:55:56

Tu aurais pu voir l'affichage de :

Debug.Print z.Rows.Count


Dans la fenetre "Execution" (si elle est affichée bien sur ;p) de ton editeur vba ...

Répondre à ShaBoo

22

Nyck0las, le 23 nov 2007 à 12:03:32

J'ai pas trouvé ...

Répondre à Nyck0las

23

ShaBoo, le 23 nov 2007 à 12:05:01

Lol ...

quand tu es dans l'editeur vba, tu fais "CTRL+G"

Répondre à ShaBoo

25

Nyck0las, le 23 nov 2007 à 12:16:03

çà marche !!

Répondre à Nyck0las

21

Nyck0las, le 23 nov 2007 à 11:55:59

J'ai fait quelques tests de rows et columns.count
et je me rends compte que lorsque je prends un ensemble de plage, il considère la plage qui recouvre tout.
En gros si je choisis
Range("B2:C3", "E5:F5")
il comprend
Range("B2:F5")

Répondre à Nyck0las

24

Nyck0las, le 23 nov 2007 à 12:15:18

Il faudrait une liste de range en argument dont la taille n'est pas définie

Répondre à Nyck0las

26

ShaBoo, le 23 nov 2007 à 14:16:28

La "taille" d'un Range n'est définie que par ce que tu veux bien lui mettre dedans.

Répondre à ShaBoo

27

Nyck0las, le 23 nov 2007 à 14:32:43

Mais encore ....?????...????

moi ce que je voudrais c'est que lorsque j'indique
B2:C3;E5:F5
il comprenne
B2:C3 + E5:F5
et non
B2:F5
et ce qu'il y ait 2 plages ou plus

Répondre à Nyck0las

28

ShaBoo, le 23 nov 2007 à 14:40:41

Il faudrait voir les fonctions Union ou bien Intersect pour voir ce cela peut resoudre ton pb.

Sinon tu fais 2 objets Range ...

Répondre à ShaBoo

29

Nyck0las, le 23 nov 2007 à 16:06:38

Je ne vois pas du tout comment faire pour avoir en argument d'une fonction un ensemble de plage.

Dans la fonction SOMME par ex, je peux mettre en argument tout un ensemble de cellules contigues ou non et çà marche. Je voudrais faire la même chose ...

Répondre à Nyck0las

30

ShaBoo, le 23 nov 2007 à 16:31:26

Tu met un bouton sur ta feuille, tu double-click dessus et tu arrives sur l'editeur vba.

Private Sub CommandButton1_Click()

Debug.Print flNomDeTaFonction(ActiveSheet.Range("B2:C2"),ActiveSheet.Range("E5:C5")
  
End Sub





Dans un module tu mets ceci :

Function flNomDeTaFonction(Dim oPlg1 As Range, Dim oPlg2 As Range) As Long

Dim lRes As Long

'ici tu mets ta petite bidouille de calcul avec oPlg1 et oPlg2 (noublie pas : ce sont des ranges)
'avec lRes qui stocke le resultat


fNomDeTaFonction = lRes
End Function

Répondre à ShaBoo

31

Nyck0las, le 23 nov 2007 à 16:41:41

Ok c'est cool
mais comment je peux faire si je veux un nombre n de range, avec n non défini ?????????
that is the question ...

Répondre à Nyck0las

32

ShaBoo, le 23 nov 2007 à 17:12:52

Ok ...

Ceci devrait te ravir :

Private Sub CommandButton1_Click()

Debug.Print flNomDeTaFonction(Union(ActiveSheet.Range("B2:C3"), ActiveSheet.Range("E5:F5")))

End Sub



Function flNomDeTaFonction(oPlg As Range) As Long

Dim lRes As Long

Debug.Print oPlg.Areas(1).AddressLocal
Debug.Print oPlg.Areas(2).AddressLocal

'ici tu mets ta petite bidouille de calcul avec oPlg.Areas(1) et oPlg.Areas(2)  (noublie pas : ce sont des ranges)
'avec lRes qui stocke le resultat


flNomDeTaFonction = lRes
End Function

Répondre à ShaBoo

33

Nyck0las, le 26 nov 2007 à 14:36:19

J'ai peut-etre trouvé une solution à mon pb avec :

Public Function Test(ParamArray Rng() As Variant) As Long
Dim I As Integer, CellCount As Integer

For I = 0 To UBound(Rng)
CellCount = CellCount + Rng(I).Cells.Count
Next

Test = CellCount
End Function

ce qui permet d'avoir un ensemble de plages en argument.

Répondre à Nyck0las

34

Nyck0las, le 26 nov 2007 à 14:37:23

Par contre j'ai un autre problème et oui ....

cette fois par rapport à du calcul matriciel.

J'ai défini
le vecteur X(n-1) et la matrice M(n-1,n-1)
et je voudrais calculer tX*M*X avec tX représentant "transposé de X".
J'ai marqué :
Transpose(X) * M * X
mais çà ne marche pas

çà indique
"erreur de compilation : sub ou function non définie" en surlignant la fonction "transpose" dans le code

Répondre à Nyck0las

35

Nyck0las, le 27 nov 2007 à 11:57:17

J'ai fait quelques modifs dans le programme et voici le résultat :

Sub Notation()

Dim min As Integer, max As Integer
Dim PE(1), EE(0), SE(1)
Dim PA(0), EA(1), SA(1)
Dim i As Integer

Worksheets("Feuil1").Activate

min = 2
max = 9

EE(0) = "B"
PE(0) = "C"
PE(1) = "d"
SE(0) = "E"

SA(0) = "f"
EA(0) = "g"
PA(0) = "h"
EA(1) = "i"

SE(1) = "j"
SA(1) = "j"

For i = min To max
If Cells(i, "a") = "Eau" Then
Cells(i, "k").Value = Note(i, PE())
Cells(i, "l").Value = Note(i, EE())
Cells(i, "m").Value = Note(i, SE())
ElseIf Cells(i, "a") = "Ass" Then
Cells(i, "k").Value = Note(i, PA())
Cells(i, "l").Value = Note(i, EA())
Cells(i, "m").Value = Note(i, SA())
Next

End Sub
______________________________________________________

Function Note(lg As Integer, ParamArray Rng() As Variant) As Long

Dim i As Integer, j As Integer, n As Integer
Dim alpha, pi
Dim A, Am

'calcul du nombre de cellules
n = UBound(Rng) + 1

'calcul de l'angle
pi = 4 * Atn(1)
alpha = 2 * pi / n

Debug.Print n

'définition de ma matrice M
Dim M()
ReDim M(n - 1, n - 1)

For i = 0 To n - 1
For j = 0 To n - 1
M(i, j) = 0
Next
Next

M(n - 1, 0) = 1

For i = 0 To n - 2
M(i, i + 1) = 1
Next

'definition du vecteur X
Dim X()
ReDim X(n - 1, 0)

For i = 0 To n - 1
X(i, 0) = ActiveSheet.Cells(lg, Rng(i).Value)
Next

'création de la tranposé de X
Dim TX()
Call Tvect(X, TX)

'quelques petits calculs
Dim p1(), p2()

Call PMAT(M(), X(), p1())
Call PMAT(TX(), p1(), p2())

A = 1 / 2 * Sin(alpha) * p2(0, 0)
Am = 1 / 2 * Sin(alpha) * 100 ^ 2 * n

Note = A / Am

End Function
__________________________________________________
Sub PMAT(A(), B(), C())

Dim i As Integer, j As Integer, k As Integer
Dim n As Integer, M As Integer, p As Integer

n = UBound(A, 2)
M = UBound(A, 1)
p = UBound(B, 2)

ReDim C(M, p)

For i = 0 To M
For j = 0 To p
For k = 0 To n
C(i, j) = C(i, j) + A(i, k) * B(k, j)
Next
Next
Next

End Sub
__________________________________
Sub Tvect(X(), TX())

Dim i As Integer, n As Integer

n = UBound(X, 1)

ReDim TX(0, n)

For i = 0 To n
TX(0, i) = X(i, 0)
Next

End Sub


Quand je le lance, le message d'erreur est le suivant :
"variable ou précédure attendue et non un module"
et la première occurence de "note" est surlignée dans la procédure notation

perso je ne vois pas trop où çà coince ....

Répondre à Nyck0las

36

ShaBoo, le 27 nov 2007 à 14:49:17

Bonjour,

Essaye ceci :

Function Note(lg As Integer, Dim Rng() As Variant) As Long

Répondre à ShaBoo

37

Nyck0las, le 27 nov 2007 à 14:58:59

Non il ne veut pas du dim çà me donne

"erreur de compilation : attendu : identificateur"

Répondre à Nyck0las

38

ShaBoo, le 27 nov 2007 à 15:03:40

Pfff ... naouak (chui fatigué moi)

Function Note(lg As Integer, Rng() As Variant) As Long

Répondre à ShaBoo

39

Nyck0las, le 27 nov 2007 à 15:29:40

Dsl mais c'est pas mieux on est reparti sur l'erreur "variable ou procédure attendue et non un module"

Répondre à Nyck0las

40

ShaBoo, le 27 nov 2007 à 15:46:22

Sur quelle ligne l'erreur ???

Répondre à ShaBoo

41

Nyck0las, le 27 nov 2007 à 15:57:59

Toujours pareil sur la première occurence de "note" est dans la procédure "notation"

Répondre à Nyck0las

42

ShaBoo, le 27 nov 2007 à 16:55:05

Peux tu mettre ton fichier en ligne, stp ... ??

Répondre à ShaBoo

43

Nyck0las, le 27 nov 2007 à 17:00:47

Si tu parles uniquement du code je l'ai posté juste avant
si tu parles du fichier excel, je veux bien mais je fais comment ??

Répondre à Nyck0las

44

ShaBoo, le 27 nov 2007 à 17:09:21

Tu dépose ton fichier Excel ici : http://www.cijoint.fr/

Tu copies le lien qui te seras fourni et tu le posteras dans la suite de ce msg ...

Répondre à ShaBoo

45

Nyck0las, le 27 nov 2007 à 17:14:51
Répondre à Nyck0las

46

ShaBoo, le 27 nov 2007 à 17:23:39
Répondre à ShaBoo

47

ShaBoo, le 27 nov 2007 à 17:30:24

Dans le module Note, tu rempleceras :

For i = 0 To n - 1
    X(i, 0) = ActiveSheet.Cells(lg, Rng(i).Value)
Next


par

For i = 1 To n - 1
    X(i, 0) = ActiveSheet.Cells(lg, Rng(i)).Value
Next

Répondre à ShaBoo

49

ShaBoo, le 27 nov 2007 à 17:47:09

Pff ... chui vraiment fatigué :

Dans le module Note, tu remplaceras :

For i = 0 To n - 1
    X(i, 0) = ActiveSheet.Cells(lg, Rng(i).Value)
Next


par

For i = 0 To n - 1
    X(i, 0) = ActiveSheet.Cells(lg, Rng(i)).Value
Next


et

Function fNote(lg As Integer, Rng() As Variant) As Long


par

Function fNote(lg As Integer, Rng() As Variant) As Double

Répondre à ShaBoo

50

Nyck0las, le 28 nov 2007 à 10:35:05

Ouaou !!!!!
merci bp shaboo j'ai l'impression que çà marche maintenant

Répondre à Nyck0las

48

le père, le 27 nov 2007 à 17:37:11
  • +1

"variable ou procédure attendue et non un module"
ça ne voudrait pas dire que tu aurais nommé un module Note dans ton application ? auquel cas, tu n'as pas le droit d'appeler une fonction Note aussi

Répondre à le père

51

Nyck0las, le 28 nov 2007 à 10:36:35

Ouais en fait j'avais appelé un module Note, d'où la confusion ..

Répondre à Nyck0las