На одной из сайтов нашел функцию на Паскале, которая преобразовывала сумму в текст. Я решил переписать ее для MS SQL (так у нее значительно увеличивается диапазон применений).
Сам механизм состоит из нескольких функций. Конечная функция: dbo.[Money2Words, rub]( Money).
Пример запуска
Select dbo.[Money2Words, rub]( 1002.34 )
Результат:
«Одна тысяча два рубля 34 коп.»
create function [SumStrThree] ( @Summa varchar(4000), @TempValue bigint, Rod int, @w1 varchar(40), @w2to4 varchar(40), @w5to10 varchar(40) )
RETURNS tab TABLE ( Txt varchar(4000), Rest bigint )
as begin
/*
— — Формирования строки для трехзначного числа:
— (последний трех знаков TempValue
— Eсли нужно оперировать с числами > 2 147 483 647
— замените в описании на TempValue AS DOUBLE
--====================================
*/
declare Rest int, @Rest1 int, @EndWord varchar(100), @s1 varchar(40), s10 varchar(40), s100 varchar(40)
— set Rest = @TempValue % 1000
set @TempValue = @TempValue / 1000
If Rest = 0 begin — последние три знака нулевые
If @Summa = ''
set @Summa = @w5to10 + ' '
insert into tab
select @Summa, @TempValue
return
End
— — начинаем подсчет с Rest
set @EndWord = @w5to10
— сотни
Select s100 = Case Rest / 100
when 0 then ''
when 1 then 'сто '
when 2 then 'двести '
when 3 then 'триста '
when 4 then 'четыреста '
when 5 then 'пятьсот '
when 6 then 'шестьсот '
when 7 then 'семьсот '
when 8 then 'восемьсот '
when 9 then 'девятьсот '
End
— — десятки
set Rest = Rest % 100
set @Rest1 = Rest / 10
set @s1 = ''
Select s10 = Case @Rest1
when 0 then ''
when 1 then
Case Rest
when 10 then 'десять '
when 11 then 'одиннадцать '
when 12 then 'двенадцать '
when 13 then 'тринадцать '
when 14 then 'четырнадцать '
when 15 then 'пятнадцать '
when 16 then 'шестнадцать '
when 17 then 'семнадцать '
when 18 then 'восемнадцать '
when 19 then 'девятнадцать '
End
when 2 then 'двадцать '
when 3 then 'тридцать '
when 4 then 'сорок '
when 5 then 'пятьдесят '
when 6 then 'шестьдесят '
when 7 then 'семьдесят '
when 8 then 'восемьдесят '
when 9 then 'девяносто '
End
— If @Rest1 <> 1 begin — единицы
if Rest % 10 = 1
set @EndWord = @w1
else if Rest % 10 between 2 and 4
set @EndWord = @w2to4
Select @s1 = Case Rest % 10
when 0 then ''
when 1 then
Case Rod
when 1 then 'один '
when 2 then 'одна '
when 3 then 'одно '
End
when 2 then
Case
when Rod = 2
then 'две '
else 'два '
End
when 3 then 'три '
when 4 then 'четыре '
when 5 then 'пять '
when 6 then 'шесть '
when 7 then 'семь '
when 8 then 'восемь '
when 9 then 'девять '
End
End
— — сборка строки
insert into Tab
select Txt = RTrim(RTrim( s100 + s10 + @s1 + @EndWord) + ' ' + @Summa), @TempValue
return
End
go
create function dbo.SumStr(@Source bigint, Rod int, @w1 varchar(40), @w2to4 varchar(40), @w5to10 varchar(40) )
returns varchar(4000)
as begin
/*
— — 'Сумма прописью':
— преобразование числа из цифрого вида в символьное
— ==================================================
— Исходные данные:
— Source — число от 0 до 2147483647 (2^31-1)
— Eсли нужно оперировать с числами > 2 147 483 647
— замените описание переменных Source и TempValue на 'AS DOUBLE'
— — далее нужно задать информацию о единице изменения
— Rod% = 1 — мужской, = 2 — женский, = 3 — средний
— название единицы изменения:
— w1bigint — именительный падеж единственное число (= 1)
— w2to4bigint — родительный падеж единственное число (= 2-4)
— w5to10bigint — родительный падеж множественное число ( = 5-10)
— — Rod% должен быть задано обязательно, название единицы может быть
— не задано = ''
— ———————————————-
— Результат: Summa bigint — запись прописью
— --================================
*/
declare @Summa varchar(4000)
declare @TempValue bigint
— If Source = 0 begin
set @Summa = 'ноль ' + RTrim(@w5to10)
return @Summa
end
— select @TempValue = Source, @Summa = ''
— единицы
select @Summa = Txt, @TempValue = Rest from dbo.SumStrThree( @Summa, @TempValue, Rod, @w1, @w2to4, @w5to10)
If @TempValue = 0 return @Summa
— тысячи
select @Summa = Txt, @TempValue = Rest from dbo.SumStrThree( @Summa, @TempValue, 2, 'тысяча', 'тысячи', 'тысяч')
If @TempValue = 0 return @Summa
— миллионы
select @Summa = Txt, @TempValue = Rest from dbo.SumStrThree( @Summa, @TempValue, 1, 'миллион', 'миллиона', 'миллионов')
If @TempValue = 0 return @Summa
— миллиардов
select @Summa = Txt, @TempValue = Rest from dbo.SumStrThree( @Summa, @TempValue, 1, 'миллиард', 'миллиарда', 'миллиардов')
If @TempValue = 0 return @Summa
— select @Summa = Txt, @TempValue = Rest from dbo.SumStrThree( @Summa, @TempValue, 1, 'трилллион', 'триллиона', 'триллионов')
return @Summa
End;
go
create function dbo.[Money2Words, rub]( Money money )
returns varchar(max)
as begin
declare Source bigint
declare minus varchar(10)
declare sum varchar(max)
if Money < 0 begin
set minus = 'Минус '
set Money = -@Money
end else
set minus = ''
declare Cent int, @CentTxt varchar(20)
set Source = floor( Money )
set Cent = (@Money — 1. * Source ) * 100
set sum = Minus + dbo.SumStr( source, 1, 'рубль', 'рубля', 'рублей' )
if Cent < 10
set @CentTxt = ' 0' + convert(varchar, Cent) + ' коп.'
else
set @CentTxt = ' ' + convert(varchar(3), Cent) + ' коп.'
set sum = Upper( SubString( sum,1,1) ) + SubString( sum, 2, len(@sum)-1) + @CentTxt
return sum
end
Сам механизм состоит из нескольких функций. Конечная функция: dbo.[Money2Words, rub]( Money).
Пример запуска
Select dbo.[Money2Words, rub]( 1002.34 )
Результат:
«Одна тысяча два рубля 34 коп.»
create function [SumStrThree] ( @Summa varchar(4000), @TempValue bigint, Rod int, @w1 varchar(40), @w2to4 varchar(40), @w5to10 varchar(40) )
RETURNS tab TABLE ( Txt varchar(4000), Rest bigint )
as begin
/*
— — Формирования строки для трехзначного числа:
— (последний трех знаков TempValue
— Eсли нужно оперировать с числами > 2 147 483 647
— замените в описании на TempValue AS DOUBLE
--====================================
*/
declare Rest int, @Rest1 int, @EndWord varchar(100), @s1 varchar(40), s10 varchar(40), s100 varchar(40)
— set Rest = @TempValue % 1000
set @TempValue = @TempValue / 1000
If Rest = 0 begin — последние три знака нулевые
If @Summa = ''
set @Summa = @w5to10 + ' '
insert into tab
select @Summa, @TempValue
return
End
— — начинаем подсчет с Rest
set @EndWord = @w5to10
— сотни
Select s100 = Case Rest / 100
when 0 then ''
when 1 then 'сто '
when 2 then 'двести '
when 3 then 'триста '
when 4 then 'четыреста '
when 5 then 'пятьсот '
when 6 then 'шестьсот '
when 7 then 'семьсот '
when 8 then 'восемьсот '
when 9 then 'девятьсот '
End
— — десятки
set Rest = Rest % 100
set @Rest1 = Rest / 10
set @s1 = ''
Select s10 = Case @Rest1
when 0 then ''
when 1 then
Case Rest
when 10 then 'десять '
when 11 then 'одиннадцать '
when 12 then 'двенадцать '
when 13 then 'тринадцать '
when 14 then 'четырнадцать '
when 15 then 'пятнадцать '
when 16 then 'шестнадцать '
when 17 then 'семнадцать '
when 18 then 'восемнадцать '
when 19 then 'девятнадцать '
End
when 2 then 'двадцать '
when 3 then 'тридцать '
when 4 then 'сорок '
when 5 then 'пятьдесят '
when 6 then 'шестьдесят '
when 7 then 'семьдесят '
when 8 then 'восемьдесят '
when 9 then 'девяносто '
End
— If @Rest1 <> 1 begin — единицы
if Rest % 10 = 1
set @EndWord = @w1
else if Rest % 10 between 2 and 4
set @EndWord = @w2to4
Select @s1 = Case Rest % 10
when 0 then ''
when 1 then
Case Rod
when 1 then 'один '
when 2 then 'одна '
when 3 then 'одно '
End
when 2 then
Case
when Rod = 2
then 'две '
else 'два '
End
when 3 then 'три '
when 4 then 'четыре '
when 5 then 'пять '
when 6 then 'шесть '
when 7 then 'семь '
when 8 then 'восемь '
when 9 then 'девять '
End
End
— — сборка строки
insert into Tab
select Txt = RTrim(RTrim( s100 + s10 + @s1 + @EndWord) + ' ' + @Summa), @TempValue
return
End
go
create function dbo.SumStr(@Source bigint, Rod int, @w1 varchar(40), @w2to4 varchar(40), @w5to10 varchar(40) )
returns varchar(4000)
as begin
/*
— — 'Сумма прописью':
— преобразование числа из цифрого вида в символьное
— ==================================================
— Исходные данные:
— Source — число от 0 до 2147483647 (2^31-1)
— Eсли нужно оперировать с числами > 2 147 483 647
— замените описание переменных Source и TempValue на 'AS DOUBLE'
— — далее нужно задать информацию о единице изменения
— Rod% = 1 — мужской, = 2 — женский, = 3 — средний
— название единицы изменения:
— w1bigint — именительный падеж единственное число (= 1)
— w2to4bigint — родительный падеж единственное число (= 2-4)
— w5to10bigint — родительный падеж множественное число ( = 5-10)
— — Rod% должен быть задано обязательно, название единицы может быть
— не задано = ''
— ———————————————-
— Результат: Summa bigint — запись прописью
— --================================
*/
declare @Summa varchar(4000)
declare @TempValue bigint
— If Source = 0 begin
set @Summa = 'ноль ' + RTrim(@w5to10)
return @Summa
end
— select @TempValue = Source, @Summa = ''
— единицы
select @Summa = Txt, @TempValue = Rest from dbo.SumStrThree( @Summa, @TempValue, Rod, @w1, @w2to4, @w5to10)
If @TempValue = 0 return @Summa
— тысячи
select @Summa = Txt, @TempValue = Rest from dbo.SumStrThree( @Summa, @TempValue, 2, 'тысяча', 'тысячи', 'тысяч')
If @TempValue = 0 return @Summa
— миллионы
select @Summa = Txt, @TempValue = Rest from dbo.SumStrThree( @Summa, @TempValue, 1, 'миллион', 'миллиона', 'миллионов')
If @TempValue = 0 return @Summa
— миллиардов
select @Summa = Txt, @TempValue = Rest from dbo.SumStrThree( @Summa, @TempValue, 1, 'миллиард', 'миллиарда', 'миллиардов')
If @TempValue = 0 return @Summa
— select @Summa = Txt, @TempValue = Rest from dbo.SumStrThree( @Summa, @TempValue, 1, 'трилллион', 'триллиона', 'триллионов')
return @Summa
End;
go
create function dbo.[Money2Words, rub]( Money money )
returns varchar(max)
as begin
declare Source bigint
declare minus varchar(10)
declare sum varchar(max)
if Money < 0 begin
set minus = 'Минус '
set Money = -@Money
end else
set minus = ''
declare Cent int, @CentTxt varchar(20)
set Source = floor( Money )
set Cent = (@Money — 1. * Source ) * 100
set sum = Minus + dbo.SumStr( source, 1, 'рубль', 'рубля', 'рублей' )
if Cent < 10
set @CentTxt = ' 0' + convert(varchar, Cent) + ' коп.'
else
set @CentTxt = ' ' + convert(varchar(3), Cent) + ' коп.'
set sum = Upper( SubString( sum,1,1) ) + SubString( sum, 2, len(@sum)-1) + @CentTxt
return sum
end