1с убрать лидирующие нули в номере

Обновлено: 07.07.2024

Большинство хороших программистов делают свою работу не потому, что ожидают оплаты или признания, а потому что получают удовольствие от программирования (Linus Torvalds).

пятница, 17 января 2014 г.

Убрать лидирующие нули из номера документа

Убрать лидирующие нули из номера документа может нам понадобиться в том случае, если мы, к примеру, формируем печатную форму и номер нужно привести к нормальному виду, не показывая лидирующие нули и префикс документа. Для этого можно воспользоваться готовой процедурой, которая преобразовывает номер к нужному нам виду. Содержится она в общем модуле ОбщегоНазначения:

Если Документ = Неопределено Тогда
Возврат 0 ;
КонецЕсли;

Номер = СокрЛП ( Документ . Номер );

Если ПечатьПрефиксовРИБ Тогда
МассивПрефиксовРИБ = ПолучитьМассивПрефиксовРИБ ();
КонецЕсли;

Если МассивПрефиксов = Неопределено Тогда

Организация = Документ . Организация ;

Организация = Документ . Организация ;

Для Каждого ТекущийПрефикс ИЗ МассивПрефиксовДляОбхода Цикл

// удаление префикса из номера документа
Если Найти ( Номер , ТекущийПрефикс )= 1 Тогда
Номер = Сред ( Номер , СтрДлина ( ТекущийПрефикс )+ 1 );
КонецЕсли;

УдалитьПрефиксОбособленногоПодразделенияИзНомера ( Документ , МетаданныеДокумента , Номер );

1с убрать лидирующие нули в номере
Программирование системы 1с убрать лидирующие нули в номере
07.12.2017 13:52 1с убрать лидирующие нули в номере
1230

Допустим необходимо, чтобы из числа 3 получалось 00003, из 356 получалось 00356 и так далее.

Для этого можно использовать функцию Формат().

Здесь в форматной строке указано три параметра:

Для составления форматной строки можно использовать конструктор форматной строки.

Подробнее о функции Формат() можно почитать в синтакс-помощнике:

Часто возникает необходимость вывести в печатную форму номер документа без префикса и лидирующих нулей.

Для этого можно воспользоватся маленькой обработкой прикрепленной к статьи или использовать ниже приведенный код.

НомерБезНулей = НомерБезПрефикса ;
Пока Найти ( НомерБезНулей ,"0") = 1 Цикл
НомерБезНулей = Сред( НомерБезНулей , 2 ); //удаляет лидирующие нули
КонецЦикла;
Объект . ОбработанныйНомер = НомерБезНулей ;

Специальные предложения

Electronic Software Distribution

Интеграция 1С с системой Меркурий

Алкогольная декларация

Готовые переносы данных

54-ФЗ

Управление проектом на Инфостарте

Траектория обучения 1С-разработчика

Забавно. Буквально вчера решал эту общеизвестную задачку и думал, как бы поэффективнее. Способ замен, конечно, тоже рассматривал, но. Автор, простите, а если номер "00012034", что будет? Верно, лажа будет. Вот если использовать Лев(,1) и Прав(,1) или новомодные СтрНачинаетсяС и СтрЗаканчиваетсяНа, тогда ещё куда ни шло. А так явный минус.

Ну и вообще, кажется мне, что не самый это изящный и быстрый способ.

(2) Yashazz, функции СтрНачинаетсяС и СтрЗаканчиваетсяНа не на всех релизах конфигурации работают.
Если номер документа "00012034" после обработки станет "12034", что вполне корректно..

(5) не релизах конфигурации, а релизах платформы. Не ниже 8.3.7, ну я и написал, что "новомодные")

Хожу второй день и пытаюсь решить задачу в духе работ Ильдаровича. Чтобы стильно и извратно)))

