Fonction sur Excel

Résolu/Fermé
hoquei44 Messages postés 16053 Date d'inscription dimanche 19 janvier 2014 Statut Membre Dernière intervention 13 mai 2024 - Modifié le 5 juil. 2022 à 22:40
hoquei44 Messages postés 16053 Date d'inscription dimanche 19 janvier 2014 Statut Membre Dernière intervention 13 mai 2024 - 6 juil. 2022 à 23:01
Bonjour à vous,

J'essaye de créer une fonction pour procéder au calcul à partir d'une grille tarifaire :
Les 10 premiers articles sont à 30€
Les 10 articles suivants (20-10) sont à 25€, auxquels on ajoute les 300€ (10 * 30€) des articles précédents.
Etc...

Je rencontre un problème avec la fonction suivante car elle me retourne #VALEUR! dans ma cellule. Mais je n'arrive pas à identifier le soucis.

Function Tarif_Paye(nombre)

'Déclaration et initialisation de valeurs
Dim NbPaye, Paye_Marginale As Integer
NbPaye = nombre
Tarif_Paye = 0

'Grille tarifaire
Table_Paye = Array(0, 10, 20, 30, 40, 50, 60, 99)
Table_Tarif = Array(0, 30, 25, 20, 15, 10, 5, 0)

'Calcul rapide des montants intermédiaires
Table_Antecedant = Array(0, 0, 0, 0, 0, 0, 0, 0)
For i = 1 To UBound(Table_Paye)
    Table_Antecedant(i) = Table_Antecedant(i - 1) + Table_Paye(i) * Table_Tarif(i)
Next


For j = 1 To UBound(Table_Paye)     'Pour chaque plage tarifaire

    Debut = Table_Paye(j - 1) + 1   'Montant bas de la plage
    Fin = Table_Paye(j)             'Montant haut de la page

    Select Case NbPaye              'Vérifie la condition suivante
        Case Debut  To Fin          'Si le montant recherché est compris dans la plage
        Paye_Marginale = (NbPaye - Table_Paye(j - 1))   'Nombre de paye comprise dans la plage
        Tarif_Paye = Paye_Marginale * Table_Tarif(j) + Table_Antecedant(j - 1)  'calcul du tarif

    End Select
Next

Tarif_Paye = Round(Tarif_Paye, 2)

End Function


Lors que je modifie la "function" en un Sub, j'obtiens bien le résultat souhaité (avec un léger remaniement du code pour le mettre en boucle sur ma liste dans mon classeur. Cependant lorsque je souhaite la transformer en fonction, je bloque.

Pour les fonctions très simples, j'arrive bien à un résultat. Il doit y avoir une poutre que je n'arrive pas à voir.
  Function carre(nombre)
     carre = nombre ^ 2 
  End Function


Je vous remercie d'avance pour votre aide,

Bonne soirée
A voir également:

2 réponses

via55 Messages postés 14408 Date d'inscription mercredi 16 janvier 2013 Statut Membre Dernière intervention 5 mai 2024 2 705
6 juil. 2022 à 00:21
Bonjour à toi

Pourquoi faire simple quand on peut faire compliqué !
Si j'ai bien compris ta problématique, personnellement je bâtirai ma fonction ainsi :
Function tarif_paye(nombre)
Select Case nombre
Case Is <= 10
pu = 30: plus = 0: moins = 0
Case Is <= 20
pu = 25: plus = 300: moins = 10
Case Is <= 30
pu = 20: plus = 550: moins = 20
Case Is <= 40
pu = 15: plus = 750: moins = 30
Case Is <= 50
pu = 10: plus = 900: moins = 40
Case Is > 50
pu = 5: plus = 1000: moins = 50
End Select
tarif_paye = (nombre - moins) * pu + plus
End Function

Cdlmnt
VIa
1
hoquei44 Messages postés 16053 Date d'inscription dimanche 19 janvier 2014 Statut Membre Dernière intervention 13 mai 2024
6 juil. 2022 à 18:30
Bonjour et merci de votre retour,

L'origine du "compliqué", c'est parce qu'à l'origine je souhaite aller plus loin dans ma fonction pour lui permettre d'être réutilisée plus facilement dans d'autre situation :
1/ La variabilisation de "plus" avait pour objectif de ne pas avoir à le recalculer en cas de changement des seuils ou des prix unitaires.
2/ La variabilisation des CASE avait pour objectif de pouvoir ajouter de nouveaux seuils sans avoir à toucher au code, mis à part le tableau.

Comme je ne suis pas parvenu à mettre une boucle FOR/NEXT à l'intérrieur d'un SELECT CASE, j'ai fait l'inverse en mettant un SELECT CASE à l'intérieur d'un FOR/NEXT. Même si je pense qu'un WHILE aurait été plus performant, mais dans l'absolue pour l'instant je cherche simplement à ce que cela fonctionne. Puis je corrige petit à petit à tâtons.

Par contre, je n'ai pas compris d'où venait mon erreur... J’aimerai bien comprendre si possible.

Question bonus : comment peut-on initialiser un tableau d'une dimension i avec uniquement des valeurs à 0 ?
C'est pour éviter le
Array(0, 0, 0, 0, 0, 0, 0, 0)
et d'avoir à compter le nombre de 0.

Merci et bonne journée
0
via55 Messages postés 14408 Date d'inscription mercredi 16 janvier 2013 Statut Membre Dernière intervention 5 mai 2024 2 705
6 juil. 2022 à 21:00
Bonsoir

1) Ta fonction personnalisée fonctionne très bien chez mois sans erreur de VALEUR

2) Par contre elle renvoie un résultat erroné à partir de 21 articles !

https://www.cjoint.com/c/LGgs6a2Oe7u

3) J'ai établi de mon côté sur ce fichier une fonction personnalisée tarif_paye2 qui a l'air de fonctionner et qui ne comporte pas le Array avec les 0

Cdlmnt
Via


1
hoquei44 Messages postés 16053 Date d'inscription dimanche 19 janvier 2014 Statut Membre Dernière intervention 13 mai 2024
6 juil. 2022 à 22:44
Bonsoir,

J'ai copier-coller le code que j'avais posté hier dans un nouveau tableur, et effectivement il n'y a pas d'erreur de valeur. Je ne vais pas chercher à comprendre.
Par contre ma curiosité va me pousser à comprendre le dysfonctionnement à partir de 21.

Merci pour votre aide.
0
hoquei44 Messages postés 16053 Date d'inscription dimanche 19 janvier 2014 Statut Membre Dernière intervention 13 mai 2024 > hoquei44 Messages postés 16053 Date d'inscription dimanche 19 janvier 2014 Statut Membre Dernière intervention 13 mai 2024
6 juil. 2022 à 23:01
Trouvé pour le problème à partir de 21 :
Il faut remplacer la ligne
    Table_Antecedant(i) = Table_Antecedant(i - 1) + Table_Paye(i) * Table_Tarif(i)

Par la ligne
Table_Antecedant(i) = Table_Antecedant(i - 1) + (Table_Paye(i) - Table_Paye(i - 1)) * Table_Tarif(i)


Et mon problème de valeur provenant du fait que j'avais une ligne de plus dans mon algo mais que j'avais supprimé en le mettant sur le site. Il s'agissait d'une ligne du style :
cells(i, 1) = Table_Antecedant(i)

Donc, j'en conclu qu'une fonction ne peut pas écrire de valeur dans une autre cellule.

CB
0