Разработка и Конфигурация · 9 мин
Как взять символ из строки в 1С
Как получить символ из строки в 1С: функции Сред(), Лев(), Прав(), СтрДлина(), перебор символов в цикле, типичные ошибки и примеры кода.
Встроенный язык 1С не имеет отдельного типа «символ» и не поддерживает обращение к строке по индексу в квадратных скобках, как C# или Python. Поэтому задача «взять символ из строки» решается через строковые функции: Сред(), Лев(), Прав(), а для перебора всех символов — через цикл в связке с СтрДлина().
Понимание этих приёмов нужно при разборе артикулов, штрихкодов, кодов номенклатуры, проверке ИНН, форматировании номеров документов и любой посимвольной обработке текста. Ниже разобраны все рабочие способы с примерами кода, ограничениями и типичными ошибками.
Функция Сред() — основной способ получить символ по позиции
Функция Сред() возвращает подстроку, начиная с указанной позиции. Чтобы получить ровно один символ, третьим параметром передают единицу. Нумерация символов в 1С начинается с 1, а не с нуля — это важное отличие от большинства языков программирования.
Строка = "Артикул-12345";
ТретийСимвол = Сред(Строка, 3, 1); // "т"
ПятыйСимвол = Сред(Строка, 5, 1); // "и"
Если позиция выходит за пределы строки, функция вернёт пустую строку, а не ошибку. Это удобно, но опасно: логика модуля может молча отработать на пустом значении. Перед обращением к позиции, которая может отсутствовать, проверяйте длину через СтрДлина().
Если СтрДлина(Штрихкод) >= 7 Тогда
СедьмойСимвол = Сред(Штрихкод, 7, 1);
КонецЕсли;
Лев() и Прав() — первый и последний символ
Когда нужен крайний символ строки, короче и читабельнее использовать специализированные функции. Лев(Строка, 1) возвращает первый символ, Прав(Строка, 1) — последний. Второй параметр — количество символов, поэтому для одного символа всегда передаётся 1.
Код = "Н-00452";
Префикс = Лев(Код, 1); // "Н"
Последний = Прав(Код, 1); // "2"
Такой приём типичен при определении типа номенклатуры по первой букве кода, проверке завершающего символа штрихкода или отсечении служебного префикса. Если строка пустая, обе функции вернут пустую строку без ошибки.
Перебор всех символов строки в цикле
Для посимвольного анализа — например, проверки, что строка состоит только из цифр, или подсчёта определённых знаков — используют цикл Для от 1 до СтрДлина() с вызовом Сред() внутри.
Функция ТолькоЦифры(Строка)
Для Позиция = 1 По СтрДлина(Строка) Цикл
Символ = Сред(Строка, Позиция, 1);
Если Найти("0123456789", Символ) = 0 Тогда
Возврат Ложь;
КонецЕсли;
КонецЦикла;
Возврат Истина;
КонецФункции
Обратите внимание на приём с Найти(): вместо длинной цепочки сравнений символ ищется в строке допустимых значений. Это компактно и легко расширяется — достаточно добавить символ в эталонную строку.
- 1Проверьте, что строка не пустая: СтрДлина(Строка) > 0
- 2Организуйте цикл Для Позиция = 1 По СтрДлина(Строка)
- 3Получайте символ: Символ = Сред(Строка, Позиция, 1)
- 4Обработайте символ: сравнение, Найти(), накопление результата
- 5Проверьте результат на тестовых строках, включая пустую и односимвольную
Сравнение способов: что выбрать под задачу
Разные функции оптимальны для разных сценариев. Таблица помогает быстро выбрать подходящий инструмент.
| Задача | Функция | Пример |
|---|---|---|
| Символ по номеру позиции | Сред(Строка, N, 1) | Сред("АБВ", 2, 1) → "Б" |
| Первый символ | Лев(Строка, 1) | Лев("АБВ", 1) → "А" |
| Последний символ | Прав(Строка, 1) | Прав("АБВ", 1) → "В" |
| Перебор всех символов | Цикл + Сред() | Для П = 1 По СтрДлина(Строка) |
| Строка по разделителю | СтрПолучитьСтроку() | СтрПолучитьСтроку(Текст, 1) |
Отдельно выделим СтрПолучитьСтроку(): она работает не с позициями, а с многострочными строками и разделителями. Если «символ» на самом деле — фрагмент между запятыми или переносами строк, эта функция подходит лучше, чем ручной разбор через Сред().
Сравнение вариантов
Универсальный способ для любой позиции. Требует контроля длины строки.
Короче и читабельнее для крайних символов. Не подходит для середины строки.
Единственный вариант для посимвольного анализа. На очень длинных строках работает медленнее встроенных функций.
Для строк с разделителями. Не даёт доступа к отдельному символу внутри фрагмента.
Типичные ошибки и подводные камни
Большинство проблем при работе с символами строк связано с нумерацией и пограничными случаями. Разберём самые частые.
Особого внимания заслуживает регистр. Сравнение Символ = "а" не сработает для заглавной «А». Если регистр не важен, приводите обе стороны к одному виду: НРег(Символ) = "а". Для кириллицы и латиницы это работает корректно.
Ещё один подвох — непечатаемые символы: неразрывный пробел, табуляция, перенос строки. Они учитываются в СтрДлина(), но визуально не видны. Если посимвольный разбор ведёт себя странно, проверьте коды символов через КодСимвола() — часто выясняется, что в строке «лишний» служебный знак.
КодСимвола() и Символ() — работа на уровне кодов
Иногда нужен не сам символ, а его числовой код — например, для проверки диапазона или генерации служебных последовательностей. Функция КодСимвола(Символ) возвращает код Unicode, а обратная ей Символ(Код) — символ по коду.
СимволА = Сред("Артикул", 1, 1);
Код = КодСимвола(СимволА); // 1040 (А кириллическая)
Перенос = Символ(10); // перевод строки
Табуляция = Символ(9);
Практический сценарий — проверка, что символ является цифрой, без перечисления всех цифр: коды символов «0»–«9» идут подряд, поэтому достаточно сравнения КодСимвола(Символ) >= 48 И КодСимвола(Символ) <= 57. Однако для читаемости в прикладном коде чаще предпочитают вариант с Найти(), показанный выше.
В толстом клиенте и на сервере строковые функции работают одинаково, но посимвольные циклы по очень длинным строкам (десятки тысяч символов) заметно медленнее встроенных функций. Если задачу можно решить через Найти(), СтрЗаменить() или СтрРазделить() — выбирайте их.
Проверка результата и границы применения
После написания кода проверьте его на граничных случаях: пустая строка, строка из одного символа, строка ровно той длины, что указана в позиции, и строка с непечатаемыми символами. Именно на таких данных посимвольная логика ломается чаще всего.
Как проверить результат
Функция возвращает пустую строку или осмысленное значение по умолчанию
Ошибка выполнения или зависание цикла
Сред(Строка, СтрДлина(Строка), 1) возвращает последний символ
Возвращается пустая строка при корректной позиции
Регистр учтён явно (ВРег/НРег) там, где он не важен
Сравнение 'не находит' символы в другом регистре
Если задача выходит за рамки простого получения символа — регулярные выражения, сложный разбор форматов, обработка больших текстов — рассмотрите внешние компоненты или обработку на стороне СУБД. Встроенный язык 1С для тяжёлой посимвольной обработки не оптимизирован.
Что важно запомнить
Символ по позиции берут через Сред(Строка, Позиция, 1), крайние символы — через Лев() и Прав(), перебор — циклом от 1 до СтрДлина(). Нумерация начинается с 1, выход за границы строки возвращает пустую строку без ошибки, поэтому длину проверяют заранее. Для сравнения символов помните про регистр и непечатаемые знаки.
Частые вопросы
Как получить символ по индексу, как в других языках — Строка[2]?
В 1С такой синтаксис отсутствует. Вместо обращения по индексу используется функция Сред(Строка, Позиция, 1). Учтите, что позиция считается с единицы, а не с нуля.
Что вернёт Сред(), если позиция больше длины строки?
Пустую строку. Ошибки времени выполнения не будет, поэтому при строгой логике длину строки нужно проверять заранее через СтрДлина().
Как проверить, что символ — цифра?
Проще всего через Найти("0123456789", Символ) > 0. Альтернатива — сравнение кода символа с диапазоном 48–57 через КодСимвола(), но первый вариант читабельнее.
Как взять последний символ строки?
Функцией Прав(Строка, 1). Эквивалентный вариант — Сред(Строка, СтрДлина(Строка), 1), но Прав() короче и понятнее при чтении кода.
Почему сравнение символа с буквой не срабатывает?
Чаще всего из-за регистра: «А» и «а» — разные символы. Приведите обе стороны к одному регистру функциями ВРег() или НРег(). Реже причина в непечатаемых символах — проверьте строку через КодСимвола().
Как разбить строку на символы и поместить в массив?
Стандартной функции нет. Создайте массив и заполните его в цикле: для каждой позиции от 1 до СтрДлина(Строка) добавляйте Сред(Строка, Позиция, 1) методом Массив.Добавить().