Разработка и Конфигурация · 10 мин
Как разложить строку по буквам в 1С
Как разложить строку по буквам в 1С: перебор символов через Сред(), работа с массивом, обработка кириллицы и типичные ошибки. Примеры кода для разработчика.
Задача разложить строку по буквам в 1С возникает регулярно: при проверке ИНН посимвольно, разборе артикулов, валидации введённых данных, преобразовании текста в транслит или поиске недопустимых символов. Во встроенном языке 1С нет отдельной функции «разбить строку на символы», как в некоторых других языках, поэтому задачу решают комбинацией функций работы со строками.
Основной инструмент — функция Сред(), которая извлекает подстроку заданной длины с указанной позиции. Если запрашивать по одному символу в цикле от первого до последнего, строка раскладывается на отдельные буквы. Дополнительно используются СтрДлина() для определения границ цикла и КодСимвола() для анализа символов на уровне кодов Unicode.
Ниже разобраны рабочие способы: классический цикл, разбор в массив и в таблицу значений, особенности кириллицы и спецсимволов, а также типичные ошибки, из-за которых код возвращает пустые значения или «мусор».
Базовый способ: цикл с функцией Сред()
Самый простой вариант — перебрать позиции от 1 до длины строки и на каждой итерации извлекать один символ. Функция Сред(Строка, НачальнаяПозиция, Длина) при длине 1 возвращает ровно одну букву.
Строка = "Привет";
Для Позиция = 1 По СтрДлина(Строка) Цикл
Символ = Сред(Строка, Позиция, 1);
Сообщить(Символ);
КонецЦикла;
В результате в окно сообщений последовательно выводятся «П», «р», «и», «в», «е», «т». Нумерация символов в 1С начинается с единицы, а не с нуля — это важно для тех, кто пришёл из других языков. Попытка обратиться к позиции 0 вернёт пустую строку без ошибки, что затрудняет поиск проблемы.
Если строка пустая, СтрДлина() вернёт 0, и цикл просто не выполнится — отдельная проверка не обязательна, но полезна для читаемости кода.
Для Позиция = 1 По СтрДлина(Строка) Цикл
Символ = Сред(Строка, Позиция, 1);
КонецЦикла;Разложение строки в массив символов
Когда символы нужны не один раз, а многократно — например, для подсчёта статистики или многопроходного анализа — удобнее один раз сложить их в массив и дальше работать с ним.
Функция РазложитьСтрокуВМассив(Строка)
МассивСимволов = Новый Массив;
Для Позиция = 1 По СтрДлина(Строка) Цикл
МассивСимволов.Добавить(Сред(Строка, Позиция, 1));
КонецЦикла;
Возврат МассивСимволов;
КонецФункции
Оформление разбора в отдельную функцию оправдано, если операция используется в нескольких местах модуля. Массив индексируется с нуля, поэтому первый символ строки окажется в элементе МассивСимволов[0] — не перепутайте с позициями в самой строке.
Для очень длинных строк (десятки тысяч символов) посимвольный разбор работает медленно из-за особенностей неизменяемости строк. Если нужно просто проверить вхождение символов, рассмотрите альтернативы: СтрНайти(), СтрЗаменить() или регулярные выражения через COM-объект VBScript.RegExp на Windows-сервере.
Разбор в таблицу значений с дополнительными данными
Если вместе с символом нужно хранить его позицию, код или признак (цифра, буква, разделитель), удобна таблица значений. Такой подход типичен при разборе штрихкодов и кодов маркировки.
ТаблицаСимволов = Новый ТаблицаЗначений;
ТаблицаСимволов.Колонки.Добавить("Позиция");
ТаблицаСимволов.Колонки.Добавить("Символ");
ТаблицаСимволов.Колонки.Добавить("КодСимвола");
Для Позиция = 1 По СтрДлина(Строка) Цикл
Символ = Сред(Строка, Позиция, 1);
НоваяСтрока = ТаблицаСимволов.Добавить();
НоваяСтрока.Позиция = Позиция;
НоваяСтрока.Символ = Символ;
НоваяСтрока.КодСимвола = КодСимвола(Символ);
КонецЦикла;
Колонку с кодом символа удобно использовать для классификации: цифры лежат в диапазоне кодов 48–57, латинские заглавные буквы — 65–90, строчные — 97–122. Это позволяет проверять строку на недопустимые символы без длинных перечислений.
Проверка символов: цифры, буквы, служебные знаки
Частая практическая цель разложения — проверить, состоит ли строка только из допустимых символов. Например, ИНН должен содержать только цифры, а в наименовании не должно быть управляющих символов.
Проверка на цифры
Функция ТолькоЦифры(Строка)
Для Позиция = 1 По СтрДлина(Строка) Цикл
Код = КодСимвола(Строка, Позиция);
Если Код < 48 Или Код > 57 Тогда
Возврат Ложь;
КонецЕсли;
КонецЦикла;
Возврат Истина;
КонецФункции
Обратите внимание: КодСимвола() умеет принимать сразу строку и позицию, поэтому вызывать Сред() здесь не обязательно — код получается короче и быстрее.
Поиск недопустимых символов
Обратная задача — найти в строке символы, которых там быть не должно. Проще всего задать строку-«белый список» и проверять вхождение каждого символа через СтрНайти():
Допустимые = "0123456789АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ";
Для Позиция = 1 По СтрДлина(Строка) Цикл
Символ = ВРег(Сред(Строка, Позиция, 1));
Если СтрНайти(Допустимые, Символ) = 0 Тогда
Сообщить("Недопустимый символ на позиции " + Позиция);
КонецЕсли;
КонецЦикла;
Как выбрать способ разбора
Особенности: пробелы, переносы строк и спецсимволы
При посимвольном разборе пробелы, табуляции и переносы строк тоже являются символами и попадают в результат. Если они мешают, предварительно обработайте строку: СокрЛП() убирает незначащие символы по краям, а СтрЗаменить(Строка, Символы.ПС, "") удаляет переносы строк.
Объект Символы содержит предопределённые значения: Символы.ПС (перевод строки), Символы.ВК (возврат каретки), Символы.Таб (табуляция), Символы.НПП (неразрывный пробел). Неразрывный пробел — частый источник ошибок: визуально он неотличим от обычного, но сравнение строк даёт Ложь. При разборе данных из Excel или веб-форм проверяйте код символа 160.
Обратная задача — собрать строку из символа по его коду — решается функцией Символ(Код). Например, Символ(1057) вернёт букву «С».
Практический пример: транслитерация и подсчёт
Посимвольный разбор — основа транслитерации. Создаётся соответствие «русская буква → латинское написание», затем строка перебирается, и каждый символ заменяется:
Соответствие = Новый Соответствие;
Соответствие.Вставить("а", "a");
Соответствие.Вставить("б", "b");
// ... остальные буквы
Результат = "";
Для Позиция = 1 По СтрДлина(Строка) Цикл
Символ = НРег(Сред(Строка, Позиция, 1));
Замена = Соответствие.Получить(Символ);
Если Замена = Неопределено Тогда
Результат = Результат + Символ;
Иначе
Результат = Результат + Замена;
КонецЕсли;
КонецЦикла;
Аналогично решается подсчёт количества вхождений конкретного символа, хотя для этой задачи короче использовать СтрЧислоВхождений(Строка, Символ) — встроенная функция работает быстрее ручного цикла.
Как проверить результат
Равно СтрДлина() исходной строки
Меньше — пропущены позиции, больше — ошибка в границах цикла
Совпадают с началом и концом исходной строки
Пустые значения — сбита нумерация позиций
Конкатенация всех символов равна исходной строке
Расхождение — потеряны или изменены символы
Производительность и ограничения
Для строк разумной длины (наименования, коды, артикулы) посимвольный разбор выполняется мгновенно, и оптимизация не требуется. Проблемы начинаются на строках в десятки и сотни тысяч символов: каждый вызов Сред() и каждая конкатенация создают новую строку в памяти.
Если анализируются большие тексты, используйте СтрРазделить() для предварительного разбиения по разделителям, а посимвольный разбор применяйте только к коротким фрагментам. Для поиска и замены предпочитайте встроенные строковые функции — они реализованы на уровне платформы и работают заметно быстрее циклов на встроенном языке.
Что важно запомнить
Разложение строки по буквам в 1С делается циклом с Сред(Строка, Позиция, 1) от 1 до СтрДлина(). Символы удобно собирать в массив или таблицу значений, анализировать — через КодСимвола(). Помните о нумерации с единицы, неразрывных пробелах и разных кодах кириллицы и латиницы.
Частые вопросы
Можно ли разложить строку по буквам без цикла?
Одной встроенной функции «строка в массив символов» в 1С нет. Функция СтрРазделить() раскладывает строку по разделителю, но не по символам. Без цикла не обойтись, однако его можно один раз оформить в общую функцию и вызывать где угодно.
Почему Сред(Строка, 0, 1) не выдаёт ошибку?
Платформа 1С мягко обрабатывает выход за границы строки: при некорректной начальной позиции функция возвращает пустую строку, а не исключение. Поэтому ошибки нумерации не «падают», а молча портят результат — проверяйте границы вручную.
Как разложить строку с учётом регистра букв?
Функция Сред() сохраняет регистр исходной строки, ничего дополнительно делать не нужно. Регистр теряется только если вы сами применяете ВРег() или НРег() — например, для сравнения без учёта регистра.
Как перебрать строку в обратном порядке?
Используйте цикл с шагом -1: Для Позиция = -СтрДлина(Строка) По -1 Цикл с обращением Сред(Строка, -Позиция, 1). Альтернатива — обычный цикл с вычислением позиции как СтрДлина(Строка) - Индекс + 1.
Чем отличается разбор строки от СтрРазделить()?
СтрРазделить() раскладывает строку в массив подстрок по указанному разделителю (запятая, пробел, точка с запятой). Посимвольный разбор нужен, когда разделителя нет и каждый знак значим сам по себе — например, в ИНН, штрихкоде или коде маркировки.
Как посчитать, сколько раз буква встречается в строке?
Проще всего встроенной функцией СтрЧислоВхождений(Строка, "а") — она вернёт количество вхождений без цикла. Посимвольный перебор со счётчиком тоже работает, но медленнее и длиннее в записи.