gifts2017

Склонение числа прописью

Опубликовал Максим Умнов (maxvcb) в раздел Программирование - Универсальные функции

Склоняет число прописью до 999999 Пример: до склонения "Не позднее 3 (Три) дней", после - "Не позднее 3 (Трех) дней"

Столкнулся с тем, что число дней в договоре необходимо указывать в склонении (например, 3 (Трех) дней), перекопал инет и мануал 1С-ный, ничего не нашел. Может, я слепой или не там искал, не суть. 

Накатал склонялку, реализовал до 999999, т.к. более не нужно. Можно посмотреть, как сделано, и добавить, кому надо, и больше, добавляем слово в структуру и его аналог, в общем, все просто.

Работает так: у функции на входе число прописью, обработанное стандартной функцией 1С ЧислоПрописью(...)

На выходе склоненное или, если не удалось, то, что передали.

Тестил так: от балды вбивал всякие числа - склоняет.

Вот код, может, кому пригодится.

Функция ПолучитьСтруктуруСклонени(ЧислоПрописью)
	ЧислоПрописью = СокрЛП(ЧислоПрописью);
	
	ПадежРодительный = новый структура;
	ПадежРодительный.Вставить("Один","Одного");
	ПадежРодительный.Вставить("Два","Двух");
	ПадежРодительный.Вставить("Три","Трех");
	ПадежРодительный.Вставить("Четыре","Четырех");
	ПадежРодительный.Вставить("Пять","Пяти");
	ПадежРодительный.Вставить("Шесть","Шести");
	ПадежРодительный.Вставить("Семь","Семи");
	ПадежРодительный.Вставить("Восемь","Восьми");
	ПадежРодительный.Вставить("Девять","Девяти");
	ПадежРодительный.Вставить("Десять","Десяти");
	ПадежРодительный.Вставить("Одиннадцать","Одиннадцати");
	ПадежРодительный.Вставить("Двенадцать","Двенадцати");
	ПадежРодительный.Вставить("Тринадцать","Тринадцати");
	ПадежРодительный.Вставить("Четырнадцать","Четырнадцати");
	ПадежРодительный.Вставить("Пятнадцать","Пятнадцати");
	ПадежРодительный.Вставить("Шестнадцать","Шестнадцати");
	ПадежРодительный.Вставить("Семнадцать","Семнадцати");
	ПадежРодительный.Вставить("Восемнадцать","Восемнадцати");
	ПадежРодительный.Вставить("Девятнадцать","Девятнадцати");
	ПадежРодительный.Вставить("Двадцать","Двадцати");
	ПадежРодительный.Вставить("Тридцать","Тридцати");
	ПадежРодительный.Вставить("Сорок","Сорока");
	ПадежРодительный.Вставить("Пятьдесят","Пятидесяти");
	ПадежРодительный.Вставить("Шестьдесят","Шестидесяти");
	ПадежРодительный.Вставить("Семьдесят","Семидесяти");
	ПадежРодительный.Вставить("Восемьдесят","Восьмидесяти");
	ПадежРодительный.Вставить("Девяносто","Девятоста");
	ПадежРодительный.Вставить("Сто","Ста");
	ПадежРодительный.Вставить("Двести","Двухсот");
	ПадежРодительный.Вставить("Триста","Трехсот");
	ПадежРодительный.Вставить("Четыреста","Четырехсот");
	ПадежРодительный.Вставить("Пятьсот","Пятисот");
	ПадежРодительный.Вставить("Шестьсот","Шестисот");
	ПадежРодительный.Вставить("Семьсот","Семисот");
	ПадежРодительный.Вставить("Восемьсот","Восьмисот");
	ПадежРодительный.Вставить("Девятьсот","Девятисот");
	ПадежРодительный.Вставить("Тысяча","Тысячи");
	ПадежРодительный.Вставить("Одна","Одной");
    ПадежРодительный.Вставить("Две","Двух");
	ПадежРодительный.Вставить("Тысяч","Тысяч");
	ПадежРодительный.Вставить("Тысячи","Тысяч");


	МассивСлов = новый массив;
	готово = ложь;
	ПервоеСлово = Истина;
	НовоеСлово = "";
	Перваябуква = "";
	Вырезка= "";
	ВернутьОшибка = ЧислоПрописью;
	Пока НЕ Готово Цикл
		НайденноеЗначение = "";
		НайденныйПробел = Найти(ЧислоПрописью," ");
		Если НайденныйПробел = 0 Тогда
			Если ПервоеСлово Тогда
				Если ПадежРодительный.Свойство(ЧислоПрописью, НайденноеЗначение) Тогда
					Возврат НайденноеЗначение;
				Иначе
					Возврат ВернутьОшибка;
				КонецЕсли;
			Иначе
				Вырезка = СокрЛП(ЧислоПрописью);
				Перваябуква = Врег(ЛЕВ(Вырезка,1));
				ЧислоПрописью = Перваябуква + Прав(Вырезка,СтрДлина(Вырезка)-1);

				Если ПадежРодительный.Свойство(ЧислоПрописью, НайденноеЗначение) Тогда
					НайденноеЗначение = НРЕГ(НайденноеЗначение);
					НовоеСлово = НовоеСлово + НайденноеЗначение + " ";
					Возврат сОКРлп(НовоеСлово);
				Иначе
					Возврат ВернутьОшибка;
				КонецЕсли;

			КонецЕсли;
		Иначе
			Вырезка = СокрЛП(ЛЕВ(ЧислоПрописью,НайденныйПробел));
			Перваябуква = Врег(ЛЕВ(Вырезка,1));
			Вырезка = Перваябуква + Прав(Вырезка,СтрДлина(Вырезка)-1);
			Если ПадежРодительный.Свойство(Вырезка, НайденноеЗначение) Тогда
				Если ПервоеСлово Тогда
					НовоеСлово = НовоеСлово + НайденноеЗначение + " ";
					первоеСлово = Ложь;
					ЧислоПрописью = СокрЛП(Прав(ЧислоПрописью,СтрДлина(ЧислоПрописью)-НайденныйПробел));
				Иначе
					НовоеСлово = НовоеСлово + НРЕГ(НайденноеЗначение) + " ";
					ЧислоПрописью = СокрЛП(Прав(ЧислоПрописью,СтрДлина(ЧислоПрописью)-НайденныйПробел));

				КонецЕсли;
			Иначе
				Возврат ВернутьОшибка;
			КонецЕсли;
		КонецЕсли;
		
	КонецЦикла;
	
