Conversion de nombre en lettres (sql)

Soyez le premier à donner votre avis sur cette source.

Vue 44 148 fois - Téléchargée 1 354 fois

Description

Je me suis inspiré du code c# trouvé ici (http://files.codes-sources.com/fichier.aspx?id=21491&f=convertisseur.cs) pour écrire cette fonction SQL.
Elle convertit les nombres de 0 à 999,999,999 en lettres, et j'ai corrigé un ou deux points mineurs.

Source / Exemple :


CREATE FUNCTION NombreEnLettres
(
	@nombre int
)
RETURNS varchar(200)
AS
BEGIN
	DECLARE @lettres varchar(200)

	DECLARE @diviseur int

	DECLARE @centaine int
	DECLARE @dizaine int
	DECLARE @unite int
	DECLARE @reste int
	DECLARE @courant int
	DECLARE @dix bit
	DECLARE @et bit

	DECLARE @ajout varchar(200)

	SET @lettres = ''
	SET @diviseur = 1000000
	SET @dix = 0
	SET @reste = @nombre

	IF @nombre > 999999999
		RETURN 'Un milliard ou plus'

	WHILE @diviseur >= 1
	BEGIN
		SELECT @courant = @reste / @diviseur
		IF @courant <> 0
		BEGIN
			SELECT @centaine = @courant / 100
			SELECT @dizaine = (@courant - @centaine * 100) / 10
			SELECT @unite = @courant - (@centaine * 100) - (@dizaine * 10)
			SELECT @ajout = ''

			SELECT @ajout = @ajout +
				CASE @centaine
				WHEN 1 THEN 'cent '
				WHEN 2 THEN 
					CASE WHEN @dizaine = 0 AND @unite = 0 THEN 'deux cents ' ELSE 'deux cent ' END
				WHEN 3 THEN 
					CASE WHEN @dizaine = 0 AND @unite = 0 THEN 'trois cents ' ELSE 'trois cent ' END
				WHEN 4 THEN 
					CASE WHEN @dizaine = 0 AND @unite = 0 THEN 'quatre cents ' ELSE 'quatre cent ' END
				WHEN 5 THEN 
					CASE WHEN @dizaine = 0 AND @unite = 0 THEN 'cinq cents ' ELSE 'cinq cent ' END
				WHEN 6 THEN 
					CASE WHEN @dizaine = 0 AND @unite = 0 THEN 'six cents ' ELSE 'six cent ' END
				WHEN 7 THEN 
					CASE WHEN @dizaine = 0 AND @unite = 0 THEN 'sept cents ' ELSE 'sept cent ' END
				WHEN 8 THEN 
					CASE WHEN @dizaine = 0 AND @unite = 0 THEN 'huit cents ' ELSE 'huit cent ' END
				WHEN 9 THEN 
					CASE WHEN @dizaine = 0 AND @unite = 0 THEN 'neuf cents ' ELSE 'neuf cent ' END
				ELSE ''
				END

			SELECT @ajout = @ajout +
				CASE @dizaine
				WHEN 2 THEN 'vingt '
				WHEN 3 THEN 'trente '
				WHEN 4 THEN 'quarante '
				WHEN 5 THEN 'cinquante '
				WHEN 6 THEN 'soixante '
				WHEN 7 THEN 'soixante '
				WHEN 8 THEN 'quatre-vingt '
				WHEN 9 THEN 'quatre-vingt '
				ELSE ''
				END
			
			SELECT @dix = CASE @dizaine
				WHEN 1 THEN 1
				WHEN 7 THEN 1
				WHEN 9 THEN 1
				ELSE 0
				END

			SELECT @et = CASE @dizaine
				WHEN 0 THEN 0
				WHEN 1 THEN 0
				WHEN 2 THEN 1
				WHEN 3 THEN 1
				WHEN 4 THEN 1
				WHEN 5 THEN 1
				WHEN 6 THEN 1
				WHEN 7 THEN 1
				WHEN 8 THEN 0
				WHEN 9 THEN 0
				ELSE 0
				END

			SELECT @ajout = @ajout +
				CASE @unite
				WHEN 0 THEN
					CASE @dix WHEN 1 THEN 'dix ' ELSE '' END
				WHEN 1 THEN
					CASE @et WHEN 1 THEN 'et ' ELSE '' END +
					CASE @dix WHEN 1 THEN 'onze ' ELSE 'un ' END
				WHEN 2 THEN
					CASE @dix WHEN 1 THEN 'douze ' ELSE 'deux ' END
				WHEN 3 THEN
					CASE @dix WHEN 1 THEN 'treize ' ELSE 'trois ' END
				WHEN 4 THEN
					CASE @dix WHEN 1 THEN 'quatorze ' ELSE 'quatre ' END
				WHEN 5 THEN
					CASE @dix WHEN 1 THEN 'quinze ' ELSE 'cinq ' END
				WHEN 6 THEN
					CASE @dix WHEN 1 THEN 'seize ' ELSE 'six ' END
				WHEN 7 THEN
					CASE @dix WHEN 1 THEN 'dix-sept ' ELSE 'sept ' END
				WHEN 8 THEN
					CASE @dix WHEN 1 THEN 'dix-huit ' ELSE 'huit ' END
				WHEN 9 THEN
					CASE @dix WHEN 1 THEN 'dix-neuf ' ELSE 'neuf ' END
				ELSE ''
				END

			SELECT @lettres = @lettres +	
				CASE @diviseur
				WHEN 1000000 THEN
					CASE
					WHEN @courant = 1 THEN 'un million ' 
					WHEN @courant > 1 THEN @ajout + 'millions '
					END 
				WHEN 1000 THEN
					CASE WHEN @courant > 1 THEN @ajout ELSE '' END + 'mille ' 
				ELSE @ajout
				END

			SELECT @reste = @reste - @courant * @diviseur
		END
		SELECT @diviseur = @diviseur / 1000
	END

	IF @lettres = '' SELECT @lettres = 'zéro'

	RETURN RTRIM(@lettres)
