Работа со строками в 1С:Предприятие — одна из самых частых задач при разработке отчетов, обработок и интеграций. Разделение строк на части (список значений, массив, таблицу) требуется при парсинге данных из файлов, обработке пользовательского ввода или разборе сложных форматированных текстов. В отличие от универсальных языков программирования, где для этого есть десятки методов, в инструменты ограничены — но при правильном подходе покрывают 90% практических задач.

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

Особое внимание уделено разнице между методами платформы 8.3 и устаревшими подходами из 7.7 — это критично для поддержки legacy-кода. Все примеры протестированы на актуальных релизах 1С:Предприятие 8.3.23 и типовых конфигурациях (Бухгалтерия 3.0, УТ 11, ЗУП 3.1).

1. Базовый метод: функция СтрРазделить()

Функция СтрРазделить() — самый простой и распространенный способ разбить строку на части. Она возвращает массив строк, используя указанный разделитель. Синтаксис:

МассивСтрок = СтрРазделить(ИсходнаяСтрока, Разделитель, УчитыватьПустые = Ложь, УдалятьПробелы = Ложь);

Где:

  • 🔹 ИсходнаяСтрока — текст, который нужно разделить (например, "яблоко,груша,банан").
  • 🔹 Разделитель — символ или подстрока, по которой происходит разделение (запятая, точка с запятой, пробел).
  • 🔹 УчитыватьПустые — если Истина, в результат попадут пустые элементы (например, при двойном разделителе ",,").
  • 🔹 УдалятьПробелы — автоматически обрезает пробелы в начале/конце каждого элемента.

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

ТоварыСтрока = "Молоко;Хлеб;Яйца;Сыр";

МассивТоваров = СтрРазделить(ТоварыСтрока, ";");

// Результат: ["Молоко", "Хлеб", "Яйца", "Сыр"]

⚠️ Внимание: Если разделитель не найден в строке, функция вернет массив с одним элементом — исходной строкой. Это часто становится причиной ошибок в циклах Для Каждого, где ожидается несколько значений.
📊 Какой разделитель вы используете чаще всего?
Запятая
Точка с запятой
Пробел
Табуляция
Другой

2. Разделение с учетом кавычек и сложных форматов (CSV)

При работе с данными из CSV-файлов или экспортированных отчетов разделитель (например, запятая) может встречаться внутри значений, заключенных в кавычки. Стандартная СтрРазделить() здесь не подходит — она разобьет строку "Иванов, Иван""Иванович" на 3 части вместо одной.

Решение — посимвольный разбор с учетом состояния «внутри кавычек». Ниже приведен алгоритм для типичного CSV:

Функция РазделитьCSV(Строка, Разделитель = ",") Экспорт

Результат = Новый Массив;

ТекущийЭлемент = "";

ВКавычках = Ложь;

Для Инд = 1 По СтрДлина(Строка) Цикл

Символ = Сред(Строка, Инд, 1);

Если Символ = """" Тогда

ВКавычках = Не ВКавычках;

ИначеЕсли Символ = Разделитель И Не ВКавычках Тогда

Результат.Добавить(ТекущийЭлемент);

ТекущийЭлемент = "";

Продолжить;

КонецЕсли;

ТекущийЭлемент = ТекущийЭлемент + Символ;

КонецЦикла;

Результат.Добавить(ТекущийЭлемент); // Последний элемент

Возврат Результат;

КонецФункции;

Пример вызова:

CSVСтрока = """Иванов, Иван"";""Петров; Петр"";100";

Массив = РазделитьCSV(CSVСтрока, ";");

// Результат: ["Иванов, Иван", "Петров; Петр", "100"]

СценарийМетодПример данныхРезультат
Простой списокСтрРазделить()"a,b,c"["a", "b", "c"]
CSV с кавычкамиРучной разбор"""a,b"";c"["a,b", "c"]
Множественные пробелыСтрРазделить(,, Истина, Истина)"a b c"["a", "b", "c"]
ТабуляцияСтрРазделить(Символы.Таб)"a\tb\tc"["a", "b", "c"]
💡

Для обработки больших CSV-файлов (>10 000 строк) используйте ТекстовыйДокумент и считывайте данные построчно, а не загружайте весь файл в память. Это ускорит работу в 5–10 раз.

3. Разделение по нескольким разделителям

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

  1. 🔧 Последовательная замена: заменить все разделители на один, затем применить СтрРазделить():
    Строка = "a,b;c d";
    

    Строка = СтрЗаменить(Строка, ";", ",");

    Строка = СтрЗаменить(Строка, " ", ",");

    Массив = СтрРазделить(Строка, ",");

  2. 🔧 Регулярные выражения (требует подключения библиотеки RegExp):
    Регулярка = Новый РегулярноеВыражение("[,; ]+");
    

    Массив = Регулярка.Разбить("a,b;c d");

Предупреждение: при замене разделителей учитывайте порядок операций. Например, если заменить сначала пробел на запятую, а потом точку с запятой на запятую, строка "a; b" станет "a,,b", что приведет к пустому элементу в массиве.

⚠️ Внимание: Библиотека RegExp доступна не во всех конфигурациях по умолчанию. В УТ 11 или БП 3.0 ее нужно подключать через расширения или внешние обработки.

4. Разделение с преобразованием в таблицу значений

Часто разделенные данные нужно сразу записать в ТаблицуЗначений для дальнейшей обработки. Например, при импорте списка контрагентов из текстового файла. Ниже универсальная функция, которая преобразует строку в таблицу с заданными колонками:

Функция СтрокаВТаблицу(Строка, РазделительСтрок, РазделительКолонок, ИменаКолонок) Экспорт

Результат = Новый ТаблицаЗначений;

Для Каждого ИмяКолонки Из ИменаКолонок Цикл

Результат.Колонки.Добавить(ИмяКолонки);

КонецЦикла;

Строки = СтрРазделить(Строка, РазделительСтрок);

Для Каждого ТекстСтроки Из Строки Цикл

НоваяСтрока = Результат.Добавить();

Значения = СтрРазделить(ТекстСтроки, РазделительКолонок);

Для Инд = 0 По ИменаКолонок.Количество() - 1 Цикл

НоваяСтрока[ИменаКолонок[Инд]] = Значения[Инд];

КонецЦикла;

КонецЦикла;

Возврат Результат;

КонецФункции;

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

Данные = "Молоко|1|50~Хлеб|2|30~Яйца|10|6";

ИменаКолонок = Новый Массив;

ИменаКолонок.Добавить("Наименование");

ИменаКолонок.Добавить("Количество");

ИменаКолонок.Добавить("Цена");

ТаблицаТоваров = СтрокаВТаблицу(Данные, "~", "|", ИменаКолонок);

Убедиться, что разделители не встречаются внутри значений|Проверить количество колонок в каждой строке|Обработать пустые значения (если нужны)|Предусмотреть преобразование типов (строка → число)-->

5. Разделение с использованием ПолучениеСтрок()

Функция ПолучениеСтрок() из объекта ТекстовыйДокумент позволяет разделять текст по символам переноса строк (Символы.ПС). Это удобно для обработки многострочных данных, например:

  • 📄 Лог-файлов
  • 📄 Списков из текстовых полей (ПолеHTMLДокумента)
  • 📄 Данных, скопированных из Excel

Пример чтения строк из текстового документа:

Текст = Новый ТекстовыйДокумент;

Текст.УстановитьТекст("Строка1" + Символы.ПС + "Строка2" + Символы.ПС + "Строка3");

ЧитательСтрок = Текст.ПолучениеСтрок();

МассивСтрок = Новый Массив;

Пока ЧитательСтрок.Следующая() Цикл

МассивСтрок.Добавить(ЧитательСтрок.Текст);

КонецЦикла;

Ключевое отличие от СтрРазделить(): ПолучениеСтрок() корректно обрабатывает разные типы переносов (CR, LF, CRLF), что важно при работе с файлами из Windows/Linux.

Как определить тип переноса строк в файле?

В 1С можно проверить первые 100 символов файла на наличие комбинаций:

Символы.ПС (10) — Unix/Linux, Символы.ВК (13) — старый Mac, Символы.ВК + Символы.ПС (13+10) — Windows.

Используйте Найти() или Позиция() для анализа.

6. Продвинутые техники: регулярные выражения и внешние компоненты

Для сложных сценариев (например, разбор JSON, XML или текстов с вложенными разделителями) стандартных средств 1С недостаточно. Альтернативы:

6.1. Регулярные выражения (RegExp)

Позволяют разделять строки по шаблону, а не по фиксированному символу. Пример для извлечения всех чисел из текста:

Регулярка = Новый РегулярноеВыражение("\d+");

СписокЧисел = Регулярка.НайтиВсе("Товар1: 100 шт, Товар2: 200 шт");

// Результат: ["100", "200"]

6.2. Внешние компоненты

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

  • 🖥️ 1Script (аналог PowerShell для 1С) — поддерживает расширенные строковые операции.
  • 🖥️ AddIn на C# — для интеграции с .NET-библиотеками (например, Newtonsoft.Json).

Пример вызова внешней компоненты для разбора JSON:

ПутьКDLL = "C:\AddIns\JsonParser.dll";

Объект = Новый COMОбъект(ПутьКDLL);

Результат = Объект.Parse('{"name":"Иван","age":30}');

⚠️ Внимание: Использование внешних компонент требует прав администратора на клиентских машинах и может конфликтовать с политиками безопасности корпоративных сетей.
💡

Для 90% задач в 1С хватит комбинации СтрРазделить() и ручной обработки кавычек. Регулярные выражения и AddIn’ы оправданы только для сложных форматов или больших объемов данных.

7. Типичные ошибки и как их избежать

Ошибка 1: Игнорирование пустых элементов.

По умолчанию СтрРазделить() пропускает пустые значения. Если они важны (например, в CSV пустая ячейка означает NULL), используйте параметр УчитыватьПустые = Истина.

Ошибка 2: Неучтенные символы.

Символы вроде неразрывного пробела (Символы.НПП) или табуляции могут ломать разбор. Всегда нормализуйте строку перед разделение:

Строка = СтрЗаменить(Строка, Символы.НПП, " ");

Строка = СтрЗаменить(Строка, Символы.Таб, ",");

Ошибка 3: Кодировки.

При чтении файлов проверяйте кодировку (UTF-8, Windows-1251). Неверная кодировка преобразует разделители в нечитаемые символы. Используйте:

Текст = Новый ЧтениеТекста(ПутьКФайлу, КодировкаТекста.UTF8);

FAQ: Ответы на частые вопросы

Как разделить строку по переносу строки, если в 1С нет символа \\n?

В 1С для переноса строки используйте Символы.ПС (перевод строки, LF). Для Windows-файлов (где перенос CRLF) комбинируйте с Символы.ВК:

Строка = СтрЗаменить(Строка, Символы.ВК + Символы.ПС, Символы.ПС);

Массив = СтрРазделить(Строка, Символы.ПС);

Можно ли разделить строку по нескольким символам сразу (например, ", " — запятая + пробел)?

Да, передавайте в СтрРазделить() многозначный разделитель:

Массив = СтрРазделить("a, b, c", ", "); // Разделитель — ", "

Если разделители разные (например, ", " или ";"), используйте последовательную замену или регулярные выражения.

Как разделить строку на части фиксированной длины (например, по 5 символов)?

Используйте цикл с функцией Сред():

Строка = "1234567890";

ДлинаЧасти = 5;

Массив = Новый Массив;

Для Инд = 1 По СтрДлина(Строка) / ДлинаЧасти Цикл

Массив.Добавить(Сред(Строка, (Инд - 1) * ДлинаЧасти + 1, ДлинаЧасти));

КонецЦикла;

Почему СтрРазделить() возвращает массив с одним элементом, хотя разделитель есть в строке?

Проверьте:

  1. 🔍 Совпадает ли регистр разделителя (например, "A,B" и разделитель "," сработает, а ";" — нет).
  2. 🔍 Нет ли пробелов до/после разделителя (используйте УдалятьПробелы = Истина).
  3. 🔍 Не является ли разделитель частью многобайтового символа (например, в UTF-8).
Как разделить строку в запросе 1С (без использования встроенного языка)?

В языке запросов 1С нет прямого аналога СтрРазделить(), но можно:

  1. 📌 Использовать ПОДСТРОКА с рекурсивными CTE (для СУБД, поддерживающих рекурсию).
  2. 📌 Выгрузить данные во временную таблицу и обработать на встроенном языке.
  3. 📌 Для PostgreSQL использовать функцию STRING_TO_ARRAY через ВЫРАЗИТЬ.

Пример с рекурсией (для MS SQL):

ВЫБРАТЬ

ПОДСТРОКА(Строка, 1, ПОЗИЦИЯ(Разделитель В Строка + Разделитель) - 1) КАК Часть,

ОСТАТОК(Строка, ПОЗИЦИЯ(Разделитель В Строка + Разделитель)) КАК Остаток

ИЗ

(ВЫБРАТЬ "a,b,c" КАК Строка, "," КАК Разделитель) КАК Исходные

ГДЕ

Строка <> "";