КонецФункции

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Михаил Зотов (ZOMI) 19.08.16 11:59
Уж если так важна каждая буковка в договоре - не быстрее ли договор поправить на "не позднее чем за 3(Три) дня" ?

2. Максим Умнов (maxvcb) 19.08.16 12:04
(1) ZOMI, мне не важна юристам важна. Меня попросили я сделал разговоры разговаривать не в моих правилах.
kuzyara; baracuda; +2 1 Ответить
3. Антонио (Fragster) 19.08.16 16:12
Есть хорошая универсальная штука (в договорах, например, еще есть пункты типа "в лице генерального директора, действующего на основании устава", где выделенные куски также должны браться из базы) http://infostart.ru/public/330103/
daMaster; klinval; premier; Uncore; ZOMI; +5 Ответить 2
4. Максим Умнов (maxvcb) 19.08.16 18:51
(3) Fragster, и? она числительные склоняет? к чему вот писать охинею? я выложил довольно таки простой код склонения числительных, мне зачем ваши фамилии? К чему вот это сообщение?
5. Максим Умнов (maxvcb) 19.08.16 18:55
(3) Fragster, склоняет таки, не посмотрел код сразу, приношу извинения. Ну дело то добровольное, у меня код по проще. Я выложил не хотите не берите че минусовать то.
6. Артано Майаров (Артано) 22.08.16 01:57
Я для данной задачи использовал типовую склонялку, склоняющую рубли. Просто вместо слова рубль используется день :-)
ARL; Uncore; +2 Ответить 2
7. Иван Петров (dgolovanov) 22.08.16 16:51
(5) maxvcb, слюнями много брызжете, вот и минусуют
8. Дмитрий Денисов (Uncore) 23.08.16 09:40
9. Максим Умнов (maxvcb) 23.08.16 13:23
(6) Артано, чет не понятно, тут склоняются не Дни а Числа.
10. Максим Умнов (maxvcb) 23.08.16 13:29
что за люди такие, пишут не в тему еще и минусы ставят. Любители покакать в коментариях
11. Артано Майаров (Артано) 24.08.16 07:12
(9) maxvcb, перечитайте еще раз моё сообщение и вы всё поймете. Если нет, то изучите имеющиеся механизмы склонения в типовых. Изобретать велосипеды может быть приятно, но смекалку и находчивость еще никто не отменял
12. Денис Лопато (Terve!R) 24.08.16 11:16
(11) ты бы еще склонять через morpher.ru предложил)
Если конфа на БСП, то конечно лучше разобраться и типовые функции склонения использовать. Но тут кажется весьма универсальный для данной задачи велосипед получился, пусть будет :)
13. Максим Умнов (maxvcb) 24.08.16 11:51
(11) Артано, перечитал, тут либо я дурак либо одно из двух.
Типовая склонялка это ЧислоПрописью(СрЭск,,",мр1,мр2,мр3,р,жр1,жр2,жр3,ж.0");
где мр и жр это варианты числа
типа рубля, рублей.Рублев
и выдает она
Семь тысяч Двести Тридцать ддва рубля, ты Ркбли поменял на дни иии?
Когда мой велосипед склоняет Семь тысяч Двести Тридцать ДВа в Семи тысяч Тридцати двух и по х** чего рублей дне колес насосов.
Ну и?
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа