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

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

Как разложить строку по буквам в 1С

Как разложить строку по буквам в 1С: перебор символов через Сред(), работа с массивом, обработка кириллицы и типичные ошибки. Примеры кода для разработчика.

Задача разложить строку по буквам в 1С возникает регулярно: при проверке ИНН посимвольно, разборе артикулов, валидации введённых данных, преобразовании текста в транслит или поиске недопустимых символов. Во встроенном языке 1С нет отдельной функции «разбить строку на символы», как в некоторых других языках, поэтому задачу решают комбинацией функций работы со строками.

Основной инструмент — функция Сред(), которая извлекает подстроку заданной длины с указанной позиции. Если запрашивать по одному символу в цикле от первого до последнего, строка раскладывается на отдельные буквы. Дополнительно используются СтрДлина() для определения границ цикла и КодСимвола() для анализа символов на уровне кодов Unicode.

Ниже разобраны рабочие способы: классический цикл, разбор в массив и в таблицу значений, особенности кириллицы и спецсимволов, а также типичные ошибки, из-за которых код возвращает пустые значения или «мусор».

Базовый способ: цикл с функцией Сред()

Самый простой вариант — перебрать позиции от 1 до длины строки и на каждой итерации извлекать один символ. Функция Сред(Строка, НачальнаяПозиция, Длина) при длине 1 возвращает ровно одну букву.

Строка = "Привет";

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

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

Сообщить(Символ);

КонецЦикла;

В результате в окно сообщений последовательно выводятся «П», «р», «и», «в», «е», «т». Нумерация символов в 1С начинается с единицы, а не с нуля — это важно для тех, кто пришёл из других языков. Попытка обратиться к позиции 0 вернёт пустую строку без ошибки, что затрудняет поиск проблемы.

Если строка пустая, СтрДлина() вернёт 0, и цикл просто не выполнится — отдельная проверка не обязательна, но полезна для читаемости кода.

1c
Для Позиция = 1 По СтрДлина(Строка) Цикл
    Символ = Сред(Строка, Позиция, 1);
КонецЦикла;

Разложение строки в массив символов

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

Функция РазложитьСтрокуВМассив(Строка)

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

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

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

КонецЦикла;

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

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

Оформление разбора в отдельную функцию оправдано, если операция используется в нескольких местах модуля. Массив индексируется с нуля, поэтому первый символ строки окажется в элементе МассивСимволов[0] — не перепутайте с позициями в самой строке.

Для очень длинных строк (десятки тысяч символов) посимвольный разбор работает медленно из-за особенностей неизменяемости строк. Если нужно просто проверить вхождение символов, рассмотрите альтернативы: СтрНайти(), СтрЗаменить() или регулярные выражения через COM-объект VBScript.RegExp на Windows-сервере.

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

Если вместе с символом нужно хранить его позицию, код или признак (цифра, буква, разделитель), удобна таблица значений. Такой подход типичен при разборе штрихкодов и кодов маркировки.

ТаблицаСимволов = Новый ТаблицаЗначений;

ТаблицаСимволов.Колонки.Добавить("Позиция");

ТаблицаСимволов.Колонки.Добавить("Символ");

ТаблицаСимволов.Колонки.Добавить("КодСимвола");

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

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

НоваяСтрока = ТаблицаСимволов.Добавить();

НоваяСтрока.Позиция = Позиция;

НоваяСтрока.Символ = Символ;

НоваяСтрока.КодСимвола = КодСимвола(Символ);

КонецЦикла;

Колонку с кодом символа удобно использовать для классификации: цифры лежат в диапазоне кодов 48–57, латинские заглавные буквы — 65–90, строчные — 97–122. Это позволяет проверять строку на недопустимые символы без длинных перечислений.

Проверка символов: цифры, буквы, служебные знаки

Частая практическая цель разложения — проверить, состоит ли строка только из допустимых символов. Например, ИНН должен содержать только цифры, а в наименовании не должно быть управляющих символов.

Проверка на цифры

Функция ТолькоЦифры(Строка)

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

Код = КодСимвола(Строка, Позиция);

Если Код < 48 Или Код > 57 Тогда

Возврат Ложь;

КонецЕсли;

КонецЦикла;

Возврат Истина;

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

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

Поиск недопустимых символов

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

Допустимые = "0123456789АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ";

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