а зачем изобретать "велосипед", если можно вызвать готовую функцию общего модуля ОбщегоНазначения.ПолучитьНомерНаПечать(документ); KDZorkov; intelligentvadik; zoikins; unduty; wolfsoft; Eillecho; user598655_ilia-bers; timurkhann; TManukovskaya; temdj; mark_oilbass; synelf; BIT_vnedr; vadimlp77; vovan_victory; eksdak; + 16 – Ответить (3) alex-l19041, ОбщегоНазначения.ПолучитьНомерНаПечать(документ) удаляет только ПрефиксПодразделения или ПрефиксИнформационнойБазы. Если вручную бухгалтер поменял префикс на какой захотел, он не удалится стандартной функцией. (4) ОбщегоНазначения.ПолучитьНомерНаПечать если её вызывать в цикле и много документов, то она очень медленно работает. в БП 3.0 с нумерацией типа ААББ-000001 корректно работает? (6) c300pm, не могу сказать не проверял на БП 3.0.
Тем не менее была просьба доработать такой механизм для печати, поскольку стандартный не отрабатывал.
Какая конфигурация и какой релиз уже не помню.
Мой способ не является эталоном, но как мне кажется имеет право на жизнь)) Очевидно, что это вариант не сработает с номером АА-123, так как в нем ни одного нуля нет. Или, например, с номером АА-101 сработает неверно, оставив от него только 1 Думаю, более правильно будет просматривать посимвольно справа налево до первой не цифры, затем полученную подстроку чистить от ведущих нулей, например так Строка(Число("0"+ПромежуточнаяПодстрока)) (9) v3rter, согласен Ваш вариант более коректный чем мой. Хотя есть альтернативный способ - выкинуть из номера все нецифровые символы, затем ведущие нули. Недостаток: кривые номера типа Н1АБ0000021 превратятся в 10000021, а не в 21. Такие "чудо-номера" бывают от кривых префиксов при обмене. Если исходить из того, что все нецифровые префиксы уже отброшены, то самое топорное решение это Формат(Число(Номер)). Вот простой код, который сработает, если номер содержит число.

Как всегда шедевры. Математики поймут )

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

Первая функция: рекурсивно проверяются символы справа налево до первой не цифры,
затем происходит возврат правой части строки по накопленному значению К;
( КодСимвола() / 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) вместо Формат(, "ЧГ=") можно попробовать неявное преобразование в строку ""+Число(

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

Забавно. Буквально вчера решал эту общеизвестную задачку и думал, как бы поэффективнее. Способ замен, конечно, тоже рассматривал, но. Автор, простите, а если номер "00012034", что будет? Верно, лажа будет. Вот если использовать Лев(,1) и Прав(,1) или новомодные СтрНачинаетсяС и СтрЗаканчиваетсяНа, тогда ещё куда ни шло. А так явный минус.

Ну и вообще, кажется мне, что не самый это изящный и быстрый способ.

(2) Yashazz, функции СтрНачинаетсяС и СтрЗаканчиваетсяНа не на всех релизах конфигурации работают.
Если номер документа "00012034" после обработки станет "12034", что вполне корректно..

(5) не релизах конфигурации, а релизах платформы. Не ниже 8.3.7, ну я и написал, что "новомодные")

Хожу второй день и пытаюсь решить задачу в духе работ Ильдаровича. Чтобы стильно и извратно)))

а зачем изобретать "велосипед", если можно вызвать готовую функцию общего модуля ОбщегоНазначения.ПолучитьНомерНаПечать(документ); KDZorkov; intelligentvadik; zoikins; unduty; wolfsoft; Eillecho; user598655_ilia-bers; timurkhann; TManukovskaya; temdj; mark_oilbass; synelf; BIT_vnedr; vadimlp77; vovan_victory; eksdak; + 16 – Ответить (3) alex-l19041, ОбщегоНазначения.ПолучитьНомерНаПечать(документ) удаляет только ПрефиксПодразделения или ПрефиксИнформационнойБазы. Если вручную бухгалтер поменял префикс на какой захотел, он не удалится стандартной функцией. (4) ОбщегоНазначения.ПолучитьНомерНаПечать если её вызывать в цикле и много документов, то она очень медленно работает. в БП 3.0 с нумерацией типа ААББ-000001 корректно работает? (6) c300pm, не могу сказать не проверял на БП 3.0.
Тем не менее была просьба доработать такой механизм для печати, поскольку стандартный не отрабатывал.
Какая конфигурация и какой релиз уже не помню.
Мой способ не является эталоном, но как мне кажется имеет право на жизнь)) Очевидно, что это вариант не сработает с номером АА-123, так как в нем ни одного нуля нет. Или, например, с номером АА-101 сработает неверно, оставив от него только 1 Думаю, более правильно будет просматривать посимвольно справа налево до первой не цифры, затем полученную подстроку чистить от ведущих нулей, например так Строка(Число("0"+ПромежуточнаяПодстрока)) (9) v3rter, согласен Ваш вариант более коректный чем мой. Хотя есть альтернативный способ - выкинуть из номера все нецифровые символы, затем ведущие нули. Недостаток: кривые номера типа Н1АБ0000021 превратятся в 10000021, а не в 21. Такие "чудо-номера" бывают от кривых префиксов при обмене. Если исходить из того, что все нецифровые префиксы уже отброшены, то самое топорное решение это Формат(Число(Номер)). Вот простой код, который сработает, если номер содержит число.

Как всегда шедевры. Математики поймут )

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

Первая функция: рекурсивно проверяются символы справа налево до первой не цифры,
затем происходит возврат правой части строки по накопленному значению К;
( КодСимвола() / 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) вместо Формат(, "ЧГ=") можно попробовать неявное преобразование в строку ""+Число(

(49) Там ничего про НПП нет. НПП может быть в строке, Формат преобразовывает строку?
Как написать "Сумма 1<НПП>520<НПП>руб." без НПП через формат?

(51) Если не читая вопрос - то лучше держать при себе)

(52) Предлагаешь в какой-то типовой изучить километры кода вместо написания 3-х строк?
Даже этот пост оказалось читать дольше, чем написать все варианты кода из этой ветки. И, самое главное, зачем? Зачем это читать, если можно это написать
(13) вот это странное в комментарии:
// это для контроля Строка 0 и число О тракутются при сравнении по разному, но код символа у них один
(57) основную прибыль 1Снику приносит работа с типовыми, так что привыкайте к размеру кода в типовых, что еще могу сказать. фирма 1С принимает односторонние решения.

Пользуй на здоровье.

(60) ну да, давайте лепить на каждую мелочь вызов COMОбъекта + такой код неработоспособен не в Windows или есть сервак на Linux'е.
(61) Для линухи тоже можно написать без проблем, но будем откровенны - 1С под линухой стоит у 0,005% всех пользоателей.
(62) а вот это интересно. вообще хорошо бы если бы 1С запилил поддержку RegExp в 1С.
(63) вот недавно у меня как раз был такой случай.
(64) ну вообще шикарно.
(66) Стрелять надо за подобную китайскую грамоту в таких задачах. А других - в 1С и нет.
Станет код "Х00000000209/кр117", и как дорабатывать, чтоб "Х" тоже убирал? А я отвечу - стереть нахрен это варварство и вписать добрый, понятный и уютный овно-код
(67) зато четко по ТЗ в заголовке)
все способы решения давно известны, это лишь еще один, не претендующий на универсальность, а лишь на изящество. может быть кто-то откроет для себя replace, уже хорошо
(68) Согласен! Но без комментариев, этот код - трэш, не более.
(67),(70) поддержу всех кто использует регулярки - если знаешь их, то жить порой становится гораздо проще, чем писать простыню овно-кода
и никакой это не треш, а комментировать - да! надо!
(71) Простыни написаны в 1С, которые кто-то выше предлагал найти и ж0стко заюзать. У нас код - три строки. В (66) - тоже 3 строки, но без обфускатора, дешифратора и хард-хасп-старфорс-а - не разобраться.
Тема сисек не раскрыта, щетаю.

