Rendre monnaie

Résolu
chelguera Messages postés 28 Date d'inscription mardi 15 janvier 2002 Statut Membre Dernière intervention 13 avril 2024 - 12 avril 2024 à 20:18
vb95 Messages postés 3473 Date d'inscription samedi 11 janvier 2014 Statut Contributeur Dernière intervention 30 avril 2024 - 13 avril 2024 à 18:13

Bonjour, je tourne en rond et c'est si bête pourtant....

disons que je dois rendre 1 montant X avec un choix de pieces déterminées

exemple X = 3,80€ le plus simple serait 1*2

reste 1,8 puis 1 donc reste 0.80 etc 

ce qui ferait 2€ + 1€,+0.50€ +3fois 0.10

cela sans passer par la methode "gloutonne de 38 piéces de 0.10...

deux jours que je tourne en rond alors que c'est une simple boucle ...

si vous avez un exemple je suis preneur 

merci à vous 

7 réponses

Whismeril Messages postés 19033 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 30 avril 2024 656
13 avril 2024 à 11:17

En VBA

Option Explicit

Sub test()

Dim aRendre As Integer ' valeur à rendre, convertie en centimes pour se simplifier la vie par la suite
Dim existants() As Variant ' pièces existantes, on pourrait eventuellement ajouter des billets
Dim monnaie() As Integer ' détail des pièces à rendre, converties en centimes pour se simplifier la vie par la suite
Dim index As Integer

Dim resultat As String ' uniquement pour l'affichage


aRendre = 575
existants = Array(200, 100, 50, 20, 10, 5)
ReDim monnaie(UBound(existants) - LBound(existants) + 1) ' le tableau des pièces à rendre à la même taille que le tableau des existants

index = LBound(existants) ' 0 ou 1 en fonction de l'option Bas choisie

' Calcul des pièces à rendre
Do While index <= UBound(existants)
    If existants(index) <= aRendre Then
        monnaie(index) = aRendre \ existants(index) ' utilisation de la division euclidienne, fonctionne avec des entiers (d'où les centimes)
        aRendre = aRendre Mod existants(index)
    End If
    
    index = index + 1 ' on passe à la pièce suivante
Loop

' affichage des pièces à rendre
resultat = ""
For index = LBound(existants) To UBound(existants)
    resultat = resultat & "Nbr de pièces de " & existants(index) / 100 & " : " & monnaie(index) & vbCrLf
Next

MsgBox resultat


End Sub

Comme c'était proche de VB6, avec un peu de chance ça marche direct


1
vb95 Messages postés 3473 Date d'inscription samedi 11 janvier 2014 Statut Contributeur Dernière intervention 30 avril 2024 169
13 avril 2024 à 04:16

Bonjour

Je n'ai pas le code en VB 6 mais le principe est simple . Soit un montant X à rendre ( exemple : 3€80  comme tu dis ) .

Tu choisis la pièce la plus forte en valeur mais inférieure au montant restant à rendre . Ici c'est la pièce de  2 € . Tu fais la division entière de 3,80 par 2 . Le résultat est 1 donc une pièce de 2€ . Tu en déduis le reste à rendre qui est donc 1€80 . 

Tu choisis la pièce la plus forte en valeur mais inférieure au montant restant à rendre . Ici c'est la pièce de  1 € . Tu fais la division entière de 1,80 par 1 . Le résultat est 1 donc une pièce de 1€ . Tu en déduis le reste à rendre qui est donc 0€80 . 

Tu choisis la pièce la plus forte en valeur mais inférieure au montant restant à rendre . Ici c'est la pièce de  0€50 € . Tu fais la division entière de 0,80 par 0,50 . Le résultat est 1 donc une pièce de 0€50 . Tu en déduis le reste à rendre qui est donc 0€30 . 

Tu choisis la pièce la plus forte en valeur mais inférieure au montant restant à rendre . etc...........

A chaque fois il faut calculer le nombre de pièces à rendre en tenant compte du fait  que la valeur de la pièce doit être la valeur la plus proche du reste à rendre tout en lui étant inférieure .

Reste        NB pièces à rendre

3€80         1 x 2€  

