ATOUTFOX
COMMUNAUTÉ FRANCOPHONE DES PROFESSIONNELS FOXPRO
Visual FoxPro : le développement durable

Convertir un nombre en lettres   



L'auteur

Francis Faure
France France
Membre Actif (personne physique)
# 0000000001
enregistré le 11/10/2004

http://www.wanagain.net
56 ans
Faure Francis
de la société Design Or Decline
Fiche personnelle


Note des membres
19,3/20
4 votes


Contributions > 01 - PRG : Programmation > Conversions

Convertir un nombre en lettres
# 0000000839
ajouté le 18/10/2012 21:51:23 et modifié le 19/10/2012
consulté 10071 fois
Niveau débutant

Version(s) Foxpro :
VFP 9.0


Le téléchargement des pièces jointes est limité aux membres
Veuillez vous identifier ou vous inscrire si vous n'avez pas encore de compte ...
Description

Un programme informatique devant retranscrire un nombre en lettres peut sembler une tâche simple…

Mais, les bizarreries de la langue française rendent très difficile la création d’un tel algorithme de conversion.

En liminaire :

La règle : Les nombres <100 qui sont composés de numéraux sont unis par un trait d’union (exemple « dix-huit »),

Sauf : les composés « et un » exemple « trente et un » (La réforme de l’académie française de 1990 autorise les traits d’union sur « et un » donc par exemple ce n’est plus une faute d’écrire « vingt-et-un » au lieu de « vingt et un »).

Concernant les unités :

Pas de problème… chaque chiffre a un correspondant littéral :

0 zéro,

1 un,

2 deux,

3 trois,

4 quatre,

5 cinq,

6 six,

7 sept,

8 huit,

9 neuf

Concernant les dizaines : cela se complique…

En effet :

a) dans la dizaine « 10 » il y des « exceptions »

b) les dizaines ont un correspondant littéral sauf pour 70 et 90 et aussi 80 qui est « capricieux »

c) Exceptions dans la composition au niveau des « 1 » de chaque dizaine


Alors, ne parlons plus de « d’exceptions » mais « particularités » à gérer…

Pour a)

Les « particularités » dans la dizaine « 10 » sont majeures donc pas de règle :

  • 11 onze (et non « dix-un » ni « dix et un »),
    12 douze,
    13 treize,
    14 quatorze,
    15 quinze,
    16 seize
  • Par contre les suivants sont « conformes » :
    17 dix-sept,
    18 dix-huit
    et 19 dix-neuf

Pour b)

10 dix,
20 vingt,
30 trente,
40 quarante,
50 cinquante,
60 soixante :
tout est ok

mais

70 s’écrit « soixante-dix » (60+10) et non « septante » (comme en Belgique ou Suisse équivalent « seventy » aux Anglo-Saxons à traduction égale)

90 s’écrit « quatre-vingt-dix » (80+10) et non « nonante » (comme en Belgique ou Suisse équivalent «ninety » aux Anglo-Saxons à traduction égale)

Reste 80 qui s’écrit chez nous « quatre-vingts », (4 x 20 !?) on pourrait le prendre comme une « littéral » mais il en est rien du tout car c’est bien 4 fois le vingt et il prend donc un « s » (s’il n’est pas suivi d’un nombre, tout comme « 100 » mais on y reviendra plus tard).
Donc « quatre-vingts » prend un « s » mais 84 « quatre-vingt-quatre » n’en prend pas. Il aurait pu s’appeler « octante » ou « huitante » (ou équivalent «eighty » Anglo-Saxons à traduction égale)

Pour c)

La règle : Les 1 de chaque dizaines s’écrivent avec « et un » sans trait d’union. Donc 21 « vingt et un »,
31 « trente et un »,
41 « quarante et un »,
51 « cinquante et un »,
61 « soixante et un »

Sauf : 11 « onze », 71 « soixante-et-onze », 91 « quatre-vingt-onze » et le vilain 81 « quatre-vingt-un » (par de « et un » et sans le ‘s’ à vingt… car il est suivi d’un nombre…)

La suite

Centaines (100)

a) Comme VINGT, le CENT il y a une règle : il prend la marque du pluriel s’il est multiplié par un nombre ET (exception à la règle) s’il n’est pas suivi d’un nombre. Exemple 200 = « deux cents », 201 = « deux cent un »

