Работа со строками в 1С:Предприятие — одна из самых частых задач при разработке отчетов, обработок и интеграций. Разделение строк на части (список значений, массив, таблицу) требуется при парсинге данных из файлов, обработке пользовательского ввода или разборе сложных форматированных текстов. В отличие от универсальных языков программирования, где для этого есть десятки методов, в 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. Разделение по нескольким разделителям
Если строка может содержать разные разделители (например, запятую или точку с запятой), стандартные функции не помогут. Решения:
- 🔧 Последовательная замена: заменить все разделители на один, затем применить
СтрРазделить():Строка = "a,b;c d";Строка = СтрЗаменить(Строка, ";", ",");
Строка = СтрЗаменить(Строка, " ", ",");
Массив = СтрРазделить(Строка, ",");
- 🔧 Регулярные выражения (требует подключения библиотеки 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, ДлинаЧасти));
КонецЦикла;
Почему СтрРазделить() возвращает массив с одним элементом, хотя разделитель есть в строке?
Проверьте:
- 🔍 Совпадает ли регистр разделителя (например,
"A,B"и разделитель","сработает, а";"— нет). - 🔍 Нет ли пробелов до/после разделителя (используйте
УдалятьПробелы = Истина). - 🔍 Не является ли разделитель частью многобайтового символа (например, в UTF-8).
Как разделить строку в запросе 1С (без использования встроенного языка)?
В языке запросов 1С нет прямого аналога СтрРазделить(), но можно:
- 📌 Использовать
ПОДСТРОКАс рекурсивными CTE (для СУБД, поддерживающих рекурсию). - 📌 Выгрузить данные во временную таблицу и обработать на встроенном языке.
- 📌 Для PostgreSQL использовать функцию
STRING_TO_ARRAYчерезВЫРАЗИТЬ.
Пример с рекурсией (для MS SQL):
ВЫБРАТЬ
ПОДСТРОКА(Строка, 1, ПОЗИЦИЯ(Разделитель В Строка + Разделитель) - 1) КАК Часть,
ОСТАТОК(Строка, ПОЗИЦИЯ(Разделитель В Строка + Разделитель)) КАК Остаток
ИЗ
(ВЫБРАТЬ "a,b,c" КАК Строка, "," КАК Разделитель) КАК Исходные
ГДЕ
Строка <> "";