Activer fonction Excel

Estelle_BNP Messages postés 25 Date d'inscription jeudi 14 décembre 2006 Statut Membre Dernière intervention 10 mai 2008 - 5 oct. 2007 à 19:44
Estelle_BNP Messages postés 25 Date d'inscription jeudi 14 décembre 2006 Statut Membre Dernière intervention 10 mai 2008 - 10 oct. 2007 à 15:55
Bonsoir à tous,

Je viens de créer une fonction VBA très simple qui permet de réaliser une interpolation linéaire. La voici :

Public Function Interpoline(X() as variant, Y() as variant, Z as variant)

Dim t as Interger
t=1
While X(t)<Z and t<Ubound(X)
t=t+1
Wend

Interpoline = Y(t-1)+(Z-X(t-1))/(X(t)-X(t-1))*(Y(t)-Y(t-1))

End Function

J'aimerai maintenant utiliser cette fonction à partir d'Excel. J'ai donc tapé dans une page Interpoline(Dates, Taux, C8) où Dates est une plage de dates triées par ordre croissant, Taux est une plage de chiffres et C8 est une date.
Dans ma cellule Excel où j'ai tapée cette fonction je vois #VALEUR.

Pensant que j'avais mal écrit la fonction j'ai tapé ensuite au début de la fonction Interpoline=1 pour voir si elle était activée correctement (et j'ai mis le reste du code en commentaire) mais je vois toujours #VALEUR.

Pouvez-vous me dire comment utiliser ma fonction Interpoline directement dans Excel ?

Merci pour vos réponses.

7 réponses

cs_MPi Messages postés 3877 Date d'inscription mardi 19 mars 2002 Statut Membre Dernière intervention 17 août 2018 23
6 oct. 2007 à 00:32
Premièrement, une Function devrait retourner quelque chose.
Ta formule est peut-être simple pour toi, mais je n'ai aucune idée de ce qu'elle devrait retourner

Alors tu devrais l'écrire comme ceci
Public Function Interpoline(X() as variant, Y() as variant, Z as variant) As TypeRetour
en changeant TypeRetour par ce qui devrait être retourné. Par défaut le retour est Variant, donc ça ne devrait pas causer de problème ici ...

Deuxièmement, cette formule doit être déclarée dans un module standard (.bas) et non pas dans le code d'une feuille ou d'un UserForm. C'est probablement ici qu'il y a problème... (?)

En espérant que ça puisse aider ...

MPi²
0
us_30 Messages postés 2065 Date d'inscription lundi 11 avril 2005 Statut Membre Dernière intervention 14 mars 2016 10
6 oct. 2007 à 12:21
Bonjour,

Non une fonction n'a pas obligatoirement bessoin de déclarer le type de donnée en retour. Car sans précision le type sera en Variant par défaut. Mais il reste vrai, qu'il est préférable de déclarer son type... C'est une nuance.

Pour illustrer, voici un exemple plus que basique :

Function essai()
essai = 5
End Function


Sub test()
Debug.Print essai
End Sub

qui fonctionne parfaitement...

Ensuite, encore un précision sur l'emplacement. La fonction si elle est déclarée dans "feuil1", sera correctement utilisable qu'à partir d'un appel effectuée à partir de ce même emplacement (donc en interne avec une sub en VBA). Malgré, les apparences les appels d'une fonction à partir d'une cellule EXCEL, ne fait pas directement référence à "feuil1" du VBA. Seul les événements passent directement. (Je ne sais pas si je suis bien clair... c'est pourtant juste).

En définitive, pour appeler une fonction reconnue à partir des cellules, il faut qu'elle soit dans un module (donc accessible à tous et en Public (par défaut)), comme l'indique MPi².

=

Le code d'erreur  #VALEUR, ne signifie pas que la fonction n'est pas reconnue ! mais justement l'inverse. LA fonction est bien reconnue, mais ces paramètres où son calcul (plus généralement) pose problème.

Si la fonction n'était pas reconnue, le code d'erreur serait #NOM.

=

LE problème ici, semble être le passage des paramètres à la fonction. Pour passer une plage de cellule, on utilise la type RANGE. VARIANT fonctionnera mais peut poser problème si on traite n'importe comment les données par la suite.

PAR contre, les parenthèse ne seront pas valide pour passer une plage. C'est ICI l'erreur !

Donc utiliser :

Public Function Interpoline(X as variant, Y as variant, Z as variant)

et plus précisément : 

Function Interpoline(X as range, Y as range, Z as range)

(Public est par défaut, donc on peut aussi le retirer)

On peut vérifier que cela fonctionne avec cet exemple basique :

Function essai(X As Range)
essai = X(2)
End Function

et en prenant une plage d'au moins 2 valeurs... et renvoi toujours la valeur de la 2ième selection X(2)  (y'a pas de test de validité !)

=

Ensuite, le code proposée est obscure et ne fonctionne donc pas... mais les problèmes de syntaxe sont déjà résolus...

Amicalement,
Us.
0
cs_lermite222 Messages postés 492 Date d'inscription jeudi 5 avril 2007 Statut Membre Dernière intervention 2 juillet 2012 4
7 oct. 2007 à 11:37
Citation
Dans ma cellule Excel où j'ai tapée cette fonction je vois #VALEUR.

Les fonctions ne peuvent pas êtres entrées dans une cellule, elle doivent l'être soit dans un module de feuille soit dans un module commun.
@+
0
us_30 Messages postés 2065 Date d'inscription lundi 11 avril 2005 Statut Membre Dernière intervention 14 mars 2016 10
7 oct. 2007 à 15:32
Euh... bonjour, lermite22... Perso, j'aime bien la justesse de la citation...

Amicalement,
Us.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Estelle_BNP Messages postés 25 Date d'inscription jeudi 14 décembre 2006 Statut Membre Dernière intervention 10 mai 2008
8 oct. 2007 à 16:33
Merci pour votre aide. Grâce à vos remarques et en tatonnant un peu, j'ai réussi à faire marcher cette fonction. Voici le code final :

Public Function InterpoLine(x As Range, Y As Range, Z As Date) As Double
Dim i As Integer
Dim TabDate() As Variant
Dim TabTx() As Variant
Dim xk As Variant


TabDate() = x
TabTx() = Y


i = 1
While TabDate(i, 1) < Z And i < UBound(TabDate, 1)
    i = i + 1
Wend


InterpoLine = TabTx(i - 1, 1) + (Z - TabDate(i - 1, 1)) / (TabDate(i, 1) - TabDate(i - 1, 1)) * (TabTx(i, 1) - TabTx(i - 1, 1))


 


End Function

Encore merci d'avoir pris de votre temps pour m'aider.

Cordialement,

Estelle
0
us_30 Messages postés 2065 Date d'inscription lundi 11 avril 2005 Statut Membre Dernière intervention 14 mars 2016 10
8 oct. 2007 à 22:51
Bonsoir,

Encore une précision. Tu utilises les plages en les tranférant dans un tableau déclaré par DIM. Ok, cela marche, mais comme tu ne modifie pas ces données, tu peux plus simplement garder les données RANGE.

En clair, ton code pourrait se simplifier avec :

=

Function InterpoLine(X As Range, Y As Range, Z As Date) As Double
Dim i As Integer
i = 1
While X(i, 1) < Z And i < UBound(X, 1)
    i = i + 1
Wend
InterpoLine = Y(i - 1, 1) + (Z - X(i - 1, 1)) / (X(i, 1) - X(i - 1, 1)) * (Y(i, 1) - Y(i - 1, 1))
End Function

=

Rq : la variable "Dim xk As Variant" n'est jamais utilisée...

Amicalement,
Us.
0
Estelle_BNP Messages postés 25 Date d'inscription jeudi 14 décembre 2006 Statut Membre Dernière intervention 10 mai 2008
10 oct. 2007 à 15:55
Merci pour le conseil
0
Rejoignez-nous