1€80         1 x 1€

0€80         1 x 0€50

0€30         1 x 0€20

0€10         1 x 0€10 


0
chelguera Messages postés 28 Date d'inscription mardi 15 janvier 2002 Statut Membre Dernière intervention 13 avril 2024
13 avril 2024 à 09:17

merci, mais j'ai résolu cela cette nuit avec une boucle do

Monnaie = FormatNumber(Main.T_Monnaie, 2)
  Do While Monnaie > 5                         'Pieces de 5€
    Main.T5.Text = Main.T5.Text + 1
    Monnaie = FormatNumber(Monnaie - 5, 2)
  Loop
  Do While Monnaie > 1                         'Pieces de 1€
    Main.T1.Text = Main.T1.Text + 1
    Monnaie = FormatNumber(Monnaie - 1, 2)
  Loop
  Do While Monnaie > 0.5                       'Pieces de 0,50€
    Main.T05.Text = Main.T05.Text + 1
    Monnaie = Monnaie - 0.5
  Loop
  Do While FormatNumber(Monnaie, 2) > 0         'Pieces de 0,10€
    Main.T01.Text = Main.T01.Text + 1
    Monnaie = Monnaie - CSng(0.1)
  Loop
0
Whismeril Messages postés 19033 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 30 avril 2024 656
13 avril 2024 à 10:10

Bonjour

si je peux me permettre y'a rien de bon dans ce code.

  • Main.T1.Text contient une string à laquelle tu ajoutes 1, un integer. Tu laisses donc à VB de faire le choix de quoi faire
    1. Convertir le texte en nombre et ajouter 1 à ce nombre
    2. Concantener le texte et "1"

         Figure-toi qu'en laissant VB choisir, parfois, il ne fait pas le choix que tu veux. Et comme t'as l'habitude de "ça marche par magie" quand ça bogue, tu ne comprends pas pourquoi.

Du coup, te forcer à utiliser une variable de type numérique (double par exemple), convertir le texte au début de ta procédure, faire tous tes calculs avec des nombres et à la fin seulement t'évitera des déconvenues, en VB. Mais aussi si un jour tu passes dans un langage moderne (rappel, fin de commercialisation de VB6 1996, abandon total 2005) au typage dynamique comme Python ou Javascript de comprendre où ça plante quand justement le typage dynamique se plante.

  • À décomposer pièce par pièce, il n'y a pas besoin de boucle, une simple division suffit comme te l'a indiqué VB95 (que je salue au passage), là
    1. tu écris plus de code que nécessaire
    2. tu utilises des ressources systèmes inutilement
    3. tu perds en efficacité à l'exécution
  • Tu recopies 4 fois le même code, à supposer qu'il soit faux, tu dois le corriger 4 fois. En utilisant, un tableau de pièces et cette fois en bouclant dessus
    1. tu optimiserais l'écriture et la maintenance du code
    2. tu n'utiliserais pas trop de ressources système (une seule boucle à initier et pas 4)

0
vb95 Messages postés 3473 Date d'inscription samedi 11 janvier 2014 Statut Contributeur Dernière intervention 30 avril 2024 169
13 avril 2024 à 18:13

Salut à toi aussi Whis !

0

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

Posez votre question
chelguera Messages postés 28 Date d'inscription mardi 15 janvier 2002 Statut Membre Dernière intervention 13 avril 2024
13 avril 2024 à 10:20

merci whismeril, tu as raison ce code ne vaut rien et je vais l'adapter à la solution de vb95.

Ya juste que j'ai arrêter de programmer en 2003 et donc un peu rouillé ajoute à cela 2 avc loll et mes neuronnes partent en couilles.

Bonne journée à tous et toutes

0
chelguera Messages postés 28 Date d'inscription mardi 15 janvier 2002 Statut Membre Dernière intervention 13 avril 2024
13 avril 2024 à 11:25

c'est ok du 1er coup !

merci

0
vb95 Messages postés 3473 Date d'inscription samedi 11 janvier 2014 Statut Contributeur Dernière intervention 30 avril 2024 169
13 avril 2024 à 14:30

Tant mieux


0
Rejoignez-nous