b) Pour 100 : On écrit CENT et non UN CENT


Milliers (1000)

a) Mille est invariable (n’a pas de « s ») et n’a pas de trait d’union.
Historiquement cela s’expliquerait ( ?) par le fait que « Mille » est le pluriel de « mil »…

b) pour 1000 : on écrit MILLE et non UN MILLE

MILLION et MILLIARD

a) Les mots million et milliard sont des noms, ils prennent donc la marque du pluriel. (1 milliard, 2 milliards)

b) pour 1 000 000 on écrit « UN MILLION »

c) c’est un nom et non un adjectif numéral : donc « huit millions deux euros » (contrairement à « deux cent deux euros »)

Les textes des nombres de cette classe ont été vérifiés dans le « petit Robert » et le « Larousse » (qui semblent d’accord pour une fois).

Pour information

Word sait convertir des chiffres en lettres !

Il fait des fautes et ne gère pas les décimales : mais c’est un bon début

Pour transformer un nombre en lettre dans word :

Tapez : CTRL F9

Dans les accolades tapez : =98 \*CardText

Concernant ma classe :

Avant de l’écrire j’ai cherché une solution existante (ne pas ré-inventer la roue),

J’ai trouvé une fonction publiée en novembre 2004 par « Aumeric » (Alias Eric Leisseler) Lien : http://www.atoutfox.org/articles.asp?ACTION=FCONSULTER&ID=0000000067

Je lui ai trouvée plusieurs bugs (sur les vingt et cent mais surtout après 1 million), j’ai essayé de les corriger, et comme elle ne gère pas la conformité des traits d’unions et surtout les décimales, et qu’elle est orientée pour des unités monétaires entières et elle ajoute des ‘s’ : J’ai décidé de réaliser une classe plutôt qu’une fonction, cela m’a pris un week-end complet pour me documenter sur les règles et exceptions et coder : Ce n’est pas un exercice simple !

J’imagine que Eric a du galérer aussi !

Ma classe commence par créer une collection des exceptions.
Puis travaille dessus récursivement par nombre de 3 chiffres.

Le but est de pouvoir gérer des valeurs numéraires, mais aussi des dates, et tous autres chiffres comme les températures, numéros de téléphone, pourcentages, etc…

La classe a comme propriétés :

nNombre = 0 && nombre a convertir

cUnitesEntiers = "euros" && Unité du nombre au pluriel

cUnitesDecimales = "centimes" && Unité des décimales au pluriel

nDecimales = 2 && nombre de décimales à mettre en lettres

cLiaison = "et" && libellé de la liaison

lLettresDecimaleSiZero = .F. && si la décimale vaut 0, afficher "et zéro centime" ?

La classe a comme méthodes:

Convert([surchage nNombre], ;
[surchage cUnitesEntiers], ;
[surchage cUnitesDecimales], ;
[surchage nDecimales], ;
[cLiaison])

Je pense enrichir et facilement rapidement la classe d’une fonction « speak() » lisant dans le haut parleur du PC le nombre sélectionné.

Cordialement

Francis

Code source :
CLEAR
SET PROCEDURE TO "nombresenlettres"

o=Createobject("Nombres_En_Lettre")


? o.convert() && doit retourner "zéro euro"


o.nNombre=91
? o.convert() && doit retourner "quatre-vingt-onze euros"

