Как убрать лидирующие нули и префиксы в строке на платформе 1С 7.7

Программист 1С v7.7 1C:Бухгалтерия Бухгалтерский учет IT и автоматизация бизнеса
← На главную

При работе в программной среде 1С:Предприятие 7.7 разработчики регулярно сталкиваются с необходимостью форматирования номеров документов. Это требуется для вывода красивых номеров в печатных формах (счетах-фактурах, накладных), построения читаемых реестров или интеграции со сторонними информационными системами.

Типовые механизмы автонумерации платформы 1С 7.7 устроены так, что они дополняют номер лидирующими нулями для сохранения фиксированной длины строки (например, 00000124). Кроме того, в распределенных базах данных или крупных организациях часто используются буквенные префиксы (например, К0001571 или ГК00326). Бухгалтерам и внешним контрагентам такие громоздкие обозначения в печатных формах не нужны — им требуется видеть «чистый» номер.

В этой статье мы подробно разберем несколько эффективных способов решения этой задачи на платформе 1С 7.7: от классических циклов разбора строки до использования регулярных выражений и встроенных глобальных функций типовых конфигураций. Мы вместе проанализируем преимущества и недостатки каждого подхода, чтобы вы смогли выбрать оптимальный вариант для своей конфигурации.

Постановка задачи и тестовые примеры

Рассмотрим возможные варианты входящих строк, с которыми нам предстоит работать:

Наша цель — написать универсальный или специализированный алгоритм, который вернет очищенную строку, начинающуюся со значащей цифры (от 1 до 9).

Способ 1. Цикл с «откусыванием» левого символа через Лев и Сред

Давайте разберем классический алгоритм, который обсуждался разработчиками на форуме. Основная идея заключается в том, чтобы последовательно проверять первый символ строки слева. Если он не является значащей цифрой (то есть не входит в диапазон от "1" до "9"), мы его удаляем и переходим к следующему символу. Цикл продолжается до тех пор, пока первым символом строки не станет цифра от 1 до 9 или пока строка полностью не опустеет.

Посмотрим на практическую реализацию этого метода:


// Очищаем пробелы по краям строки
СтрокаНомера = СокрЛП(ТаблицаДекларации.НомерСчетаФактуры);

// Запускаем цикл проверки первого левого символа
Пока Найти("123456789", Лев(СтрокаНомера, 1)) = 0 Цикл
    // "Откусываем" первый символ слева, заменяя строку её частью со второго символа
    СтрокаНомера = Сред(СтрокаНомера, 2);
    
    // Предотвращаем бесконечный цикл в случае пустой строки или строки без цифр
    Если СтрДлина(СтрокаНомера) = 0 Тогда
        Прервать;
    КонецЕсли;
КонецЦикла;

Проанализируем детально, как работает этот код по шагам на примере строки ГК00326:

  1. На первой итерации функция Лев(СтрокаНомера, 1) возвращает букву Г. Функция Найти("123456789", "Г") возвращает 0, так как буквы Г нет в строке поиска. Условие цикла выполняется. Строка преобразуется в К00326 (символы со 2-го до конца).
  2. На второй итерации проверяется буква К. Найти снова возвращает 0. Строка сокращается до 00326.
  3. На третьей итерации проверяется символ 0. Он также отсутствует в поисковой строке "123456789". Результат Найти равен 0. Строка становится 0326.
  4. На четвертой итерации проверяется очередной 0. Строка усекается до 326.
  5. На пятой итерации Лев(СтрокаНомера, 1) возвращает 3. Функция Найти("123456789", "3") возвращает её позицию (равную 3), что не равно 0. Цикл завершается.

Этот метод полностью универсален для платформы 1С 7.7, так как использует самые базовые функции работы со строками, которые гарантированно доступны в любой конфигурации.

Способ 2. Оптимизированный цикл по кодам символов (ASCII)

Иногда операции со строками (такие как Найти) могут работать медленнее, чем прямое сравнение числовых кодов символов. Давайте рассмотрим альтернативный вариант решения, использующий функцию КодСимв. В кодовой таблице цифры от "1" до "9" идут последовательно и имеют коды от 49 до 57 соответственно.


СтрокаНомера = СокрЛП(ТаблицаДекларации.НомерСчетаФактуры);

// Будем убирать символы, пока код первого символа не попадет в диапазон [49; 57]
Пока (СтрДлина(СтрокаНомера) > 0) И ((КодСимв(Лев(СтрокаНомера, 1)) < 49) Или (КодСимв(Лев(СтрокаНомера, 1)) > 57)) Цикл
    СтрокаНомера = СокрЛП(Сред(СтрокаНомера, 2));
КонецЦикла;

Этот подход лаконичен и работает достаточно быстро, так как платформа сравнивает обычные целые числа вместо поиска одной строки внутри другой. Обратите внимание на важную деталь: мы добавили проверку СтрДлина(СтрокаНомера) > 0 непосредственно в условие цикла Пока, чтобы избежать критических ошибок при работе с пустыми значениями.

