Как разделить строку на части по разделителю в 1С 7.7?

Программист 1С v7.7
← На главную

В процессе разработки на платформе 1С:Предприятие 7.7 часто возникает задача разбора текстовых строк, которые поступают из внешних источников или вводятся пользователями в одно поле через запятую. Типичный пример — паспортные данные, записанные одной строкой. Разберем подробно, какими способами можно «расщепить» такую строку на отдельные составляющие, чтобы затем использовать их в коде или записать в соответствующие реквизиты справочника.

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

Этот метод считается классическим «ручным» разбором. Он полезен, когда нам нужно быстро вытащить одно или два первых значения из строки, не создавая дополнительных объектов. Давайте проанализируем логику этого процесса. Для работы нам понадобятся функции Найти(), которая возвращает позицию символа в строке, и функции извлечения подстрок.

Рассмотрим пример, где в переменной ИсходнаяСтрока находятся данные вида: "паспорт, 0000, 000000". Разберем по шагам, как вытащить первый и второй элементы:


// Определяем позицию первой запятой
ПозицияЗапятой = Найти(ИсходнаяСтрока, ",");

// Извлекаем первый элемент (все, что левее запятой)
ВидДокумента = Лев(ИсходнаяСтрока, ПозицияЗапятой - 1);

// Получаем остаток строки, отрезая уже найденную часть
// Прибавляем 1 к позиции, чтобы пропустить саму запятую
ОстатокСтроки = Сред(ИсходнаяСтрока, ПозицияЗапятой + 1);

// Снова ищем запятую, но уже в остатке строки
ПозицияЗапятой = Найти(ОстатокСтроки, ",");
СерияПаспорта = Лев(ОстатокСтроки, ПозицияЗапятой - 1);

Важный нюанс: при таком подходе в переменные могут попасть лишние пробелы (например, если после запятой стоит пробел). Чтобы данные были «чистыми», всегда используйте функцию СокрЛП(). Это защитит вашу базу от хранения невидимых символов, которые могут помешать при последующем поиске или сравнении строк.

Способ 2: Универсальная функция разложения в Список Значений

Если строка содержит много элементов (как в случае с полными паспортными данными, включающими код подразделения и дату выдачи), ручной разбор становится громоздким. В типовых конфигурациях 7.7 часто встречается универсальная функция глРазложить. Проанализируем её алгоритм, так как это «золотой стандарт» для версии 7.7.

Эта функция циклично проходит по строке, отсекает куски по разделителю и складывает их в объект СписокЗначений. Рассмотрим её реализацию:


Функция глРазложить(Знач Стр, Разделитель = ",") Экспорт
    СЗ = СоздатьОбъект("СписокЗначений");
    
    // Если разделитель - пробел, используем специальную логику
    Если Разделитель = " " Тогда
        Стр = СокрЛП(Стр);
        Пока 1=1 Цикл
            Поз = Найти(Стр, Разделитель);
            Если Поз = 0 Тогда
                СЗ.ДобавитьЗначение(СокрЛП(Стр));
                Возврат СЗ;
            КонецЕсли;
            СЗ.ДобавитьЗначение(СокрЛП(Лев(Стр, Поз - 1)));
            Стр = СокрЛ(Сред(Стр, Поз));
        КонецЦикла;
    Иначе
        // Стандартный разбор для запятой или другого символа
        ДлинаРазделителя = СтрДлина(Разделитель);
        Пока 1=1 Цикл
            Поз = Найти(Стр, Разделитель);
            Если Поз = 0 Тогда
                // Если разделителей больше нет, добавляем остаток строки
                СЗ.ДобавитьЗначение(СокрЛП(Стр));
                Возврат СЗ;
            КонецЕсли;
            СЗ.ДобавитьЗначение(СокрЛП(Лев(Стр, Поз - 1)));
            Стр = Сред(Стр, Поз + ДлинаРазделителя);
        КонецЦикла;
    КонецЕсли;
КонецФункции

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


СтрокаДанных = "паспорт, 1234, 567890, 01.01.2000";
СписокЭлементов = глРазложить(СтрокаДанных, ",");

// Обращаемся к элементам по индексу (в 7.7 индексация с 1)
ТипДок = СписокЭлементов.ПолучитьЗначение(1);
Серия  = СписокЭлементов.ПолучитьЗначение(2);
Номер  = СписокЭлементов.ПолучитьЗначение(3);

Способ 3: Метод ИзСтрокиСРазделителями()

В объекте СписокЗначений существует встроенный метод ИзСтрокиСРазделителями(). На первый взгляд он кажется идеальным решением, но у него есть свои особенности. Рассмотрим их подробнее.

Этот метод изначально проектировался для работы с форматом CSV. Он ожидает, что элементы строки могут быть заключены в кавычки. Если ваша строка выглядит как "паспорт", "0000", "000000", метод сработает безупречно. Если же кавычек нет, он всё равно разделит строку по запятым, но может некорректно обработать сложные случаи с пробелами или специальными символами.

Пример использования:


СЗ = СоздатьОбъект("СписокЗначений");
СЗ.ИзСтрокиСРазделителями(ИсходнаяСтрока);
// Теперь СЗ заполнен значениями

Способ 4: Метод превращения в многострочную строку

Существует еще один «хитрый» способ, который часто используют опытные разработчики для сокращения кода. Мы можем временно заменить все разделители (запятые) на символы переноса строк, превратив обычную строку в многострочный текст. После этого мы можем обращаться к ней, используя встроенные функции работы с многострочным текстом.

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


// Заменяем запятую на символ разделителя строк
МногострочнаяСтрока = СтрЗаменить(ИсходнаяСтрока, ",", РазделительСтрок);

// Теперь мы можем узнать количество полученных частей
Колво = СтрКоличествоСтрок(МногострочнаяСтрока);

// И получить конкретную часть по номеру
Для Номер = 1 По Колво Цикл
    ТекЗначение = СокрЛП(СтрПолучитьСтроку(МногострочнаяСтрока, Номер));
    Сообщить("Часть " + Номер + ": " + ТекЗначение);
КонецЦикла;

Этот метод очень эффективен по скорости и не требует создания объекта СписокЗначений, если вам нужно просто перебрать элементы в цикле.

Рекомендации по безопасности данных

При автоматическом разборе паспортных данных крайне важно учитывать человеческий фактор. Проанализируем ситуацию: что если пользователь вместо точки в дате поставил запятую? Или ввел серию и номер без пробела? Рассмотрим несколько правил «хорошего тона» при написании парсера:

  1. Проверка на количество элементов: Всегда проверяйте, сколько частей получилось после разделения. Если вы ожидаете 6 частей (вид, серия, номер, дата, кем выдан, код), а получили 4 — выполнение кода лучше прервать и выдать предупреждение пользователю.
  2. Валидация типов: После разделения проверьте, что в поле «Дата» действительно находится дата (используйте функцию Дата()), а в номере — только цифры.
  3. Логирование: Если разбор идет в автоматическом режиме (например, при загрузке из файла), записывайте ошибки в текстовый лог, чтобы потом можно было найти «кривую» строку.

Выбор конкретного метода зависит от ваших задач. Если нужно разобрать одну строку один раз — достаточно функций Лев() и Найти(). Если в конфигурации планируется много подобных операций — лучше один раз добавить функцию глРазложить в глобальный модуль и использовать её повсеместно.

← На главную