К статье
Практический материал

Разработка и Конфигурация · 11 мин

1С: строка как массив символов — посимвольный обход и разбор

Как в 1С работать со строкой как с массивом символов: Сред(), СтрДлина(), СтрРазделить(), циклы посимвольного обхода и типичные ошибки разработчика.

Во встроенном языке 1С строка не является массивом символов в привычном смысле: к ней нельзя обратиться по индексу, как в C# или JavaScript (строка[5] не сработает). Однако посимвольный доступ вполне возможен — через функции Сред(), Лев(), Прав(), а полноценный массив символов или подстрок можно получить через СтрРазделить(). Понимание этих механизмов нужно при разборе артикулов, проверке ИНН посимвольно, обработке кодов маркировки, парсинге банковских выписок и других задачах, где формат строки фиксирован.

Строки в 1С неизменяемы: любая операция «изменения» строки на самом деле создаёт новую строку. Это важно учитывать при посимвольной сборке результата в цикле — наивная конкатенация Результат = Результат + Символ на больших объёмах работает медленно, и лучше собирать фрагменты в массив с последующей склейкой через СтрСоединить().

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

Как устроены строки в 1С и почему нет индексации

Тип «Строка» в 1С — примитивный неизменяемый тип. Платформа не предоставляет оператор квадратных скобок для строк, поэтому код вида Строка[3] вызовет ошибку компиляции. Вместо этого работа с позициями ведётся функциями, где нумерация символов начинается с единицы, а не с нуля — это частый источник ошибок у разработчиков, пришедших из других языков.

Длина строки определяется функцией СтрДлина(Строка). Пустая строка имеет длину 0, и любое обращение к позиции за её пределами через Сред() вернёт пустую строку без ошибки — это нужно учитывать при валидации.

Посимвольный обход строки через Сред()

Базовый приём — цикл от 1 до СтрДлина() с извлечением одного символа функцией Сред(Строка, Позиция, 1). Так решают задачи подсчёта цифр, фильтрации недопустимых символов, проверки контрольных разрядов.

Функция ОставитьТолькоЦифры(ИсходнаяСтрока)

Результат = "";

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

Символ = Сред(ИсходнаяСтрока, Позиция, 1);

Если СтрНайти("0123456789", Символ) > 0 Тогда

Результат = Результат + Символ;

КонецЕсли;

КонецЦикла;

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

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

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

1c
Символ = Сред(Строка, Позиция, 1); // символ на позиции, нумерация с 1

Получение массива символов

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

Функция СтрокаВМассивСимволов(Строка)

МассивСимволов = Новый Массив;

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

МассивСимволов.Добавить(Сред(Строка, Позиция, 1));

КонецЦикла;

Возврат МассивСимволов;

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

Второй путь — СтрРазделить(Строка, "") с пустой строкой-разделителем. В актуальных версиях платформы такой вызов возвращает массив отдельных символов. Поведение с пустым разделителем зависит от версии платформы и режима совместимости, поэтому перед использованием проверьте на тестовом примере именно вашу конфигурацию. Обратная операция — СтрСоединить(МассивСимволов, "") — собирает строку обратно.

Разбор строки на подстроки через СтрРазделить()

Когда строка содержит структурированные данные (ФИО через пробел, артикул через дефис, строка CSV), удобнее разбить её на массив подстрок, чем ходить посимвольно. Функция СтрРазделить(Строка, Разделитель, ВключатьПустые) возвращает массив частей.

Части = СтрРазделить("Иванов;Иван;Иванович", ";");

// Части[0] = "Иванов", Части[1] = "Иван", Части[2] = "Иванович"

Индексация массива — уже с нуля, в отличие от позиций в строке. Третий параметр управляет пустыми элементами: СтрРазделить("а;;б", ";", Истина) даст три элемента, включая пустой, а с Ложь — только два. Для разбора банковских и обменных форматов, где пустое поле значимо, всегда указывайте этот параметр явно.

Сравнение вариантов

Сред() в цикле

Универсальный посимвольный доступ, работает на любой версии платформы. Медленнее на очень длинных строках.

СтрРазделить() с разделителем

Быстрый разбор структурированных строк (CSV, ФИО, артикулы). Не подходит для посимвольного анализа без разделителя.

СтрРазделить() с пустым разделителем

Массив символов одной строкой кода. Зависит от версии платформы и режима совместимости — требует проверки.

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

Мощная проверка шаблонов, но работает только под Windows-клиентом и усложняет переносимость.

Проверка символов по категориям

Типовая задача — определить, является ли символ цифрой, буквой, разделителем. Встроенных функций «ЭтоЦифра» в языке нет, поэтому используют поиск в эталонной строке или сравнение кодов символов через КодСимвола().

Функция ЭтоЦифра(Символ)

Возврат СтрНайти("0123456789", Символ) > 0;

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

Функция ЭтоРусскаяБуква(Символ)

Код = КодСимвола(ВРег(Символ));

Возврат (Код >= 1040 И Код <= 1071) Или Код = 1025; // А-Я и Ё

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

Подход через КодСимвола() быстрее при массовых проверках и точнее контролирует диапазоны Unicode. Не забудьте про букву Ё (код 1025/1105) — она стоит вне основного диапазона А–Я, и её пропуск ломает валидацию ФИО и наименований.

Типичные ошибки
01
Индексация с нуля: Сред(Строка, 0, 1) вместо Сред(Строка, 1, 1) — потеря первого символа или пустой результат.
02
Конкатенация в длинном цикле: Результат = Результат + Символ на сотнях тысяч итераций даёт квадратичное замедление — собирайте части в массив и склеивайте СтрСоединить().
03
Игнорирование буквы Ё при проверке диапазона А–Я — валидация отклоняет корректные ФИО.
04
Выход за границы строки без проверки СтрДлина() — при разборе форматов фиксированной длины короткая строка молча даёт пустые значения.
05
Путаница индексов: позиции в строке с 1, индексы массива из СтрРазделить() с 0.

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

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

Когда посимвольного обхода не избежать (например, проверка контрольной цифры ИНН или штрихкода), соблюдайте правила: не изменяйте исходную строку внутри цикла, результат собирайте в массив, а не конкатенацией, а саму обработку больших объёмов выносите на сервер или во внешнюю компоненту. Для пакетной обработки сотен тысяч строк рассмотрите запросы и функции СКД вместо циклов в коде.

Порядок действий при посимвольном разборе
  1. 1
    Проверьте входную строку: не Неопределено, достаточная длина через СтрДлина().
  2. 2
    Сохраните длину в переменную, если строка может меняться в цикле.
  3. 3
    Организуйте цикл Для Позиция = 1 По Длина с извлечением Сред(Строка, Позиция, 1).
  4. 4
    Классифицируйте символ через СтрНайти() по эталону или КодСимвола().
  5. 5
    Результат накапливайте в массиве и склейте СтрСоединить() после цикла.
  6. 6
    Проверьте результат на граничных случаях: пустая строка, один символ, строка из одних разделителей.

Практические сценарии

Проверка контрольной цифры штрихкода EAN-13

Классическая посимвольная задача: цифры на нечётных позициях складываются с весом 1, на чётных — с весом 3, контрольная цифра дополняет сумму до кратного 10. Здесь без обхода позиций не обойтись — веса зависят от номера позиции.

Разбор кода маркировки «Честный знак»

Код маркировки содержит GTIN, серийный номер и криптохвост с разделителями GS (код 29). Разбор делается комбинированно: СтрРазделить() по символу Символ(29), затем извлечение полей фиксированной длины через Лев() и Сред().

Очистка телефона от форматирования

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

Контрольные точки

Как проверить результат

Первый и последний символ результата
Норма

Совпадают с ожидаемыми символами исходной строки

Тревожный признак

Сдвиг на один символ — ошибка в нумерации позиций

Обработка пустой строки
Норма

Функция возвращает пустую строку или 0 без ошибки

Тревожный признак

Исключение или обращение к несуществующему элементу массива

Строка из одного символа
Норма

Корректно обрабатывается граничный случай

Тревожный признак

Цикл не выполняется или выполняется дважды

Буквы Ё и ё в данных
Норма

Проходят валидацию как русские буквы

Тревожный признак

Отклоняются из-за проверки только диапазона А–Я

FAQ

Можно ли изменить один символ в строке по позиции?

Напрямую нет — строки неизменяемы. Соберите новую строку: НоваяСтрока = Лев(Строка, Поз - 1) + НовыйСимвол + Сред(Строка, Поз + 1). Для множественных замен преобразуйте строку в массив символов, измените элементы и склейте через СтрСоединить().

Почему Сред(Строка, 0, 1) не возвращает первый символ?

Нумерация позиций в строках 1С начинается с 1. Позиция 0 некорректна: в зависимости от контекста вы получите пустую строку или ошибку. Первый символ — это Сред(Строка, 1, 1) или Лев(Строка, 1).

Как быстро проверить, что строка состоит только из цифр?

Без цикла: сравните строку с результатом удаления цифр. Практичный приём — СтрДлина(Строка) = СтрДлина(СтрЗаменитьВсехЦифр) через последовательные СтрЗаменить, либо проверка СтрДлина(СокрЛП(Строка)) > 0 в сочетании с попыткой преобразования Число() внутри Попытка/Исключение для коротких значений.

Что быстрее: посимвольный цикл или СтрРазделить?

СтрРазделить() выполняется на уровне платформы и всегда быстрее интерпретируемого цикла. Если формат позволяет разбить строку разделителем — используйте его. Посимвольный обход оправдан только там, где логика зависит от позиции каждого символа (контрольные суммы, веса разрядов).

Как работать с символами Unicode вроде эмодзи или иероглифов?

СтрДлина() и Сред() в 1С оперируют кодовыми единицами UTF-16. Символы вне базовой многоязычной плоскости (большинство эмодзи) занимают две кодовые единицы, поэтому посимвольный обход может разрезать их пополам. Для обычных кириллических и латинских данных это не проблема, но при обработке произвольного пользовательского текста учитывайте ограничение.

Как перевести символ в код и обратно?

Функция КодСимвола(Символ) возвращает числовой код Unicode, обратная операция — Символ(Код). Это удобно для проверки диапазонов (цифры 48–57, заглавные русские буквы 1040–1071) и для работы со служебными символами вроде Символ(29) в кодах маркировки.

Итог

Что важно запомнить

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