END
GO

Conclusion :


Comme j'en avais besoin pour convertir des dates, je me suis arrêté avant le million, mais on peut rajouter facilement les millions et milliards. (passer le @diviseur initial à 10^6 ou 10^9, selon les besoin, puis ajouter le cas à la fin dans le CASE @diviseur)

Update:
J'ai ajouté les millions... J'espère que ça aidera certains.
Et je me suis amusé à retourner une simple indication de dépassement si on atteint le milliard.
Notez d'ailleurs que pour les milliards, il faudra (en plus des mêmes modifications effectuées ici) passer le type de @nombre et @reste à bigint (le int étant majoré à 2,147,483,647).

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

Messages postés
1
Date d'inscription
mardi 8 mai 2012
Statut
Membre
Dernière intervention
8 mai 2012

Bonjour, merci pour ce code qui m'a été bien utile :-) J'ai essayé de m'en inspirer pour gérer les nombres mais en anglais et j'y suis presque sauf pour la gestion du "and", pas moyen de trouver comment gérer de le mettre dans certains cas et pas dans d'autres.
Exemple : 159256
me donne One hundred and fifty-nine thousand two hundred and fifty-six.

Alors que le premier and devant fifty-nine ne devrait pas être là :-/ Est-ce que quelqu'un peut me donner un coup de main pour l'anglais svp ?

Voici mon code, c'est pour les nombres ordinaux, avec "th" à la fin donc j'ai rajouté des case à la fin pour gérer cela :
CREATE FUNCTION Get_Number_to_Ordinal_In_English_Letters
(
@number int
)
RETURNS varchar(200)
AS
BEGIN
DECLARE @letters varchar(200)
DECLARE @divisor int
DECLARE @hundred int
DECLARE @ten int
DECLARE @unit int
DECLARE @remaining int
DECLARE @currentnumber int
DECLARE @tennb bit
DECLARE @adding varchar(200)
DECLARE @terminaison varchar(20)
SET @letters = ''
SET @terminaison = ''
SET @divisor = 1000000
SET @tennb = 0
SET @remaining =@number
IF @number > 999999999
RETURN 'One billion or more'
WHILE @divisor >= 1
BEGIN
SELECT @currentnumber = @remaining / @divisor
IF @currentnumber <> 0
BEGIN
SELECT @hundred = @currentnumber / 100
SELECT @ten = (@currentnumber - @hundred * 100) / 10
SELECT @unit = @currentnumber - (@hundred * 100) - (@ten * 10)
SELECT @adding = ''
SELECT @adding = @adding +
CASE @hundred
WHEN 1 THEN
CASE WHEN @ten 0 AND @unit 0 THEN 'one hundred ' ELSE 'one hundred and ' END
WHEN 2 THEN
CASE WHEN @ten 0 AND @unit 0 THEN 'two hundred ' ELSE 'two hundred and ' END
WHEN 3 THEN
CASE WHEN @ten 0 AND @unit 0 THEN 'three hundred ' ELSE 'three hundred and ' END
WHEN 4 THEN
CASE WHEN @ten 0 AND @unit 0 THEN 'four hundred ' ELSE 'four hundred and ' END
WHEN 5 THEN
CASE WHEN @ten 0 AND @unit 0 THEN 'five hundred ' ELSE 'five hundred and ' END
WHEN 6 THEN
CASE WHEN @ten 0 AND @unit 0 THEN 'six hundred ' ELSE 'six hundred and ' END
WHEN 7 THEN
CASE WHEN @ten 0 AND @unit 0 THEN 'seven hundred ' ELSE 'seven hundred and ' END
WHEN 8 THEN
CASE WHEN @ten 0 AND @unit 0 THEN 'eight hundred ' ELSE 'eight hundred and ' END
WHEN 9 THEN
CASE WHEN @ten 0 AND @unit 0 THEN 'nine hundred ' ELSE 'nine hundred and ' END
ELSE ''
END
SELECT @adding = @adding +
CASE @ten
WHEN 2 THEN
CASE WHEN @unit = 0 THEN 'twenty ' ELSE 'twenty-' END
WHEN 3 THEN
CASE WHEN @unit = 0 THEN 'thirty ' ELSE 'thirty-' END
WHEN 4 THEN
CASE WHEN @unit = 0 THEN 'forty ' ELSE 'forty-' END
WHEN 5 THEN
CASE WHEN @unit = 0 THEN 'fifty ' ELSE 'fifty-' END
WHEN 6 THEN
CASE WHEN @unit = 0 THEN 'sixty ' ELSE 'sixty-' END
WHEN 7 THEN
CASE WHEN @unit = 0 THEN 'seventy ' ELSE 'seventy-' END
WHEN 8 THEN
CASE WHEN @unit = 0 THEN 'eighty ' ELSE 'eighty-' END
WHEN 9 THEN
CASE WHEN @unit = 0 THEN 'ninety ' ELSE 'ninety-' END
ELSE ''
END

