Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » AutoIt » Перевод числа в пропись

Ответить
Настройки темы
Перевод числа в пропись

Новый участник


Сообщения: 28
Благодарности: 2

Профиль | Отправить PM | Цитировать


Выручайте времени совсем нет.
Нужна подпрограмма, которая переводит деньги из числа в пропись. Например: 10598 р => десять тысяч пятьсот девяносто восемь рублей.
Как это сделать я понимаю, но не когда. Может уже есть готовый код?

Отправлено: 07:50, 16-04-2012

 

Аватара для Creat0R

Must AutoIt


Сообщения: 3054
Благодарности: 1009

Профиль | Сайт | Отправить PM | Цитировать


Вот вариант на английском, можно перевести значения:

Код: Выделить весь код
$iNum = 10598
$sNumName = _NumberNumToName($iNum)
$sNumber = _NumberNameToNum($sNumName)

ConsoleWrite($sNumName & @LF)
ConsoleWrite($sNumber & @LF)

Func _NumberNameToNum($sWord)
	Local $sDigits = "zero|one|two|three|four|five|six|seven|eight|nine"
	Local $sTeens = "eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen"
	Local $sTens = "ten|twenty|thirty|forty|fifty|sixty|seventy|eighty|ninety"
	Local $sBig = "thousand|million|billion|trillion|quadrillion|quintillion|sextillion|septillion|octillion|nonillion|" & _
		"decillion|undecillion|duodecillion|tredecillion|quattuordecillion|quindecillion|sexdecillion|septendecillion|octodecillion|novemdecillion|vigintillion"
	
	Local $asDigits = StringSplit($sDigits, "|", 2)
	Local $asTeens = StringSplit($sTeens, "|", 2)
	Local $asTens = StringSplit($sTens, "|", 2)
	Local $asBig = StringSplit($sBig, "|", 2)
	
	Local $sRet = ""
	Local $iTemp[3] = [0, 0, 0]
	Local $aWords
	
	; check...
	If Not StringRegExp($sWord, "^(minus\s+)?((((" & $sTens & ")\s+)?(" & $sDigits & ")|(" & $sTeens & ")|(" & $sTens & "))\s+(hundred|" & $sBig & ")(\s+and)?(\s+|\z))*(((" & $sTens & ")\s+)?(" & $sDigits & ")?|(" & $sTeens & ")|(" & $sTens & "))(\s+point(\s+(" & $sDigits & "))+)?$") Then
		Return SetError(1)
	EndIf
	
	$sWord = StringReplace($sWord, " and", "")
	
	For $i = 0 To 8
		$sWord = StringReplace($sWord, $asTeens[$i], "ten " & $asDigits[$i + 1])
	Next
	
	$aWords = StringSplit($sWord, " ")
	
	If StringInStr($sWord, " point ") Then
		Do
			For $n = 0 To UBound($asDigits) - 1
				If $asDigits[$n] = $aWords[$aWords[0]] Then
					$sRet = $n & $sRet
					ExitLoop
				EndIf
			Next
			
			$aWords[0] -= 1
		Until $aWords[$aWords[0]] <> "point"
		
		$sRet = "." & $sRet
		If $aWords[$aWords[0]] = "zero" Then $sRet = "0" & $sRet
	EndIf
	
	For $i = $aWords[0] To 1 Step -1
		If $i = 1 And $aWords[1] = "minus" Then
			$sRet = "-" & $sRet
			ExitLoop
		EndIf
		
		If StringInStr("|" & $sDigits & "|", "|" & $aWords[$i] & "|") Then ; Digit
			If $iTemp[0] <> 0 Then Return SetError(2, $i, "") ; Invalid word: @extended, expected large identifier not digit.
			
			For $n = 0 To UBound($asDigits) - 1
				If $asDigits[$n] = $aWords[$i] Then
					$iTemp[0] = $n
					ExitLoop
				EndIf
			Next
		ElseIf StringInStr("|" & $sTens & "|", "|" & $aWords[$i] & "|") Then ; Tens
			If $iTemp[1] <> 0 Then Return SetError(3, $i, "") ; Invalid word: @extended, expected large identifier not ten.
			
			For $n = 0 To UBound($asTens) - 1
				If $asTens[$n] = $aWords[$i] Then
					$iTemp[1] = $n + 1
					ExitLoop
				EndIf
			Next
		ElseIf $aWords[$i] = "hundred" Then ; hundred
			If $iTemp[2] <> 0 Then Return SetError(4, $i, "") ; Invalid word: @extended, expected large identifier not hundred.
			
			For $n = 0 To UBound($asDigits) - 1
				If $asDigits[$n] = $aWords[$i - 1] Then
					$iTemp[2] = $n
					$i -= 1
					ExitLoop
				EndIf
			Next
		ElseIf StringInStr("|" & $sBig & "|", "|" & $aWords[$i] & "|") Then ; BIG
			$sRet = $iTemp[2] & $iTemp[1] & $iTemp[0] & $sRet
			
			$iTemp[0] = 0
			$iTemp[1] = 0
			$iTemp[2] = 0
		Else
			Return SetError(4, $i, "") ; Invalid word: @extended, word not recognized.
		EndIf
	Next
	
	$sRet = $iTemp[2] & $iTemp[1] & $iTemp[0] & $sRet
	
	; No leading 0's
	While StringLeft($sRet, 1) = "0" And StringLeft($sRet, 2) <> "0."
		$sRet = StringTrimLeft($sRet, 1)
	WEnd
	
	; No trailing 0's if decimal
	If StringInStr($sRet, ".") Then
		While StringRight($sRet, 1) = "0"
			$sRet = StringTrimRight($sRet, 1)
		WEnd
		
		If StringRight($sRet, 1) = "." Then $sRet = StringTrimRight($sRet, 1)
	EndIf
	
	Return $sRet
EndFunc

Func _NumberNumToName($iNum)
	$iNum = String($iNum)
	$iNum = StringStripWS($iNum, 8)
	If Not StringRegExp($iNum, "^-?\d+?(\.\d+)?$") Then Return SetError(2, 0, "")
	If $iNum = "0" Then Return "zero"
	
	Local $asDigits[10] = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"]
	Local $asTeens[9] = ["eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"]
	Local $asTens[9] = ["ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"]
	Local $asBig[21] = ["thousand", "million", "billion", "trillion", "quadrillion", "quintillion", "sextillion", "septillion", "octillion", "nonillion", _
		"decillion", "undecillion", "duodecillion", "tredecillion", "quattuordecillion", "quindecillion", "sexdecillion", "septendecillion", "octodecillion", "novemdecillion", "vigintillion"]
	
	; No leading 0's
	While StringLeft($iNum, 1) = "0" And StringLeft($iNum, 2) <> "0."
		$iNum = StringTrimLeft($iNum, 1)
	WEnd
	
	; No trailing 0's if decimal
	If StringInStr($iNum, ".") Then
		While StringRight($iNum, 1) = "0"
			$iNum = StringTrimRight($iNum, 1)
		WEnd
		
		If StringRight($iNum, 1) = "." Then $iNum = StringTrimRight($iNum, 1)
	EndIf
	
	Local $iTemp
	Local $iLen
	Local $sRet = ""
	Local $nDec = ""
	
	; Do decimal places later
	If StringInStr($iNum, ".") Then
		$nDec = StringMid($iNum, StringInStr($iNum, ".") + 1)
		$iNum = StringLeft($iNum, StringInStr($iNum, ".") - 1)
	EndIf
	
	; Check negative
	If StringLeft($iNum, 1) = "-" Then
		$iNum = StringTrimLeft($iNum, 1)
		$sRet &= "minus "
	EndIf
	
	; Very big numbers
	For $i = 21 To 1 Step -1
		If StringLen($iNum) > $i * 3 Then
			$iLen = Mod(StringLen($iNum), 3)
			If $iLen = 0 Then $iLen = 3
			
			$iTemp = StringLeft($iNum, $iLen)
			$iNum = StringTrimLeft($iNum, $iLen)
			
			$iTemp = _NumberNumToName($iTemp)
			If $iTemp = "" Or $iTemp = "0" Then ContinueLoop
			If Not @error Then $sRet &= $iTemp & " " & $asBig[$i - 1] & " "
		EndIf
	Next
	
	; hundreds
	If StringLen($iNum) >= 3 Then
		$iTemp = StringLeft($iNum, 1)
		$iNum = StringTrimLeft($iNum, 1)
		
		If $iTemp <> "0" Then $sRet &= $asDigits[Int($iTemp)] & " hundred "
		If $iNum <> "00" Then $sRet &= "and "
	EndIf
	
	If StringLen($iNum) = 2 And StringLeft($iNum, 1) = "1" And StringRight($iNum, 1) <> "0" Then
		$iTemp = StringRight($iNum, 1)
		$sRet &= $asTeens[Int($iTemp) - 1] & " "
		
		$iNum = ""
	Else
		; Tens
		If StringLen($iNum) = 2 Then
			$iTemp = StringLeft($iNum, 1)
			$iNum = StringTrimLeft($iNum, 1)
			
			If $iTemp <> "0" Then $sRet &= $asTens[Int($iTemp) - 1] & " "
		EndIf
		
		; Digits
		If StringLen($iNum) = 1 Then
			If $iNum <> "0" Then $sRet &= $asDigits[Int($iNum)] & " "
			
			$iNum = ""
		EndIf
	EndIf
	
	If $nDec <> "" Then
		If $sRet = "" Or $sRet = "minus " Then $sRet &= "zero "
		$sRet &= "point "
		
		Do
			$iTemp = StringLeft($nDec, 1)
			$nDec = StringTrimLeft($nDec, 1)
			
			$sRet &= $asDigits[Int($iTemp)] & " "
		Until $nDec = ""
	EndIf
	
	$sRet = StringTrimRight($sRet, 1)
	
	Return $sRet
EndFunc

-------
“Сделай так просто, как возможно, но не проще этого.”... “Ты никогда не решишь проблему, если будешь думать так же, как те, кто её создал.”

Альберт Эйнштейн

P.S «Не оказываю техподдержку через ПМ/ICQ, и по email - для этого есть форум. ©»

http://creator-lab.ucoz.ru/Images/Icons/autoit_icon.png Русское сообщество AutoIt | http://creator-lab.ucoz.ru/Images/Ic...eator_icon.png CreatoR's Lab | http://creator-lab.ucoz.ru/Images/Icons/oac_icon.png Opera AC Community


Отправлено: 15:07, 16-04-2012 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Ветеран


Сообщения: 27449
Благодарности: 8087

Профиль | Отправить PM | Цитировать


Creat0R, прямого перевода, вероятно, не получится, ибо у нас есть ещё такое понятие, как род: одна тысяча, но один миллион. Я думаю, проще будет взять любой из работоспособных макросов «число|сумма прописью VBA» и переложить его с VBA на AutoIt. Раньше их немало было на русскоязычных конкурсах Microsoft Office для разработчиков, да и так писал всяк кому не лень свой вариант (даже я ).

Отправлено: 15:30, 16-04-2012 | #3


Аватара для Creat0R

Must AutoIt


Сообщения: 3054
Благодарности: 1009

Профиль | Сайт | Отправить PM | Цитировать


Цитата Iska:
у нас есть ещё такое понятие, как род »
При сильном желании можно это предусмотреть.

-------
“Сделай так просто, как возможно, но не проще этого.”... “Ты никогда не решишь проблему, если будешь думать так же, как те, кто её создал.”

Альберт Эйнштейн

P.S «Не оказываю техподдержку через ПМ/ICQ, и по email - для этого есть форум. ©»

http://creator-lab.ucoz.ru/Images/Icons/autoit_icon.png Русское сообщество AutoIt | http://creator-lab.ucoz.ru/Images/Ic...eator_icon.png CreatoR's Lab | http://creator-lab.ucoz.ru/Images/Icons/oac_icon.png Opera AC Community


Отправлено: 16:22, 16-04-2012 | #4


Аватара для apozlevich

Ветеран


Автор проектов


Сообщения: 1025
Благодарности: 180

Профиль | Отправить PM | Цитировать


Точно видел готовые программки со всеми заморочками.

-------
echo 127.0.0.1 google.ru >> %systemroot%\system32\drivers\etc\hosts && ipconfig /flushdns && echo Я ничего не трогал, оно само!


Отправлено: 16:26, 16-04-2012 | #5


Аватара для Creat0R

Must AutoIt


Сообщения: 3054
Благодарности: 1009

Профиль | Сайт | Отправить PM | Цитировать


Цитата Iska:
проще будет взять любой из работоспособных макросов «число|сумма прописью VBA» и переложить его с VBA на AutoIt »
Переделал вроде:

Код: Выделить весь код
ConsoleWrite(IntToWords(123))

Func ShortNum($num, $razr)
	Dim $hundreds, $tens, $ones, $razryad
	Dim $hundreds[10] = ["", " сто", " двести", " триста", " четыреста", " пятьсот", " шестьсот", " семьсот", " восемьсот", " девятьсот"]
	Dim $tens[10] = ["", "", " двадцать", " тридцать", " сорок", " пятьдесят", " шестьдесят", " семьдесят", " восемьдесят", " девяносто"]
	Dim $ones[20] = ["", "", "", " три", " четыре", " пять", " шесть", " семь", " восемь", " девять", " десять", " одиннадцать", " двенадцать", " тринадцать", " четырнадцать", " пятнадцать", " шестнадцать", " семнадцать", " восемнадцать", " девятнадцать"]
	Dim $razryad[7] = ["", " тысяч", " миллион", " миллиард", " триллион", " квадриллион", " квинтиллион"]
	
	Dim $t, $o
	
	$result = $hundreds[$num / 100]
	
	If $num = 0 Then Return
	
	$t = Mod($num, 100) / 10
	$o = Mod($num, 10)
	
	If $t <> 1 Then
		$result &= $tens[$t]
		
		Switch $o
			Case 1
				If $razr = 1 Then
					$result &= " одна"
				Else
					$result &= " один"
				EndIf
			Case 2
				If $razr = 1 Then
					$result &= " две"
				Else
					$result &= " два"
				EndIf
			Case 3, 4, 5, 6, 7, 8, 9
				$result &= $ones[$o]
		EndSwitch
		
		$result &= $razryad[$razr]
		
		Switch $o
			Case 1
				If $razr = 1 Then
					$result &= "а"
				EndIf
			Case 2, 3, 4
				If $razr = 1 Then
					$result &= "и"
				ElseIf $razr > 1 Then
					$result &= "а"
				EndIf
			Case Else
				If ($razr > 1) Then
					$result &= "ов"
				EndIf
		EndSwitch
		
	Else
		$result &= $ones[Mod($num, 100)]
		$result &= $razryad[$razr]
		
		If $razr > 1 Then
			$result &= "ов"
		EndIf
	EndIf
	
	Return $result
EndFunc

Func IntToWords($s)
	Dim $i, $count
	
	If (StringLen($s) = 0) Or ($s = "0") Then
		Return "ноль"
	EndIf
	
	$count = (StringLen($s) + 2) / 3
	
	If $count > 7 Then
		Return "Value is too large"
	EndIf
	
	$result = ""
	
	For $i = 1 To $count
		$result = ShortNum((StringMid($s, StringLen($s) - 3 * $i + 1, 3)), $i - 1) & $result
	Next
	
	If StringLen($result) > 0 Then
		$result = StringRight($result, StringLen($result) - 1)
	EndIf
	
	If $result = "" Then $result = $s
	
	Return $result
EndFunc
Но есть многие недоработки.

-------
“Сделай так просто, как возможно, но не проще этого.”... “Ты никогда не решишь проблему, если будешь думать так же, как те, кто её создал.”

Альберт Эйнштейн

P.S «Не оказываю техподдержку через ПМ/ICQ, и по email - для этого есть форум. ©»

http://creator-lab.ucoz.ru/Images/Icons/autoit_icon.png Русское сообщество AutoIt | http://creator-lab.ucoz.ru/Images/Ic...eator_icon.png CreatoR's Lab | http://creator-lab.ucoz.ru/Images/Icons/oac_icon.png Opera AC Community


Отправлено: 16:51, 16-04-2012 | #6


Аватара для apozlevich

Ветеран


Автор проектов


Сообщения: 1025
Благодарности: 180

Профиль | Отправить PM | Цитировать


Продолжаю оффтопить: а зачем использовать именно AutoIt? Можно же и с VBA работать

-------
echo 127.0.0.1 google.ru >> %systemroot%\system32\drivers\etc\hosts && ipconfig /flushdns && echo Я ничего не трогал, оно само!


Отправлено: 16:59, 16-04-2012 | #7


Аватара для Creat0R

Must AutoIt


Сообщения: 3054
Благодарности: 1009

Профиль | Сайт | Отправить PM | Цитировать


Цитата apozlevich:
Продолжаю оффтопить »
Заканчивай.

Цитата apozlevich:
Можно же и с VBA работать »
Покажи мне нормально решение на нём, и будет решение на AutoIt.

-------
“Сделай так просто, как возможно, но не проще этого.”... “Ты никогда не решишь проблему, если будешь думать так же, как те, кто её создал.”

Альберт Эйнштейн

P.S «Не оказываю техподдержку через ПМ/ICQ, и по email - для этого есть форум. ©»

http://creator-lab.ucoz.ru/Images/Icons/autoit_icon.png Русское сообщество AutoIt | http://creator-lab.ucoz.ru/Images/Ic...eator_icon.png CreatoR's Lab | http://creator-lab.ucoz.ru/Images/Icons/oac_icon.png Opera AC Community

Это сообщение посчитали полезным следующие участники:

Отправлено: 17:06, 16-04-2012 | #8


Аватара для apozlevich

Ветеран


Автор проектов


Сообщения: 1025
Благодарности: 180

Профиль | Отправить PM | Цитировать


Цитата Creat0R:
Цитата Iska:
проще будет взять любой из работоспособных макросов «число|сумма прописью VBA» и переложить его с VBA на AutoIt
Переделал вроде
Создается впечатление, что вы переписали код с VBA на AutoIt. Или это код из первого поста?

А вообще, я просто присоединился к Iska с его вторым постом
Цитата Iska:
Я думаю, проще будет взять любой из работоспособных макросов «число|сумма прописью VBA» »
Но
Цитата apozlevich:
Можно же и с VBA работать »

Отправлено: 17:38, 16-04-2012 | #9


Новый участник


Сообщения: 28
Благодарности: 2

Профиль | Отправить PM | Цитировать


У меня уже 30 кб кода куда нужно присобачить программу для перевода на autoit, а на vba это было бы раза в два больше. Можно и с VBA работать можно на ассемблере вообще писать, мне на autoit надо. Ладно деваться некуда пойду писать.

Отправлено: 18:16, 16-04-2012 | #10



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » AutoIt » Перевод числа в пропись

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
2007 - [решено] перевод числа в Excel 2007 в текстовую прописную форму andybus72 Microsoft Office (Word, Excel, Outlook и т.д.) 2 19-03-2012 21:27
Разное - Перевод 10ричного числа в 16ричное. Assembler dancheg Программирование и базы данных 1 17-11-2010 23:52
Числа и клетки 1.0 OSZone Software Новости программного обеспечения 0 06-08-2010 10:30
[решено] Excel, перевод числа во время. Как? Grub Хочу все знать 6 25-11-2009 10:57
Перевод десятичного числа в двойчное Guest Программирование и базы данных 2 13-03-2004 06:38




 
Переход