logo

Преобразование чисел в строки в сценариях

Иногда, для повышения удобства работы пользователей, может потребоваться преобразование чисел в строки. Чаще всего возникает необходимость автоматически написать сумму прописью, например: 152,42 – сто пятьдесят два рубля, 42 копейки.

Сделать это можно с помощью следующего сценария:

public void OnSummaChange(Context context, EleWise.ELMA.Model.Views.FormViewBuilder<Context> form)
{
	decimal mon;//в ELMA нет типа данных decimal, а метод RurPhrase работает только с ним, поэтому необходимо самостоятельно объявить переменную этого типа
	mon = (decimal)context.Summa.Value;//присвоение выше объявленной переменной значения переменной Summa с преобразованием в decimal
	context.Propisjyu = P_SummaPropisjyu_Scripts.RurPhrase(mon);//используя метод RurPhrase получаем результат, и записываем в переменную Propisjuy
}
                         	
public static string RurPhrase (decimal money)
{ 
	return CurPhrase(money,"рубль","рубля","рублей","копейка","копейки","копеек");
}

public static string NumPhrase (ulong Value, bool IsMale) 
{
	if (Value==0UL) return "Ноль";
	string[] Dek1={""," од"," дв"," три"," четыре"," пять"," шесть"," семь"," восемь"," девять"," десять"," одиннадцать"," двенадцать"," тринадцать",
	" четырнадцать"," пятнадцать"," шестнадцать"," семнадцать"," восемнадцать"," девятнадцать"};
	string[] Dek2={"",""," двадцать"," тридцать"," сорок"," пятьдесят"," шестьдесят"," семьдесят"," восемьдесят"," девяносто"};
	string[] Dek3={""," сто"," двести"," триста"," четыреста"," пятьсот"," шестьсот"," семьсот"," восемьсот"," девятьсот"};
	string[] Th={"",""," тысяч"," миллион"," миллиард"," триллион"," квадриллион"," квинтиллион"};
	string str="";
	for (byte th=1; Value>0; th++) 
	{
		ushort gr=(ushort)(Value%1000); 
		Value=(Value-gr)/1000;
		if (gr>0) 
		{
			byte d3=(byte)((gr-gr%100)/100);
			byte d1=(byte)(gr%10);
			byte d2=(byte)((gr-d3*100-d1)/10);
			if (d2==1) d1+=(byte)10;
			bool ismale=(th>2)||((th==1)&&IsMale);
			str=Dek3[d3]+Dek2[d2]+Dek1[d1]+EndDek1(d1,ismale)+Th[th]+EndTh(th,d1)+str;
		};
	};
	str=str.Substring(1,1).ToUpper()+str.Substring(2);
	return str;
}

#region Private members

private static string CurPhrase (decimal money, 
	string word1,string word234,string wordmore,
	string sword1,string sword234,string swordmore)
{ 
	money=decimal.Round(money,2);
	decimal decintpart=decimal.Truncate(money);
	ulong intpart=decimal.ToUInt64(decintpart);
	string str=NumPhrase(intpart,true)+" ";
	byte endpart=(byte)(intpart%100UL); 
	if (endpart>19) endpart=(byte)(endpart%10);
	switch (endpart) 
	{
		case 1: str+=word1; break;
		case 2:
		case 3:
		case 4: str+=word234; break;
		default: str+=wordmore; break;
	}
	byte fracpart=decimal.ToByte((money-decintpart)*100M);
	str+=" "+((fracpart<10)?"0":"")+fracpart.ToString()+" ";
	if (fracpart>19) fracpart=(byte)(fracpart%10);
	switch (fracpart) 
	{
		case 1: str+=sword1; break;
		case 2:
		case 3:
		case 4: str+=sword234; break;
		default: str+=swordmore; break;
	};
	return str;
}

private static string EndTh(byte ThNum, byte Dek)
{
	bool In234=((Dek>=2)&&(Dek<=4));
	bool More4=((Dek>4)||(Dek==0));
	if (((ThNum>2)&&In234)||((ThNum==2)&&(Dek==1))) return "а";
	else if ((ThNum>2)&&More4) return "ов";
	else if ((ThNum==2)&&In234) return "и";
	else return "";
}

private static string EndDek1(byte Dek, bool IsMale)
{
	if ((Dek>2)||(Dek==0)) return "";
	else if (Dek==1) 
	{
		if (IsMale) return "ин";
		else return "на";
	}
	else 
	{
		if (IsMale) return "а"; 
		else return "е";
	}
}
#endregion

В результате выполнения этого сценария, например, сумма 1552,25, будет записана как "Одна тысяча пятьсот пятьдесят два рубля, 25 копеек"

Кроме того, при необходимости, можно создать метод для преобразования других валют, или каких-либо других объектов.
Методы для Долларов и Гривен:
public static string USDPhrase (decimal money)
//где string тип данных возвращаемых методом USDPhrase имя метода decimal тип данных аргумента money имя аргумента
{return CurPhrase(money,"доллар","доллара","долларов","цент","цента","центов");}

public static string GRVPhrase (decimal money)
{return CurPhrase(money,"гривна","гривны","гривен","копейка","копейки","копеек");}
В русском языке есть три склонения существительного после числительного.
Например: 1 Автомобиль, 2, 3, 4 Автомобиля, 5 и больше Автомобилей.
Задав эти склонения, можно создать метод для работы с любыми существительными, а не только с валютами.
Обратите внимание, что для вызова созданного нами метода AutomobilePhrase, необходимо использовать его имя, и имя заданного аргумента (count).
decimal count;
count = (decimal)context.Avtomobili.Value;
context.Propisjyu = P_SummaPropisjyu_Scripts.AutomobilePhrase (count);
int lt = context.Propisjyu.Length; //decimal возвращает дробное число, а Автомобили измеряются целыми числами, поэтому 
context.Propisjyu = context.Propisjyu.Substring(0,lt-3);//необходимо отсечь последние 3 строчки из результата - пробел и два нуля

public static string AutomobilePhrase (int count)
{ 
	return CurPhrase(count,"Автомобиль","Автомобиля","Автомобилей");//указываем варианты склонения
}