Символ = ВРег(Сред(Строка, Позиция, 1));

Если СтрНайти(Допустимые, Символ) = 0 Тогда

Сообщить("Недопустимый символ на позиции " + Позиция);

КонецЕсли;

КонецЦикла;

Маршрут решения

Как выбрать способ разбора

Нужно просто перебрать символы один разИспользуйте цикл с Сред(Строка, Позиция, 1)
Символы нужны многократно или в произвольном порядкеСложите их в массив через функцию-обёртку
Нужны позиции, коды или признаки символовИспользуйте таблицу значений с колонками
Нужно только проверить вхождение или заменитьОбойдитесь СтрНайти() или СтрЗаменить() без цикла

Особенности: пробелы, переносы строк и спецсимволы

При посимвольном разборе пробелы, табуляции и переносы строк тоже являются символами и попадают в результат. Если они мешают, предварительно обработайте строку: СокрЛП() убирает незначащие символы по краям, а СтрЗаменить(Строка, Символы.ПС, "") удаляет переносы строк.

Объект Символы содержит предопределённые значения: Символы.ПС (перевод строки), Символы.ВК (возврат каретки), Символы.Таб (табуляция), Символы.НПП (неразрывный пробел). Неразрывный пробел — частый источник ошибок: визуально он неотличим от обычного, но сравнение строк даёт Ложь. При разборе данных из Excel или веб-форм проверяйте код символа 160.

Обратная задача — собрать строку из символа по его коду — решается функцией Символ(Код). Например, Символ(1057) вернёт букву «С».

Типичные ошибки
01
Нумерация с нуля: Сред(Строка, 0, 1) возвращает пустую строку, позиции начинаются с 1
02
Игнорирование неразрывного пробела (код 160): строки визуально равны, но сравнение даёт Ложь
03
Посимвольный разбор строк в сотни тысяч символов без необходимости — сильная просадка производительности
04
Путаница диапазонов кодов: кириллица и латиница имеют разные коды, визуально похожие буквы (А/А) не равны
05
Изменение строки внутри цикла по её длине: границы цикла смещаются, символы пропускаются

Практический пример: транслитерация и подсчёт

Посимвольный разбор — основа транслитерации. Создаётся соответствие «русская буква → латинское написание», затем строка перебирается, и каждый символ заменяется:

Соответствие = Новый Соответствие;

Соответствие.Вставить("а", "a");

Соответствие.Вставить("б", "b");

// ... остальные буквы

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

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

Символ = НРег(Сред(Строка, Позиция, 1));

Замена = Соответствие.Получить(Символ);

Если Замена = Неопределено Тогда

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

Иначе

Результат = Результат + Замена;

КонецЕсли;

КонецЦикла;

Аналогично решается подсчёт количества вхождений конкретного символа, хотя для этой задачи короче использовать СтрЧислоВхождений(Строка, Символ) — встроенная функция работает быстрее ручного цикла.

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

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

Количество полученных символов
Норма

Равно СтрДлина() исходной строки

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

Меньше — пропущены позиции, больше — ошибка в границах цикла

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

Совпадают с началом и концом исходной строки

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

Пустые значения — сбита нумерация позиций

Сборка строки обратно
Норма

Конкатенация всех символов равна исходной строке

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

Расхождение — потеряны или изменены символы

Производительность и ограничения

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

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

Итог

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

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

Частые вопросы

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

Одной встроенной функции «строка в массив символов» в 1С нет. Функция СтрРазделить() раскладывает строку по разделителю, но не по символам. Без цикла не обойтись, однако его можно один раз оформить в общую функцию и вызывать где угодно.

Почему Сред(Строка, 0, 1) не выдаёт ошибку?

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

Как разложить строку с учётом регистра букв?

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

Как перебрать строку в обратном порядке?

Используйте цикл с шагом -1: Для Позиция = -СтрДлина(Строка) По -1 Цикл с обращением Сред(Строка, -Позиция, 1). Альтернатива — обычный цикл с вычислением позиции как СтрДлина(Строка) - Индекс + 1.

Чем отличается разбор строки от СтрРазделить()?

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

Как посчитать, сколько раз буква встречается в строке?

Проще всего встроенной функцией СтрЧислоВхождений(Строка, "а") — она вернёт количество вхождений без цикла. Посимвольный перебор со счётчиком тоже работает, но медленнее и длиннее в записи.