Как получить количество месяцев из строки со стажем в 1С

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

В практике программирования на платформе 1С часто возникает задача парсинга (разбора) текстовых строк, которые генерируются системой автоматически. Типичный пример — получение количества месяцев из сформированной строки стажа сотрудника, например: "Стаж для больничного: 0г.9мес. 27д.". Несмотря на то что строка кажется простой, существует несколько подходов к решению этой задачи: от жесткого поиска подстрок до универсальных алгоритмов извлечения чисел. В этой статье мы подробно разберем каждый из них, проанализируем их преимущества и недостатки.

Способ 1: Использование функций СтрНайти и Сред

Этот метод является классическим и наиболее быстрым в исполнении, если формат строки строго фиксирован. Мы исходим из того, что количество месяцев всегда находится между обозначением года г. и обозначением месяцев мес..

Рассмотрим по шагам алгоритм реализации:

  1. Найдем позицию вхождения подстроки г..
  2. Найдем позицию вхождения подстроки мес..
  3. Вычислим длину подстроки, содержащей число месяцев.
  4. Извлечем эту подстроку и преобразуем ее в число.

Посмотрим на пример кода, реализующего данную логику:


Поз1 = СтрНайти(ИсходнаяСтрока, "г.");
Поз2 = СтрНайти(ИсходнаяСтрока, "мес.");
// Извлекаем текст между "г." (прибавляем 2 символа длины разделителя) и "мес."
ТекстМесяцев = Сред(ИсходнаяСтрока, Поз1 + 2, Поз2 - (Поз1 + 2));
КоличествоМесяцев = Число(СокрЛП(ТекстМесяцев));

Важное замечание: При использовании этого метода нужно быть внимательными с индексами. Если между "0г." и "9мес." нет пробелов или их количество меняется, функция СокрЛП поможет убрать лишние символы перед преобразованием в Число.

Способ 2: Использование функции СтрРазделить

Более современный и элегантный способ в платформе 1С 8.3 — это использование функции СтрРазделить. Этот метод позволяет разбить строку на массив подстрок, используя сразу несколько символов-разделителей. Это избавляет нас от необходимости высчитывать позиции символов вручную.

Проанализируем ситуацию: в строке "Стаж для больничного: 0г.9мес. 27д." полезные данные разделены символами :, г., мес. и д.. Если мы укажем их все как разделители, система вернет нам массив, содержащий только числа.


Разделители = ":,г.,мес.,д.";
МассивЧастей = СтрРазделить(ИсходнаяСтрока, Разделители, Ложь);

// В результате получим массив:
// МассивЧастей[0] = "Стаж для больничного"
// МассивЧастей[1] = " 0"
// МассивЧастей[2] = "9"
// МассивЧастей[3] = " 27"

Если МассивЧастей.Количество() >= 3 Тогда
    КоличествоМесяцев = Число(СокрЛП(МассивЧастей[2]));
КонецЕсли;

Этот метод гораздо устойчивее к изменению количества пробелов в строке, однако он все еще зависит от того, что порядок следования единиц измерения (годы, месяцы, дни) остается неизменным.

Способ 3: Универсальный алгоритм извлечения всех чисел

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

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


НоваяСтрока = "";
СтрВсеЧисла = "0123456789";
    
Для Сч = 1 По СтрДлина(ИсходнаяСтрока) Цикл
    Символ = Сред(ИсходнаяСтрока, Сч, 1);
    Если СтрНайти(СтрВсеЧисла, Символ) = 0 Тогда
        // Если символ не является цифрой, заменяем его на пробел
        Символ = " ";
    КонецЕсли;     
    НоваяСтрока = НоваяСтрока + Символ;
КонецЦикла;  
    
// Теперь у нас есть строка вида "                      0 9  27 "
МассивЧисел = СтрРазделить(НоваяСтрока, " ", Ложь); 

// МассивЧисел будет содержать ["0", "9", "27"]
Если МассивЧисел.Количество() > 1 Тогда
    Результат = Число(МассивЧисел[1]); // Получаем второе число (месяцы)
КонецЕсли;

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

Способ 4: Регулярные выражения (RegExp)

Для тех, кто ищет наиболее лаконичное и профессиональное решение, стоит рассмотреть использование объекта VBScript.RegExp. Регулярные выражения позволяют найти число, которое стоит непосредственно перед текстом "мес".

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


RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.IgnoreCase = Истина;
RegExp.Global = Истина;
RegExp.MultiLine = Истина;

// Шаблон ищет цифры, после которых идет "мес"
RegExp.Pattern = "(\d+)\s*мес";

Matches = RegExp.Execute(ИсходнаяСтрока);
Если Matches.Count > 0 Тогда
    КоличествоМесяцев = Число(Matches.Item(0).SubMatches.Item(0));
КонецЕсли;

Важный нюанс: Использование COM-объектов возможно только на Windows-серверах и в толстом/тонком клиенте под Windows. Если ваш код выполняется на сервере под управлением Linux, этот метод работать не будет.

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

Если вы работаете в конфигурации 1С:Зарплата и Управление Персоналом (ЗУП 3.1) или 1С:ERP, важно помнить, что строка стажа — это лишь визуальное представление данных. Программисту правильнее работать не с текстом, а с исходными данными или типовыми функциями конфигурации.

В типовых решениях для подобных задач часто используется общий модуль ЗарплатаКадрыОбщиеАлгоритмы. Вместо того чтобы парсить строку "0г.9мес. 27д.", рассмотрите возможность вызова процедур, которые рассчитывают стаж на определенную дату. Система вернет вам структуру с полями Лет, Месяцев и Дней, что на 100% исключит ошибки парсинга текста.

Резюме

Мы проанализировали различные подходы к извлечению количества месяцев из строки. Подведем итоги:

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

← На главную