SELECT @tennb = CASE @ten
WHEN 1 THEN 1
ELSE 0
END
SELECT @adding = @adding +
CASE @unit
WHEN 0 THEN
CASE @tennb WHEN 1 THEN 'ten ' ELSE '' END
WHEN 1 THEN
CASE @tennb WHEN 1 THEN 'eleven ' ELSE 'one ' END
WHEN 2 THEN
CASE @tennb WHEN 1 THEN 'twelve ' ELSE 'two ' END
WHEN 3 THEN
CASE @tennb WHEN 1 THEN 'thirteen ' ELSE 'three ' END
WHEN 4 THEN
CASE @tennb WHEN 1 THEN 'fourteen ' ELSE 'four ' END
WHEN 5 THEN
CASE @tennb WHEN 1 THEN 'fifteen ' ELSE 'five ' END
WHEN 6 THEN
CASE @tennb WHEN 1 THEN 'sixteen ' ELSE 'six ' END
WHEN 7 THEN
CASE @tennb WHEN 1 THEN 'seventeen ' ELSE 'seven ' END
WHEN 8 THEN
CASE @tennb WHEN 1 THEN 'eighteen ' ELSE 'eight ' END
WHEN 9 THEN
CASE @tennb WHEN 1 THEN 'nineteen ' ELSE 'nine ' END
ELSE ''
END
SELECT @letters = @letters +
CASE @divisor
WHEN 1000000 THEN
CASE
WHEN @currentnumber = 1 THEN 'one million '
WHEN @currentnumber > 1 THEN @adding + 'millions '
END
WHEN 1000 THEN
@adding + 'thousand '
ELSE @adding
END
SELECT @remaining = @remaining - @currentnumber * @divisor
END
SELECT @divisor = @divisor / 1000
END
IF @letters '' SELECT @letters 'zero'
SELECT @terminaison = right( @letters, 4 )
IF @terminaison 'zero' select @letters 'nought'
ELSE IF @terminaison 'one' select @letters substr(@letters,1, length(@letters)-4) + 'first'
ELSE IF @terminaison 'two' select @letters substr(@letters,1, length(@letters)-4) + 'second'
ELSE IF @terminaison 'ree' select @letters substr(@letters,1, length(@letters)-4) + 'ird'
ELSE IF @terminaison 'ive' select @letters substr(@letters,1, length(@letters)-3) + 'fth'
ELSE IF @terminaison 'ght' select @letters substr(@letters,1, length(@letters)-1) + 'h'
ELSE IF @terminaison 'ine' select @letters substr(@letters,1, length(@letters)-2) + 'th'
ELSE IF @terminaison 'lve' select @letters substr(@letters,1, length(@letters)-3) + 'fth'
ELSE IF @terminaison like '%y ' select @letters = substr(@letters,1, length(@letters)-2) + 'ieth'
ELSE SELECT @letters = substr(@letters,1, length(@letters)-1) + 'th'
RETURN @letters
END

Merci beaucoup pour votre aide! AnneSo
Messages postés
3
Date d'inscription
vendredi 23 mai 2008
Statut
Membre
Dernière intervention
24 juillet 2010

Voilà, j'ai retouché le code pour prendre en compte les millions.
Mes quelques tests sont concluants, donc si ça ne fonctionne pas, merci de me donner un ou deux exemples de cas litigieux.
Messages postés
1
Date d'inscription
samedi 15 mars 2003
Statut
Membre
Dernière intervention
23 juillet 2010

Bonjour,
j'ai essayé d'adapter votre code pour la gestion des millions mais ca ne fonctionne pas, pourriez vous m'aider ou nous donner le script ?

Merci
Messages postés
1
Date d'inscription
jeudi 19 avril 2007
Statut
Membre
Dernière intervention
21 décembre 2009

Bonjour à tous, j'ai essayé d'adapter avec PL/SQL mais je vois toujours des erreurs quelqu'un pourra m'aider. Merci d'avance
Messages postés
40
Date d'inscription
dimanche 18 janvier 2009
Statut
Membre
Dernière intervention
2 février 2012
1
Super,
J'ai fait le même programme à une époque sous qbasic et j'avais compris la difficulté et l'esprit tordu de nos académiciens de la langue française.
Je te donne huit car tu ne dépasse pas le million. quant à la virgule , j'estime que le dba peut faire preuve d'imagination :
select NombreEnLettres(95) + ' Euros et ' + NombreEnLettres (40) + ' centimes'
Merci pour cette prtit fonction.
Afficher les 10 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.