[VBA EXCEL] besoin d'aide pour une macro
ShaBoo Messages postés 406 Statut Membre -
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
- Variable ou procédure attendue et non un module
- Telecharger macro convertir chiffre en lettre excel - Télécharger - Tableur
- Déplacer une colonne excel - Guide
- Trier une colonne excel - Guide
- Liste déroulante excel - Guide
- Imprimer excel sur une page - Guide
26 réponses
- 1
- 2
La problématique porte sur une fonction VBA Note qui prend une plage de cellules en argument et construit un vecteur colonne et une matrice avant d’effectuer quelques calculs. Des corrections essentielles consistent à remplacer les accès et boucles avec des index 0-based par des références directes, et à utiliser des tableaux dynamiques avec Redim pour les dimensions variables. La meilleure réponse recommande d’alimenter X via ActiveSheet.Cells(lg, Rng(i)) et de passer Rng() en Variant, puis d’adapter la signature en Function fNote(lg As Integer, Rng() As Variant) As Double. En complément, il faut noter que la gestion des dimensions dynamiques et des valeurs non numériques nécessite des vérifications et des conversions appropriées pour éviter des erreurs d’exécution et des résultats incorrects.
ç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
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 ?...
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.
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
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)
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre questionj'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
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 ??
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
enfin quelque chose qui marche !!!!!!!!!!!
il m'affiche bien 1 comme résultat donc tu as raison un ensemble de plage = 1 plage
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")
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 ...
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
mais comment je peux faire si je veux un nombre n de range, avec n non défini ?????????
that is the question ...
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
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.
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
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 ....
- 1
- 2