Способ 3. Использование встроенной глобальной функции конфигурации

Очень часто программисты 1С начинают изобретать собственные алгоритмы, забывая о том, что разработчики типовых решений (таких как «Бухгалтерский учет» или «Торговля и Склад» для 1С 7.7) уже заложили мощный инструментарий в Глобальный модуль. Рассмотрим функцию глПреобразоватьНомерДок.

Эта функция предназначена специально для форматирования номеров перед выводом на печать или использованием в отчетах. Она имеет следующую структуру вызова:


// Синтаксис: глПреобразоватьНомерДок(НомерДок, ВыводитьНули, ВыводитьПрефикс)
// Где:
// НомерДок - исходная строка номера
// ВыводитьНули - 1 (оставить нули) или 0 (убрать нули)
// ВыводитьПрефикс - 1 (оставить префикс) или 0 (убрать префикс)

СтрокаНомера = глПреобразоватьНомерДок(ТаблицаДекларации.НомерСчетаФактуры, 0, 0);

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

  1. Надежность: код протестирован тысячами внедрений и учитывает все особенности префиксов конкретной базы данных (включая многосимвольные префиксы и префиксы распределенных ИБ).
  2. Чистота кода: ваша обработка или отчет не загромождаются лишними циклами, программа становится более понятной для других разработчиков.

Способ 4. Использование регулярных выражений VBScript.RegExp (без циклов)

Если вам необходимо обрабатывать огромные массивы данных (например, десятки тысяч строк в таблице значений при формировании книги продаж или декларации), стандартные циклы 1С 7.7 могут вызвать заметные задержки интерфейса. В таких случаях на помощь приходит COM-технология и библиотека регулярных выражений Windows.

Давайте посмотрим, как решить задачу в несколько строк без единого цикла:


// Создаем объект для работы с регулярными выражениями
RegExp = СоздатьОбъект("VBScript.RegExp");
RegExp.IgnoreCase = Истина;
RegExp.Global = Истина;
RegExp.MultiLine = Ложь;

// Задаем шаблон поиска: находим все символы от начала строки (^),
// которые НЕ являются цифрами от 1 до 9 ([^1-9]+)
RegExp.Pattern = "^[^1-9]+"; 

// Производим замену найденного префикса на пустую строку
СтрокаНомера = RegExp.Replace(ТаблицаДекларации.НомерСчетаФактуры, "");

Давайте детально разберем регулярное выражение ^[^1-9]+:

Этот способ работает невероятно быстро, так как компиляция и выполнение регулярного выражения происходят на уровне оптимизированных системных библиотек Windows, минуя медленный интерпретатор встроенного языка 1С 7.7.

Способ 5. Лайфхак с двойной заменой символов (без букв)

Если у вас гарантированно отсутствуют буквенные префиксы, а нужно удалить только ведущие нули (например, из номера 00000104 получить 104), существует очень хитрый и красивый алгоритм, который не задействует циклы и внешние компоненты.

Давайте изучим этот изящный прием:


ИсходныйНомер = ТаблицаДекларации.НомерСчетаФактуры; // Пример: "00000104"

// Выполняем двойную замену с удалением пробелов слева
Результат = СтрЗаменить(СокрЛ(СтрЗаменить(ИсходныйНомер, "0", " ")), " ", "0");

Выясним причину работоспособности этого алгоритма по шагам:

  1. Внутренняя функция СтрЗаменить(ИсходныйНомер, "0", " ") заменяет все нули на пробелы. Строка 00000104 превращается в 1 4 (пять пробелов в начале, единица, пробел вместо внутреннего нуля, четверка).
  2. Функция СокрЛ удаляет все пробелы только с левой стороны строки. На выходе мы получаем строку 1 4. Заметьте, что пробел между единицей и четверкой остался нетронутым!
  3. Внешняя функция СтрЗаменить возвращает все пробелы обратно, превращая их в нули. На выходе получается чистый номер 104.

Важное ограничение: этот способ применим только тогда, когда в исходном номере не может быть законных пробелов (например, пробелов-разделителей серий или кодов подразделений), иначе они также будут ошибочно заменены на нули. Также он не очистит буквенные префиксы.

Способ 6. Прямое приведение типов для числовых строк

Напоследок рассмотрим самый простой способ, который подходит для элементарных ситуаций. Если номер состоит исключительно из цифр и лидирующих нулей (например, 00000124), самым быстрым решением будет его преобразование в число и обратно в строку:

СтрокаНомера = Строка(Число(ТаблицаДекларации.НомерСчетаФактуры));

При конвертации строки в число платформа 1С автоматически отбрасывает незначащие нули слева. Однако помните, что если в строке встретится буква (К0001571) или спецсимвол (0000012/2), этот метод выдаст ошибку преобразования типа или вернет неверный результат. Используйте его с большой осторожностью.

Сравнительный анализ и рекомендации

Давайте обобщим полученные знания в виде кратких рекомендаций:

← На главную