Как заменить все буквы в начале номера документа на одну цифру в 1С?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

В процессе разработки и поддержки конфигураций 1С программисты часто сталкиваются с необходимостью нормализации или изменения номеров документов для печатных форм, отчетов или выгрузок. Типичная задача — заменить буквенный префикс в начале номера документа (который может состоять из различного количества символов, например, "А", "ПВМ", "ГГ") на одну фиксированную цифру, например, "9".

Сложность этой задачи заключается в том, что длина буквенной части заранее неизвестна, а новые префиксы могут добавляться в систему пользователями без ведома разработчика. Простой перебор всех возможных комбинаций букв через функцию СтрЗаменить крайне неэффективен и усложняет поддержку кода. В этой статье мы подробно рассмотрим и проанализируем различные способы решения этой задачи — от простых циклов до использования регулярных выражений и встроенных функций платформы.

Постановка задачи

Допустим, у нас есть номера документов следующего вида:

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

---

Вариант 1. Посимвольный обход строки (Универсальный метод)

Рассмотрим классический алгоритм, который будет гарантированно работать на любой версии платформы 1С (начиная с 7.7 и заканчивая самыми свежими релизами 8.3), независимо от используемого режима совместимости. Идея заключается в том, чтобы перебрать все символы строки и отделить цифры от букв.

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


НовыйНомер = "";
Для Счетчик = 1 По СтрДлина(Объект.Номер) Цикл
    Символ = Сред(Объект.Номер, Счетчик, 1);
    Если Символ = "1" или Символ = "2" или Символ = "3" или Символ = "4" или Символ = "5" или Символ = "6" или Символ = "7" или Символ = "8" или Символ = "9" или Символ = "0" Тогда
        НовыйНомер = НовыйНомер + Символ;
    КонецЕсли;
КонецЦикла;
НовыйНомер = "9" + НовыйНомер;
Сообщить(НовыйНомер);

Анализ метода: Этот код прекрасно справляется с очисткой номера от любых букв, однако у него есть существенный недостаток. Он удаляет абсолютно все буквы и спецсимволы (например, дефисы или косую черту) по всей длине строки, а не только в начале. Если исходный номер имел вид "ПВМ123-45", то на выходе мы получим "912345", потеряв важный разделитель внутри номера. Кроме того, перебор строки в цикле по одному символу может работать медленно на очень больших объемах данных.

---

Вариант 2. Использование функции СтрРазделить (Для современных платформ)

Если ваша база данных работает на платформе 1С:Предприятие 8.3.10 и выше, и у вас отключен режим совместимости со старыми версиями, вы можете использовать мощную встроенную функцию СтрРазделить.

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


лкНомер = "ПМЗ12345";
лкЧасти = СтрРазделить(лкНомер, "0123456789", Ложь);
Если лкЧасти.Количество() > 0 Тогда
    // Заменяем только найденную в начале буквенную часть на "9"
    лкНомер = СтрЗаменить(лкНомер, лкЧасти[0], "9");
КонецЕсли;
Сообщить(лкНомер);

Важное примечание: Если при выполнении этого кода вы получаете ошибку "Процедура или функция с указанным именем не определена (СтрРазделить)", это означает, что в вашей конфигурации установлен режим совместимости с версией ниже 8.3.10 (например, база работает в режиме совместимости с 8.2 или используется старый толстый клиент). В таком случае данный метод запустить не удастся без изменения настроек конфигурации.

---

Вариант 3. Оптимальный алгоритм на чистом 1С через коды символов

Для того чтобы обойти ограничения совместимости старых платформ и при этом не сломать структуру номера (сохранив внутренние дефисы и пробелы), проанализируем подход с использованием функции КодСимвола. Цифровые символы от "0" до "9" в таблице ASCII имеют коды с 48 по 57. Мы можем найти первый символ, являющийся цифрой, и отрезать все, что находится левее него.

Разберем этот алгоритм подробнее:


ИсходныйНомер = СокрЛП(ДанныеДляПечати.Номер);
ИндексПервойЦифры = 0;

// Определяем позицию, с которой начинается цифровая часть
Для Счетчик = 1 По СтрДлина(ИсходныйНомер) Цикл
    КодСимвола = КодСимвола(ИсходныйНомер, Счетчик);
    Если КодСимвола >= 48 И КодСимвола <= 57 Тогда
        ИндексПервойЦифры = Счетчик;
        Прервать; // Выходим из цикла, как только встретили первую цифру
    КонецЕсли;
КонецЦикла;

Если ИндексПервойЦифры > 0 Тогда
    // Отрезаем буквенный префикс и подставляем "9"
    НовыйНомер = "9" + Сред(ИсходныйНомер, ИндексПервойЦифры);
Иначе
    // Если в номере вообще не оказалось цифр
    НовыйНомер = "9";
КонецЕсли;

Сообщить(НовыйНомер);

Преимущества данного решения:

  1. Работает абсолютно на любой версии платформы 1С.
  2. Не зависит от режима совместимости конфигурации.
  3. Корректно обрабатывает любые буквенные префиксы произвольной длины (русские, латинские буквы, знаки подчеркивания).
  4. Не удаляет разделители (например, дефисы "-") внутри цифровой части номера.

---

Вариант 4. Использование регулярных выражений (RegExp)

Если база данных работает под управлением операционной системы Windows, отличным и элегантным решением будет использование COM-объекта регулярных выражений. Этот способ позволяет избежать циклов и написать решение буквально в несколько строк.

Посмотрим на пример реализации:


РегВыражение = Новый COMОбъект("VBScript.RegExp");
РегВыражение.Pattern = "^\D+"; // Шаблон означает: найти любые НЕ-цифры в начале строки
РегВыражение.IgnoreCase = Истина;
РегВыражение.Global = Ложь;

ИсходныйНомер = СокрЛП(ДанныеДляПечати.Номер);
НовыйНомер = РегВыражение.Replace(ИсходныйНомер, "9");

Сообщить(НовыйНомер);

Этот способ работает быстро, надежно и избавляет разработчика от необходимости писать сложные циклы обхода строк. Однако помните, что COM-объекты не будут работать на серверах под управлением ОС Linux или в некоторых облачных сервисах (например, 1С:Fresh) из-за соображений безопасности.

---

Резюме и рекомендации

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

← На главную