? o.convert(1) && doit retouner "un euro"
? o.convert(0.05) && doit retouner "cinq centimes"
? o.convert("80"&& doit retourner "quatre-vingtS euros"
? o.convert("81"&& doit retourner "quatre-vingt-un euros"
? o.convert("180"&& doit retourner "cent quatre-vingtS euros"
? o.convert("181"&& doit retourner "cent quatre-vingt-un euros"
? o.convert("280"&& doit retourner "deux cent quatre-vingtS euros"
? o.convert("1080"&& doit retourner "mille quatre-vingts euros"
? o.convert("80 000"&& doit retourner "quatre-vingts mille euros"
? o.convert("80 880"&& doit retourner "quatre-vingt mille huit cent quatre-vingtS euros"
? o.convert("200 000"&& doit retourner "deux centS mille euros"
? o.convert("200 200"&& doit retourner "deux cent mille deux centS euros"
? o.convert("200 200 200"&& doit retourner "deux cent millionS deux cent mille deux centS euros"

o.cUnitesEntiers = "€uros"
o.cUnitesDecimales  = "centimes"
o.nDecimales = 2
o.cLiaison = "et "
o.lLettresDecimaleSiZero = .T.
? o.convert(81) && doit retourner "quatre-vingt-un euroS et zéro centime"
? o.convert(20.81) && doit retourner "vingt €uros et quatre-vingt-un centimeS"

o.lLettresDecimaleSiZero = .F.

? o.convert(175.5, "€""centimes",2) && doit retourner "cent soixante-quinze € et cinquante centimes"

? o.convert(0.05, "dollars","cents",2) && doit retourner cinq cents"
? o.convert(1.01, "dollars","cents",2,"+"&& doit retourner un dollars + un cent

? o.convert(-13.5,"degrés","",1,""&& doit retourner "moins treize ° cinq"

o.nNombre = 37.2
o.cUnitesEntiers = "°C"
o.cUnitesDecimales  = ""
o.nDecimales = 1
o.cLiaison = ""
o.lLettresDecimaleSiZero = .F.
? o.Convert()

?
"Quelle est l'année de la révolution française ?"
"L'an "+ o.Convert(1700,"","",0,""), o.Convert(89,"","",0,"")
"le " + o.Convert(14,"juillet","",0,"")

?
"Quel jour sommes nous ?"
"Le "+ o.Convert(Day(Date()),"","",0,"") + " " + Cmonth(Date()) + " de l'année " + o.Convert(Year(Date()))

?
dt=Hour(Datetime())+Minute(Datetime())/100
"Avez-vous l'heure, svp ?" + Chr(13)+Chr(10)+;
  "Oui, il est "+ o.Convert(dt,"heures","minutes",2,"et")

o=Null


Commentaires
le 19/10/2012, Gregory Adam a écrit :
Excellent, Francis. J'aime le cadre grammatical

ps: Petite precision - octante ne se dit pas en Belgique

le 19/10/2012, Francis Faure a écrit :
Hello Gregory
en Belgique tu dit huitante ?

le 19/10/2012, Gregory Adam a écrit :
Simplement quatre-vingts

Il n'y a que 70 et 90 qui sont differents

ps: Le Francais a aussi connu trois-vingts, six-vingts et quinze-vingts
cf: http://fr.wikipedia.org/wiki/H%C3%B4pital_des_Quinze-Vingts

le 19/10/2012, Francis Faure a écrit :
Ok, je corrige
(pour Huitante ou Octante c'est en suisse ?)

le 19/10/2012, Gregory Adam a écrit :
(1) Je n'ai jamais entendu huitante/octante en Belgique

(2) La Suisse - oui, je crois
http://en.wiktionary.org/wiki/huitante
http://en.wiktionary.org/wiki/octante

http://fr.wiktionary.org/wiki/octante - ne plus utilise parait-il
http://fr.wiktionary.org/wiki/huitante - voir note - Ce mot n’est pas utilisé en Belgique, contrairement à ce que certaines sources indiquent par erreur.

Voir aussi http://fr.wiktionary.org/wiki/quatre-vingts



le 19/10/2012, Francis Faure a écrit :
Merci Gregory de ces précisions.
As tu testé la classe ?

le 19/10/2012, Gregory Adam a écrit :
Non, Francis, pas encore

Et la note etait pour l'etude et la recherche grammaticales

le 21/10/2012, eric leissler a écrit :
beau boulot Francis,
Bravo

le 28/10/2012, P@trick a écrit :
Juste une précision :
Vingt et cent ne se mettent pas au pluriel lorsque le nom de nombre est employé comme un ordinal : L'an cinq cent. Page quatre-vingt.
Un petit booléen optionnel en paramètre pour gérer ce cas ?

http://fr.wiktionary.org/wiki/quatre-vingt

Je dois avoir la fonction en FoxPro (DOS) si cela intéresse quelqu'un mais elle ne gère que les nombres cardinaux.

Patrick


www.atoutfox.org - Site de la Communauté Francophone des Professionnels FoxPro - v3.4.0 - © 2004-2024.
Cette page est générée par un composant COM+ développé en Visual FoxPro 9.0-SP2-HF3