(72) а я "щетаю" что если прог не знает регулярок ему же хуже.

просто я вспоминаю свои простыни кода с мильеном "если найти() тогда" и всякими там лев/прав/сред (и не важно где это было паскаль/делфи/си/эксель/1С ) везде кода много было

спустя годы, когда с регулярками освоился, понимаю какой же я тогда был. не важно кто :) и понимаю, что те задачи решались бы гораздо быстрее и приятнее

могу сказать, что для себя вывел "постулат" - если речь идет о поиске и модификации строк - только регулярки, хотя СтрЗаменить() и Найти() тоже испульзую, не перегибая палку с регэкспами
короче: регэкспы рулят, пипл, учите эту матчасть! чтоб легче жилось

(71) В пункте (2) весь код уместился в одну строку. Просто, походу, мало кто понимает как это работает, хотя, если разобраться, то код в (2) весьма даже красив.

+(74) Хотя, если написать код в понятном виде, то тоже будет три строки, то бишь, вариант:

Большинство хороших программистов делают свою работу не потому, что ожидают оплаты или признания, а потому что получают удовольствие от программирования (Linus Torvalds).

пятница, 17 января 2014 г.

Убрать лидирующие нули из номера документа

Убрать лидирующие нули из номера документа может нам понадобиться в том случае, если мы, к примеру, формируем печатную форму и номер нужно привести к нормальному виду, не показывая лидирующие нули и префикс документа. Для этого можно воспользоваться готовой процедурой, которая преобразовывает номер к нужному нам виду. Содержится она в общем модуле ОбщегоНазначения:

// Процедура предназначена для преобразования номера документа.
//
// Параметры:
// Документ - (ДокументСсылка), документ, чей номер надо получить для печати.
//
// Возвращаемое значение.
// Строка - номер документа для печати
//
Функция ПолучитьНомерНаПечать ( Документ , МассивПрефиксов = Неопределено, ПечатьПрефиксовРИБ = Истина) Экспорт

Если Документ = Неопределено Тогда
Возврат 0 ;
КонецЕсли;

ПечатьПрефиксовРИБ = ОбщегоНазначения . ПолучитьЗначениеПеременной ( "ПечатьПрефиксаРИБ" ) И ПечатьПрефиксовРИБ ;

Номер = СокрЛП ( Документ . Номер );

Если ТипЗнч ( Документ ) <> Тип ( "ВыборкаИзРезультатаЗапроса" )
И ТипЗнч ( Документ ) <> Тип ( "Структура" ) Тогда

Если ПечатьПрефиксовРИБ Тогда
МассивПрефиксовРИБ = ПолучитьМассивПрефиксовРИБ ();
КонецЕсли;

Если МассивПрефиксов = Неопределено Тогда

Если ТипЗнч ( Документ ) = Тип ( "ВыборкаИзРезультатаЗапроса" )
ИЛИ ТипЗнч ( Документ ) = Тип ( "Структура" ) Тогда

Организация = Документ . Организация ;

Если МетаданныеДокумента . Реквизиты . Найти ( "Организация" ) <> Неопределено Тогда

Организация = Документ . Организация ;

Если МетаданныеДокумента . Имя = "Доверенность" Тогда
ПрефиксДоверенности = "Д" ;
КонецЕсли;

Если ПечатьПрефиксовРИБ Тогда
// если печатаем префиксы РИБ в документах - не добавляем их в массив удаляемых префиксов
МассивПрефиксовДляОбхода = СформироватьМассивПрефиксовПоОрганизации ( Организация );
Иначе
МассивПрефиксовДляОбхода = СформироватьМассивПрефиксовДляРИБИОрганизации ( Организация );
КонецЕсли;

Если ПечатьПрефиксовРИБ Тогда
// если печатаем префиксы РИБ в документах - не добавляем их в массив удаляемых префиксов
Для Каждого ПрефиксИзМассива Из МассивПрефиксов Цикл
Если МассивПрефиксовРИБ . Найти ( ПрефиксИзМассива ) = Неопределено
И МассивПрефиксовДляОбхода . Найти ( ПрефиксИзМассива ) = Неопределено Тогда
МассивПрефиксовДляОбхода . Добавить ( ПрефиксИзМассива );
КонецЕсли;
КонецЦикла;
Иначе
МассивПрефиксовДляОбхода = МассивПрефиксов ;
КонецЕсли;

ПрефиксРИБ = "" ;
Если ПечатьПрефиксовРИБ Тогда
// определим, какие префиксы РИБ следует выводить на печать и удалим эти префиксы из номера
Для Каждого ПрефиксРИБИзМассива Из МассивПрефиксовРИБ Цикл
Если Найти ( Номер , ПрефиксРИБИзМассива ) = 1 Тогда
Номер = Сред ( Номер , СтрДлина ( ПрефиксРИБИзМассива ) + 1 );
ПрефиксРИБ = ПрефиксРИБ + ПрефиксРИБИзМассива ;
КонецЕсли;
КонецЦикла;
КонецЕсли;

Если ПрефиксДоверенности <> "" Тогда
МассивПрефиксовДляОбхода . Добавить ( ПрефиксДоверенности );
КонецЕсли;


Если НЕ МетаданныеДокумента = Неопределено Тогда
Если МетаданныеДокумента . Имя = "НалоговаяНакладная"
ИЛИ МетаданныеДокумента . Имя = "Приложение2КНалоговойНакладной" Тогда
ТекМесяц = '20000101' ;
Для Инд = 1 По 12 Цикл
МассивПрефиксовДляОбхода . Добавить ( "Н" + ПолучитьМесячныйПрефиксНалоговыхДокументов ( ТекМесяц ));
МассивПрефиксовДляОбхода . Добавить ( "П" + ПолучитьМесячныйПрефиксНалоговыхДокументов ( ТекМесяц ));
ТекМесяц = ДобавитьМесяц ( ТекМесяц , 1 );
КонецЦикла;
ТекМесяц = '20000101' ;
Для Инд = 1 По 12 Цикл
МассивПрефиксовДляОбхода . Добавить ( ПолучитьМесячныйПрефиксНалоговыхДокументов ( ТекМесяц ));
ТекМесяц = ДобавитьМесяц ( ТекМесяц , 1 );
КонецЦикла;
МассивПрефиксовДляОбхода . Добавить ( "Н" );
МассивПрефиксовДляОбхода . Добавить ( "П" );
МассивПрефиксовДляОбхода . Добавить ( "U" );
МассивПрефиксовДляОбхода . Добавить ( "V" );
МассивПрефиксовДляОбхода . Добавить ( "W" );


Для Каждого ТекущийПрефикс ИЗ МассивПрефиксовДляОбхода Цикл

// удаление префикса из номера документа
Если Найти ( Номер , ТекущийПрефикс )= 1 Тогда
Номер = Сред ( Номер , СтрДлина ( ТекущийПрефикс )+ 1 );
КонецЕсли;

// так же, может остаться "минус" впереди
Если Лев ( Номер , 1 ) = "-" Тогда
Номер = Сред ( Номер , 2 );
КонецЕсли;

// удаление ведущих нулей
Пока Лев ( Номер , 1 )= "0" Цикл
Номер = Сред ( Номер , 2 );
КонецЦикла;
КонецЦикла;

УдалитьПрефиксОбособленногоПодразделенияИзНомера ( Документ , МетаданныеДокумента , Номер );

Если ПечатьПрефиксовРИБ И ПрефиксРИБ <> "" Тогда
Номер = ПрефиксРИБ + Номер ;
КонецЕсли;

Читайте также: