0. bad_boys 11 22.06.16 11:44 Сейчас в теме

Простой способ убрать префикс и лидирующие нули из номера

Статья в которой описан, простой способ убрать префикс и лидирующие нули из номера документа.

Перейти к публикации

Комментарии
Избранное Подписка Сортировка: Древо
1. aleksey2 77 22.06.16 21:09 Сейчас в теме
2. Yashazz 2840 23.06.16 00:37 Сейчас в теме
Забавно. Буквально вчера решал эту общеизвестную задачку и думал, как бы поэффективнее. Способ замен, конечно, тоже рассматривал, но... Автор, простите, а если номер "00012034", что будет? Верно, лажа будет. Вот если использовать Лев(,1) и Прав(,1) или новомодные СтрНачинаетсяС и СтрЗаканчиваетсяНа, тогда ещё куда ни шло. А так явный минус.

Ну и вообще, кажется мне, что не самый это изящный и быстрый способ.
optnpk; klinval; ardn; shalimski; +4 Ответить
5. bad_boys 23.06.16 10:16 Сейчас в теме
(2) Yashazz, функции СтрНачинаетсяС и СтрЗаканчиваетсяНа не на всех релизах конфигурации работают...
Если номер документа "00012034" после обработки станет "12034", что вполне корректно..
13. Yashazz 2840 23.06.16 19:38 Сейчас в теме
(5) не релизах конфигурации, а релизах платформы. Не ниже 8.3.7, ну я и написал, что "новомодные")

Хожу второй день и пытаюсь решить задачу в духе работ Ильдаровича. Чтобы стильно и извратно)))
15. v3rter 24.06.16 09:36 Сейчас в теме
(13) Yashazz, Подкину для вдохновения https://meduza.io/shapito/2016/06/21/politehnicheskiy-muzey-nauchilsya-svorachivat-artema-chayku-v-lsdu3 , политота, конечно, но алгоритм многообещающий )
3. alex-l19041 8 23.06.16 09:44 Сейчас в теме
а зачем изобретать "велосипед", если можно вызвать готовую функцию общего модуля ОбщегоНазначения.ПолучитьНомерНаПечать(документ);
temdj; mark_oilbass; synelf; BIT_vnedr; vadimlp77; vovan_victory; eksdak; +7 Ответить
4. bad_boys 23.06.16 10:14 Сейчас в теме
(3) alex-l19041, ОбщегоНазначения.ПолучитьНомерНаПечать(документ) удаляет только ПрефиксПодразделения или ПрефиксИнформационнойБазы... Если вручную бухгалтер поменял префикс на какой захотел, он не удалится стандартной функцией.
6. c300pm 23.06.16 10:57 Сейчас в теме
в БП 3.0 с нумерацией типа ААББ-000001 корректно работает?
7. bad_boys 11 23.06.16 11:02 Сейчас в теме
(6) c300pm, не могу сказать не проверял на БП 3.0...
Тем не менее была просьба доработать такой механизм для печати, поскольку стандартный не отрабатывал...
Какая конфигурация и какой релиз уже не помню...
Мой способ не является эталоном, но как мне кажется имеет право на жизнь))
8. 1С_Мастер 65 23.06.16 11:07 Сейчас в теме
Очевидно, что это вариант не сработает с номером АА-123, так как в нем ни одного нуля нет. Или, например, с номером АА-101 сработает неверно, оставив от него только 1
Alex17; klinval; +2 Ответить
10. bad_boys 11 23.06.16 11:17 Сейчас в теме
(8) 1С_Мастер, да на Ваших примерах работать не будет(((
9. v3rter 23.06.16 11:11 Сейчас в теме
Думаю, более правильно будет просматривать посимвольно справа налево до первой не цифры, затем полученную подстроку чистить от ведущих нулей, например так Строка(Число("0"+ПромежуточнаяПодстрока))
bad_boys; +1 Ответить
11. bad_boys 11 23.06.16 11:18 Сейчас в теме
(9) v3rter, согласен Ваш вариант более коректный чем мой....
12. v3rter 23.06.16 11:25 Сейчас в теме
Хотя есть альтернативный способ - выкинуть из номера все нецифровые символы, затем ведущие нули. Недостаток: кривые номера типа Н1АБ0000021 превратятся в 10000021, а не в 21. Такие "чудо-номера" бывают от кривых префиксов при обмене.
14. Yashazz 2840 24.06.16 09:29 Сейчас в теме
Если исходить из того, что все нецифровые префиксы уже отброшены, то самое топорное решение это Формат(Число(Номер)).
16. Ovrfox 14 24.06.16 09:48 Сейчас в теме
Вот простой код, который сработает, если номер содержит число.
Функция ТолькоНомер(ВхНомер)
	Рез = СокрЛП(ВхНомер);
	Ном = СтрДлина(Рез);
	Пока Ном > 0 Цикл
		Если Найти("0123456789", Сред(Рез,Ном,1))=0 Тогда
			прервать;
		Иначе
			Ном = Ном - 1;
		КонецЕсли; 
	КонецЦикла; 
	Возврат ""+Число(Сред(Рез,Ном+1));
КонецФункции
Показать
19. v3rter 24.06.16 12:51 Сейчас в теме
Как всегда шедевры. Математики поймут )

Попробую расшифровать для тех, кому лень разбираться.

Первая функция: рекурсивно проверяются символы справа налево до первой не цифры,
затем происходит возврат правой части строки по накопленному значению К;
( КодСимвола() / 5 - 10.5 ) возвращает значение от -0,9 до 0,9 для символов с "0" до "9",
Цел() отсекает дробную часть, в результате для цифр получится 0, для остальных символов не ноль;
?(Цел(КодСимвола(Прав("!" + Стр, К + 1)) / 5 - 10.5),<не цифра>,<цифра>) базируется на особенности преобразования нуля в булево ложь, а "!" + Стр - подстраховка от пустой строки на входе.

Вторая функция: все числа заменяются пробелами "матрёшкой" вложенных функций
СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(Номер
, "0", " "), "1", " "), "2", " "), "3", " "), "4", " "), "5", " "), "6", " "), "7", " "), "8", " "), "9", " ")
СокрП отсекает пробелы справа, остаток замереятся через СтрДлина и вырезается часть с середины до конца с позиции +1, где должны начинаться цифры.

Формат( , "ЧГ=") в обоих случаях убирает разделители разрядов при обратном преобразовании числа в текст, потом что через Строка() "формируется ... полное представление в стандартном виде, соответствующем национальным установкам". Или как у Ovrfox в (16) вместо Формат(, "ЧГ=") можно попробовать неявное преобразование в строку ""+Число(
Ovrfox; region.eburg; +2 Ответить
17. likelol.91 24.06.16 09:49 Сейчас в теме
у меня во всех базах так:
Формат(Число(Прав(Номер,7)),"ЧГ=0")
18. ildarovich 6714 24.06.16 11:54 Сейчас в теме
Вот еще варианты:
Функция ЧислоСправа(Стр, К = 0)
	Возврат ?(Цел(КодСимвола(Прав("!" + Стр, К + 1)) / 5 - 10.5), Формат(Число("0" + Прав(Стр, К)), "ЧГ="), ЧислоСправа(Стр, К + 1))
КонецФункции

Функция ЧислоСправа1(Номер)
	Возврат Формат(Число("0" + Сред(Номер, СтрДлина(СокрП(
	СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(СтрЗаменить(Номер
	, "0", " "), "1", " "), "2", " "), "3", " "), "4", " "), "5", " "), "6", " "), "7", " "), "8", " "), "9", " "))) + 1)), "ЧГ=")
КонецФункции
dgolovanov; bad_boys; region.eburg; v3rter; +4 1 Ответить
22. m..adm 189 29.06.16 15:17 Сейчас в теме
(18) ildarovich, Код должен быть читабелен, чтобы не ломать голову в рекурсиях.
20. NoMax 232 27.06.16 00:12 Сейчас в теме
21. v3rter 27.06.16 09:15 Сейчас в теме
(20) NoMax,
Было еще на клюшках http://infostart.ru/public/57242/

Было, да сплыло - нет больше этой ссылки. И вот что там было:
Функция ClearZero(PERNR)  экспорт
Воз = PERNR;
апр=СтрДлина(Воз);
Для АНК = 1 По апр Цикл
аст = Сред(Воз, АНК);
Если Лев(аст, 1) <> "0" Тогда
Воз = Сред(Воз, АНК );
Возврат Воз;
КонецЕсли;
КонецЦикла;
КонецФункции
//В модуле формы ищем поля для которых нужно применить функцию.
//К примеру нужно чтобы поле  НомерДокумента = Докум.НомерДок; печаталось без нулей,
//заменяем на   НомерДокумента = ClearZero(Докум.НомерДок);
Показать

То есть убираются только ведущие нули, на номерах с префиксами не сработает.
23. m..adm 189 29.06.16 15:52 Сейчас в теме
я бы так отсеивал лишние нули
	НовыйНомер = "";
	Начнем = Ложь;
	Для Ном = 1 По СтрДлина(Номер) Цикл
		тКод 	 = КодСимвола(Номер,Ном);
		ЭтоЧисло = тКод > 47 И тКод < 58; //цифры от 0 до 9
		Начнем 	 = Начнем ИЛИ ЭтоЧисло И НЕ тКод = 48;
		Если Начнем И ЭтоЧисло Тогда 
			НовыйНомер = НовыйНомер + Сред(Номер,Ном,1);
		КонецЕсли;
	КонецЦикла;
Показать
v3rter; bad_boys; +2 Ответить
24. v3rter 29.06.16 17:16 Сейчас в теме
(23) m..adm, Кстати, это способ, упомянутый в (12), в целом годный, хороший с единственным недостатком
кривые номера типа Н1АБ0000021 превратятся в 10000021, а не в 21
25. vadim1011985 70 29.06.16 17:45 Сейчас в теме
Решил и я предложить свой вариант

Процедура Команда1(Команда)
	
	НомерНаПечать = ПолучитьНомерНаПечать(Объект.Номер);
	
	Объект.Номер = НомерНаПечать;
	
КонецПроцедуры

Функция ПолучитьНомерНаПечать (Номер) 
	
	Пока СтрДлина(Номер)>0 Цикл 
		
		Попытка 
			
			НомерНаПечать = Строка(Число(Номер));
			
			Возврат НомерНаПечать;
			
		Исключение
			//Если СтрДлина > 0 Тогда
			Номер = Прав(номер,СтрДлина(Номер)-1);
                      //  Иначе
                     //   Возврат 0;
                    //    конецЕсли; 
	
	      //  Продолжить;
			
		КонецПопытки;	
			
		КонецЦикла;

Возврат  "";
		
КонецФункции
Показать
26. v3rter 30.06.16 09:50 Сейчас в теме
(25) vadim1011985, тоже хороший способ. На случай кривых номеров я бы сделал Возврат "________"; чтобы была возможность вписать номер вручную не перепечатывая документ повторно.
27. Ovrfox 14 30.06.16 10:48 Сейчас в теме
(25) Вы меня мзвините, но этот код не годится.
Пример Номер А24.0000147. Правильно вернуть 147, а не 24.0000147
28. vadim1011985 70 30.06.16 11:10 Сейчас в теме
(27) Ovrfox, согласен, есть такое , но опять же можно использовать функцию СтрЗаменить где поменять точки и запятые на какой-нибудь символ. А вообще можно придумать такой пример который с предельной функцией не будет работать

Процедура Команда1(Команда)
    
    НомерНаПечать = ПолучитьНомерНаПечать(Объект.Номер);
    
    Объект.Номер = НомерНаПечать;
    
КонецПроцедуры

Функция ПолучитьНомерНаПечать (Номер) 
    
Номер = СтрЗаменить(Номер,".","@");
Номер = СтрЗаменить(Номер,",","@");

 

    Пока СтрДлина(Номер)>0 Цикл 
        
        Попытка 
            
            НомерНаПечать = Строка(Число(Номер));
            
            Возврат НомерНаПечать;
            
        Исключение
            //Если СтрДлина > 0 Тогда
            Номер = Прав(номер,СтрДлина(Номер)-1);
                      //  Иначе
                     //   Возврат 0;
                    //    конецЕсли; 
    
          //  Продолжить;
            
        КонецПопытки;    
            
        КонецЦикла;

Возврат  "______________";
        
КонецФункции
Показать
29. v3rter 30.06.16 11:40 Сейчас в теме
(27) Ovrfox, а так?
НомерНаПечать = Строка(Цел(Число(Номер)));
30. vadim1011985 70 30.06.16 11:50 Сейчас в теме
(29) v3rter, так вернет 24.

Ovrfox прав , нужно заменять "." и "," то есть знаки которые могу повлиять на формирование числа
31. v3rter 30.06.16 12:06 Сейчас в теме
Получаются два основных подхода:
1. число справа
2. все нецифровые символы удаляются, оставшиеся цифровые склеиваются
И куча промежуточных вариантов, когда нецифровые последовательности символов в номере переносятся, объединяются, заменяются на точки-прочерки-тире и т.д.
32. dakork 14 05.08.17 13:20 Сейчас в теме
Попробуйте типовой механизм (БП 3.0) ПрефиксацияОбъектовКлиентСервер.ПолучитьНомерНаПечать(НомерОбъекта, УдалитьПрефиксИнформационнойБазы, УдалитьПользовательскийПрефикс) По умолчанию УдалитьПрефиксИнформационнойБазы = Ложь, УдалитьПользовательскийПрефикс = Ложь
33. lda0312 15.11.18 11:01 Сейчас в теме
НомерБезПрефикса = Объект.ВходящийНомер;
Пока Найти(НомерБезПрефикса,"0") <> 1 Цикл
НомерБезПрефикса = Сред(НомерБезПрефикса,2); //удаляет лидирующие ненули
КонецЦикла;

Опасный код. Если в номере не будет нуля то попадаешь в вечный цикл.
34. user633533_encantado 4 15.11.18 11:06 Сейчас в теме
Статья ради статьи: как пользоваться функцией "Найти", которая , кстати, устарела.
35. Simonov_NPM 05.06.19 07:02 Сейчас в теме
Пока Лев(Номер, 1)="0" Цикл
Номер = Сред(Номер, 2);
КонецЦикла;
36. user679305_admn.nns 01.09.19 15:12 Сейчас в теме
Мой вариант:

Функция УдалитьЛидирующиеНули(Знач Номер)
Пока Лев(Номер,1) = "0" Цикл
Длина = СтрДлина(Номер);
Номер = Прав(Номер,Длина-1);
КонецЦикла;
Возврат Номер;
КонецФункции
37. user679305_admn.nns 01.09.19 15:15 Сейчас в теме
Если длина префикса известна, а во всех стандартных конфигурациях она равна 5, тогда

Функция УдалитьПрефикс(Знач Номер)
Длина = СтрДлина(Номер);
Номер = Прав(Номер,Длина-ДлинаПрефикса);
Возврат Номер;
КонецФункции
Оставьте свое сообщение
Новые вопросы с вознаграждением
Автор темы объявил вознаграждение за найденный ответ, его получит тот, кто первый поможет автору.

Вакансии

Ведущий программист 1С
Санкт-Петербург
зарплата от 130 000 руб.
Полный день

Программист 1С
Москва
зарплата от 130 000 руб. до 200 000 руб.
Полный день

Бизнес-архитектор 1С, ведущий консультант
Санкт-Петербург
Полный день

Руководитель проектов 1С
Санкт-Петербург
Полный день

Программист 1C
Москва
зарплата от 100 000 руб. до 150 000 руб.
Полный день