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

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

В процессе разработки на платформе 1С:Предприятие 7.7 программисты часто сталкиваются с необходимостью обработки и сравнения текстовых данных. Типичный пример — импорт данных из XML или строка, в которой несколько значений записаны через точку с запятой, запятую или другой символ. Для эффективной работы с такими данными их нужно «разбить» на отдельные элементы и поместить в структуру, удобную для перебора (например, в СписокЗначений с выводом в отчет).

Рассмотрим подробнее несколько способов реализации этой задачи, разберем их преимущества и выясним, как правильно работать с результатами разделения.

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

Этот метод считается классическим для версии 7.7. Мы создадим функцию, которая в цикле ищет вхождение разделителя, «откусывает» часть строки до него и добавляет её в специальный объект СписокЗначений.

Проанализируем программный код такой функции:


Функция глРазложить(Знач Стр, Разделитель = ";") Экспорт
    СЗ = СоздатьОбъект("СписокЗначений");
    
    // Если разделитель — пробел, удалим лишние пробелы по краям
    Если Разделитель = " " Тогда
        Стр = СокрЛП(Стр);
    КонецЕсли;

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

Разберем, как работает этот алгоритм. Функция использует встроенную команду Найти, чтобы определить позицию разделителя. С помощью Лев мы получаем текст до разделителя, а с помощью Сред обновляем исходную строку, удаляя из неё уже обработанный фрагмент. Цикл продолжается до тех пор, пока функция Найти не вернет 0, что означает отсутствие разделителей в остатке строки.

Способ 2. Использование системной константы РазделительСтрок

Существует более изящный способ, который часто оказывается быстрее в написании и удобнее в отладке. Мы можем временно заменить наш разделитель (например, ;) на встроенный в 1С символ переноса строки. После этого 1С начнет воспринимать нашу строку как многострочный текст.

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

  1. Заменяем все вхождения символа ; на РазделительСтрок.
  2. Используем функцию СтрКоличествоСтрок, чтобы узнать, сколько фрагментов у нас получилось.
  3. В цикле получаем каждый фрагмент функцией СтрПолучитьСтроку.

Посмотрим на пример кода:


Процедура РазборСтрокиЧерезПеренос(ИсходнаяСтрока)
    // Заменяем ";" на системный разделитель
    ТекстСПереносами = СтрЗаменить(ИсходнаяСтрока, ";", РазделительСтрок);
    
    Колво = СтрКоличествоСтрок(ТекстСПереносами);
    
    Для Ном = 1 По Колво Цикл
        ТекущееЗначение = СтрПолучитьСтроку(ТекстСПереносами, Ном);
        // Здесь мы можем работать с каждым значением отдельно
        Сообщить("Элемент №" + Ном + ": " + ТекущееЗначение);
    КонецЦикла;
КонецПроцедуры

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

Способ 3. Быстрый метод ИзСтрокиСРазделителями

Объект СписокЗначений в 1С 7.7 обладает встроенным методом ИзСтрокиСРазделителями. Он работает очень быстро, так как реализован на уровне платформы, но имеет специфические требования к формату строки. Платформа ожидает, что элементы разделены запятыми, а значения, содержащие пробелы или спецсимволы, заключены в кавычки.

Если ваши данные — это набор цифр или простых кодов (как в примере 00114069;00114070), мы можем подготовить строку и использовать этот метод:


// Предположим, Стр = "00114069;00114070;00083046"
ПодготовленнаяСтр = СтрЗаменить(Стр, ";", ",");
СЗ = СоздатьОбъект("СписокЗначений");
СЗ.ИзСтрокиСРазделителями(ПодготовленнаяСтр);

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

Работа с результатом (СписокЗначений)

Часто начинающие разработчики успешно разделяют строку, но испытывают трудности с тем, как извлечь данные из полученного объекта СписокЗначений. Выясним, как правильно это сделать.

Предположим, мы использовали Способ 1 и получили объект СЗ. Чтобы перебрать все его элементы, нам нужно использовать цикл Для:


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

В этом примере функция РазмерСписка() возвращает общее количество элементов, а ПолучитьЗначение(Ном) извлекает конкретный элемент по его индексу (в 7.7 индексация списков начинается с 1).

Дополнительные возможности: Регулярные выражения

В сложных случаях, когда разделителей может быть несколько (например, и запятая, и точка с запятой одновременно), можно прибегнуть к помощи внешних объектов. В ОС Windows доступен объект VBScript.RegExp, который позволяет выполнять разделение строк (метод Split) по сложным правилам.

Рассмотрим пример подключения этого объекта:


RegExp = СоздатьОбъект("VBScript.RegExp");
RegExp.Global = Истина;
RegExp.IgnoreCase = Истина;
RegExp.Pattern = "[;|, ]"; // Разделители: точка с запятой, запятая или пробел
// Далее используется метод Replace для нормализации или Execute для поиска

Однако для большинства повседневных задач в 1С 7.7 достаточно первых двух способов. Метод с использованием РазделительСтрок является наиболее рекомендуемым благодаря своей простоте и отсутствию необходимости писать длинные функции разбора.

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

← На главную