При выводе печатных форм первичных документов часто требуется отображать номер в привычном для контрагентов виде — без служебных префиксов информационных баз, префиксов организаций и длинных цепочек лидирующих нулей. Например, из внутреннего номера АВ С-0001206пр необходимо получить чистое числовое значение 1206.
Разберем, как решить эту задачу с помощью типовых механизмов платформы, а также проанализируем собственный алгоритм посимвольной очистки строки и подводные камни, возникающие при его реализации.
Если разработка ведется в современной типовой конфигурации на базе Библиотеки стандартных подсистем (БСП), писать собственные строковые парсеры не требуется. В составе БСП предусмотрен специализированный общий модуль ПрефиксацияОбъектовКлиентСервер.
Рассмотрим вызов базовой функции для формирования номера на печать:
НомерДокумента = ПрефиксацияОбъектовКлиентСервер.НомерНаПечать(Шапка.Номер, Истина, Истина);
Разберем параметры функции подробнее:
ОФ00-000452).Если требуется удалить только нули слева, но оставить префиксы, используем метод:
НомерБезНулей = ПрефиксацияОбъектовКлиентСервер.УдалитьЛидирующиеНулиИзНомераОбъекта(Шапка.Номер);
Если же необходимо централизованно изменить правила формирования печатного номера во всех документах конфигурации, переопределим процедуру ПриПолученииНомераНаПечать в модуле ПрефиксацияОбъектовКлиентСерверПереопределяемый. В ней можно задать глобальную обработку номера, установив параметр СтандартнаяОбработка = Ложь.
В более ранних конфигурациях (например, «1С:Бухгалтерия предприятия 8.2 ред. 2.0») аналогичную роль выполняла функция ОбщегоНазначения.ПолучитьНомерНаПечать(Шапка.Номер).
В нетиповых конфигурациях или внешних печатных формах, где нет доступа к БСП, номер можно обработать программно. Проанализируем задачу: нам нужно отсечь любые литеры слева и первые нули, но обязательно сохранить цифры внутри номера и цифры после них.
Выясним причину частой ошибки начинающих разработчиков: если просто удалять все нули до первой цифры без сохранения состояния, либо отбирать только ненулевые цифры, номер вида АВ С-0001206пр превратится в ошибочный 126, так как ноль между 2 и 6 будет проигнорирован.
Посмотрим на корректный алгоритм посимвольного обхода:
Функция ВыделитьНомер(СтрокаНомера) Экспорт
Результат = "";
Для Сч = 1 По СтрДлина(СтрокаНомера) Цикл
СимволТекущий = Сред(СтрокаНомера, Сч, 1);
Код = КодСимвола(СимволТекущий);
// Код 48 соответствует "0", коды от 49 до 57 — цифрам от "1" до "9"
Если (Код > 48 И Код < 58) ИЛИ (Код = 48 И Результат <> "") Тогда
Результат = Результат + СимволТекущий;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Разберем логику работы этого условия:
КодСимвола() возвращает числовой код символа в таблице ASCII. Код 48 соответствует нулю "0", код 57 — девятке "9"."0" (код 48), он добавится только в том случае, если в переменной Результат уже есть хотя бы одна цифра (Результат <> ""). Это гарантирует, что лидирующие нули отсекутся, а нули внутри числа (как в числе 1206) останутся на своем месте.При использовании строковых парсеров необходимо учитывать важные особенности учета и структуры данных:
000123/1). Алгоритм, извлекающий исключительно цифры, объединит дробь в сплошное число (1231), что недопустимо.Префикс-Номер (например, ТД-0000123), устойчивее всего отделить префикс с помощью функции СтрНайти(СтрокаНомера, "-"), взять правую подстроку и затем применить к ней преобразование типов или удаление лидирующих нулей.Для удобства повторного использования созданную функцию рекомендуется разместить в общем модуле с признаками Сервер и ВызовСервера или модуле клиент-серверной утилиты.