[Excel 2003] VBA fonction personnalisée par procédure

tontonexcel

XLDnaute Occasionnel
Bonjour à tous,

J'ai créé une fonction qui soustrait 2 nombres, et qui calcule le ratio lorsque l'argument optionnel est spécifié (nb1 - nb2) / nb1, tout fonctionne très bien en mode fonction personnalisées

Je cherche maintenant à appeler la fonction via une procédure, je récupère la valeur1 et la valeur 2 dans des cellules et le ratio est toujours calculé (normal puisque la valeur 1 existe toujours)

J'ai trouvé une solution pour résoudre le problème mais elle me parait un peu étrange, pouvez-vous y jeter un coup d’œil (cf fichier joint)

Merci d'avance
 

Pièces jointes

  • tonton_excel_fonction.xls
    19.5 KB · Affichages: 34

Dranreb

XLDnaute Barbatruc
Re : [Excel 2003] VBA fonction personnalisée par procédure

Bonjour.
je ne vois rien de très étrange là dedans.
On pourrait toutefois se dispenser de déclarer des variables si ByVal était utilisé dans la fonction.
VB:
Function soustraction_ratio(ByVal nombre1 As Double, ByVal nombre2 As Double, Optional ByVal nombre_diviseur As Boolean = False) As Double
En effet ByRef est assumé par défaut, ce qui oblige à passer dans la pile l'adresse de ce qui ne saurait être que du type attendu. Tandis que ByVal oblige l'appelant à se décarcasser pour fabriquer la valeur du type attendu qu'il met dans la pile.
Autre chose IsMissing n'est utilisable qu'avec un paramètre Variant. De tout autre type, un Optional à une valeur par défaut correspondant généralement à la valeur obtenu s'il a tous ses bits à 0 (j'aurais pu omettre le = False).
On peut dès lors écrire :
VB:
Sub fonction_calcul()
' Calculer la différence valeur1 et valeur2, si valeur_diviseur ratio pour pourcentage
' Si différence format en euro, sinon en pourcentage
Range("A4").Value = soustraction_ratio(ActiveSheet.Range("A1").Value, ActiveSheet.Range("A2").Value, ActiveSheet.Range("A3").Value)
End Sub
 
Dernière édition:

tontonexcel

XLDnaute Occasionnel
Re : [Excel 2003] VBA fonction personnalisée par procédure

En fait ce qui me paraissait étrange c'était de répéter les 2 fonctions dans la procédure, par contre ce que je ne comprends pas (mais c'est vrai que je ne connais pas) c'est pour le ByVal et le ByRef, quand tu dis qu'on peut se dispenser de créer des variables tu parles pour la procédure ou la fonction (ou les deux) ?
En tout merci de t'être intéressé à mon cas !
 

JBARBE

XLDnaute Barbatruc
Re : [Excel 2003] VBA fonction personnalisée par procédure

Bonjour à tous,

Et si vous procédiez ainsi :

Code:
Sub fonction_calcul()
' Calculer la différence valeur1 et valeur2, si valeur_diviseur ratio pour pourcentage
' Si différence format en euro, sinon en pourcentage
Dim valeur1 As Double
Dim valeur2 As Double
'Dim diviseur As Boolean
Dim calcul As Double
Dim diviseur As String

valeur1 = Range("A1").Value
valeur2 = Range("A2").Value
diviseur = Range("A3").Value

    ' Si le diviseur n'existe pas
    If diviseur = "" Then
        ' calcul soustraction
        calcul = valeur1 - valeur2
    Else
        'calcul ratio
        calcul = (valeur1 - valeur2) / diviseur
    End If

Range("A4").Value = calcul

End Sub

Bonne journée
 
Dernière édition:

tontonexcel

XLDnaute Occasionnel
Re : [Excel 2003] VBA fonction personnalisée par procédure

Merci Jbarbe mais en fait je désirais comprendre l'utilisation des fonctions personnalisées, d'ailleurs j'ai trouvé certaines explications sur ByRef et ByVal et je suis en train de les tester
Merci
 

Dranreb

XLDnaute Barbatruc
Re : [Excel 2003] VBA fonction personnalisée par procédure

quand tu dis qu'on peut se dispenser de créer des variables tu parles pour la procédure ou la fonction (ou les deux) ?
La fonction n'utilise que les paramètres. Je parlais donc de la procédure, qui ne comporte plus qu'une instruction si on récupère tous les paramètres ByVal dans la fonction.
 

tontonexcel

XLDnaute Occasionnel
Re : [Excel 2003] VBA fonction personnalisée par procédure

Voila j'ai fait des tests (un peu long mais je voulais être sur...) j'ai donc corrigé en conséquence en gardant les paramètres de la fonction dans la procédure puisque d'après ce que j'ai compris je ne garde que la valeur calculée

Voila je pense que maintenant c'est bon
merci encore
Code:
' Fonction soustraction sur 2 valeurs, division optionnelle pour le ratio
Function soustraction_ratio(ByVal nombre1 As Double, ByVal nombre2 As Double, Optional ByVal nombre_diviseur As Variant) As Double

    ' Si le paramètre diviseur est manquant
    If IsMissing(nombre_diviseur) Then
        ' On calcule la soustraction nombre1 - nombre2
        soustraction_ratio = nombre1 - nombre2
    ' Sinon
    Else
        ' On calcule la soustraction avec le diviseur pour le ratio (nombre1 - nombre2) / nombre1
        soustraction_ratio = (nombre1 - nombre2) / nombre1
    End If
End Function

Sub fonction_calcul()
' Calculer la différence valeur1 et valeur2, si valeur_diviseur ratio pour pourcentage
Dim calcul As Double

nombre1 = Range("A1").Value
nombre2 = Range("A2").Value
diviseur = Range("A3").Value

    ' Si le diviseur n'existe pas
    If diviseur = False Then
        ' calcul soustraction
        calcul = soustraction_ratio(nombre1, nombre2)
    Else
        ' calcul ratio
        calcul = soustraction_ratio(nombre1, nombre2, nombre1)
    End If

Range("A4").Value = calcul

End Sub

:confused: EDIT : j'ai testé avec
Code:
Optional ByVal nombre_diviseur As Boolean
et çà ne fonctionne pas (résultat toujours en faux) je pense que réellement Optional ne fonctionne qu'avec Variant
 
Dernière édition:

eriiic

XLDnaute Barbatruc
Re : [Excel 2003] VBA fonction personnalisée par procédure

Bonjour à tous,

en fait je désirais comprendre l'utilisation des fonctions personnalisées
Tu as une autre possibilité pour les paramètres optionnels.
C'est de déclarer leur valeur par défaut en cas d'absence.
Là, tu peux typer le paramètre optionnel. Ex :
..., Optional param3 As Boolean = False)

Bien sûr dans ce cas IsMissing est toujours faux, tester la valeur du paramètre.

Sur ta fonction ça donnerait :
Code:
Function soustraction_ratio(ByVal nombre1 As Double, ByVal nombre2 As Double, Optional ByVal nombre_diviseur As Boolean = False) As Double

' Si le paramètre diviseur est manquant ou False
    If Not nombre_diviseur Then
        ' On calcule la soustraction nombre1 - nombre2
        soustraction_ratio = nombre1 - nombre2
        ' Sinon
    Else
        ' On calcule la soustraction avec le diviseur pour le ratio (nombre1 - nombre2) / nombre1
        soustraction_ratio = (nombre1 - nombre2) / nombre1
    End If
End Function
 

tontonexcel

XLDnaute Occasionnel
Re : [Excel 2003] VBA fonction personnalisée par procédure

Hello tous et toutes,

Je continue sur le même post car j'améliore le programme avec le gestionnaire d'erreur

Pour "attirer" l'attention des utilisateurs une valeur d'erreur est renvoyée en cellule (type #DIV/0 ! ou #VALEUR!) dans le cas de mauvaises données

J'ai trouvé la fonction NA() qui renvoie #NA existe t'il une fonction qui renvoie les autres erreurs ? (Sinon j'ai écrit directement la valeur en mode texte mais est-ce qu'il s'agit bien d'une valeur d'erreur ? :confused:)

Merci
 

tontonexcel

XLDnaute Occasionnel
Re : [Excel 2003] VBA fonction personnalisée par procédure

Désolé eriiiic

J'étais passé à autre chose et je suis passé par dessus ton post

Voili voilou
Milles excuses

En ce qui concerne ta soluce je préfère pour mes tests perso utiliser IsMissing
Maintenant c'est intéressant car tu peux "forcer" la valeur de la variable

Autre chose si tu as un élément de réponse pour le post 10, car j'ai testé en implantant direct en cellule #DIV/0! c'est bien une valeur d'erreur mais #VALEUR! est reconnu comme texte

Et encore merci !!!

EDIT : Test sur erreur : un nombre / 0 est géré par l'erreur 11 (division par zéro) logique, mais 0 / 0 est géré par l'erreur 6 (dépassement de capacité) :confused:
Bizarre non ?
 
Dernière édition:

eriiic

XLDnaute Barbatruc
Re : [Excel 2003] VBA fonction personnalisée par procédure

Re,
Maintenant c'est intéressant car tu peux "forcer" la valeur de la variable
et de typer un paramètre optionnel. Avec IsMissing il est obligatoirement variant.

existe t'il une fonction qui renvoie les autres erreurs ?
Tu peux renvoyer la valeur d'erreur que tu veux avec CvErr(num_erreur)
Par contre ta fonction doit retourner absolument un variant.

Code Excel Constante VBA Signification..................................................................................................
#DIV/0! xlerrDiv0 Division par zéro
#N/A xlerrNA Paramètre manquant
#NOM! xlErrName
Nom inconnu
#NUL! xlErrNull
Intersection de plages non valide
#NOMBRE! xlErrNum Nombre attendu / dépassement de capacité / argument hors domaine
#REF! xlErrRef Référence de plage non valide
#VALEUR! xlErrValue Argument non approprié

eric
 
Dernière édition:

Statistiques des forums

Discussions
312 107
Messages
2 085 355
Membres
102 874
dernier inscrit
Petro2611