Разработка и Конфигурация · 10 мин
Как заменить строку в 1С: функции и примеры кода
Как заменить строку в 1С: функция СтрЗаменить, поиск подстроки через СтрНайти, замена в многострочном тексте, типичные ошибки и примеры кода на встроенном языке.
Замена подстроки — одна из самых частых операций при работе с текстом в 1С: очистка номеров документов от префиксов, подстановка значений в шаблоны печатных форм, нормализация данных при обмене. Во встроенном языке за это отвечает функция СтрЗаменить, а для контроля результата используются функции поиска — СтрНайти и СтрЧислоВхождений.
Главная особенность, о которой часто забывают: строки в 1С неизменяемы. СтрЗаменить не меняет исходную переменную, а возвращает новую строку. Если не присвоить результат обратно, замена «потеряется» без всякой ошибки — код отработает, но данные останутся прежними.
Материал рассчитан на разработчиков и администраторов, которые пишут обработки, расширения или дорабатывают конфигурации. Примеры приведены на встроенном языке 1С и работают в управляемых и обычных формах, на клиенте и на сервере.
Функция СтрЗаменить: синтаксис и базовый пример
Функция имеет три обязательных параметра: исходная строка, искомая подстрока и строка замены. Все вхождения искомого фрагмента заменяются за один вызов — перебирать вхождения вручную не требуется.
НомерДокумента = "ПР-000123";
НомерБезПрефикса = СтрЗаменить(НомерДокумента, "ПР-", "");
// Результат: "000123"
Текст = "Уважаемый [Клиент]!";
Приветствие = СтрЗаменить(Текст, "[Клиент]", "Иван Петров");
// Результат: "Уважаемый Иван Петров!"
Если искомая подстрока не найдена, функция просто возвращает исходную строку без изменений — исключения не возникает. Это удобно для шаблонов: можно последовательно «прогонять» текст через серию замен, не проверяя наличие каждого маркера.
Обратите внимание: пустая строка в качестве третьего параметра — легальный способ удалить фрагмент. А вот пустая строка в качестве искомого значения недопустима и приведёт к ошибке выполнения.
Поиск перед заменой: СтрНайти и СтрЧислоВхождений
Часто замену нужно выполнять условно — только если фрагмент действительно присутствует. Для этого используется СтрНайти, которая возвращает позицию первого вхождения (начиная с 1) или 0, если подстрока не найдена.
Строка = "Заказ № АБВ-456 от клиента";
Если СтрНайти(Строка, "АБВ-") > 0 Тогда
Строка = СтрЗаменить(Строка, "АБВ-", "XYZ-");
КонецЕсли;
Функция СтрЧислоВхождений возвращает количество вхождений подстроки. Она полезна для проверки результата: после замены число вхождений старого фрагмента должно стать нулевым, а нового — соответствовать ожиданию.
Замена без учёта регистра
СтрЗаменить всегда регистрозависима, и это одна из самых частых причин «неработающей» замены. Если регистр символов в данных непредсказуем (например, пользовательский ввод), надёжный приём — работать через копию строки в одном регистре, вычисляя позиции в ней, а вырезать фрагменты из оригинала.
Функция ЗаменитьБезРегистра(Исходная, ЧтоИскать, НаЧтоЗаменить)
Результат = Исходная;
НижнийРезультат = НРег(Результат);
ИскомоеНижний = НРег(ЧтоИскать);
Позиция = СтрНайти(НижнийРезультат, ИскомоеНижний);
Пока Позиция > 0 Цикл
Результат = Лев(Результат, Позиция - 1) + НаЧтоЗаменить
+ Сред(Результат, Позиция + СтрДлина(ЧтоИскать));
НижнийРезультат = НРег(Результат);
Позиция = СтрНайти(НижнийРезультат, ИскомоеНижний);
КонецЦикла;
Возврат Результат;
КонецФункции
Такой подход сохраняет исходный регистр остального текста и корректно обрабатывает смешанные варианты написания. Для разовых простых случаев, где регистр заведомо известен, достаточно обычной СтрЗаменить.
Последовательная замена в шаблонах
Типовой сценарий — подстановка нескольких значений в шаблон письма, СМС или печатной формы. Замены выполняются цепочкой: результат каждой операции передаётся в следующую.
- 1Подготовьте шаблон с уникальными маркерами, например [ФИО], [Дата], [Сумма]
- 2Последовательно вызовите СтрЗаменить для каждого маркера, присваивая результат той же переменной
- 3Проверьте через СтрНайти(Текст, "["), что незаменённых маркеров не осталось
- 4Передайте готовый текст в печатную форму, письмо или сообщение
Текст = Шаблон;
Текст = СтрЗаменить(Текст, "[ФИО]", Данные.ФИО);
Текст = СтрЗаменить(Текст, "[Дата]", Формат(Данные.Дата, "ДЛФ=D"));
Текст = СтрЗаменить(Текст, "[Сумма]", Формат(Данные.Сумма, "ЧДЦ=2"));
Если СтрНайти(Текст, "[") > 0 Тогда
Сообщить("В шаблоне остались незаполненные маркеры");
КонецЕсли;
Порядок замен имеет значение, если маркеры пересекаются: например, замена «[Дата]» до «[ДатаОплаты]» может повредить второй маркер. Используйте маркеры, которые не являются началом друг друга, или заменяйте более длинные маркеры первыми.
Замена в многострочном тексте и спецсимволы
СтрЗаменить корректно работает с переносами строк, табуляцией и другими служебными символами — их можно указывать через объект Символы. Это удобно для нормализации текста, пришедшего из файлов или внешних систем.
// Убрать символы возврата каретки после загрузки из файла Unix-формата
Текст = СтрЗаменить(Текст, Символы.ВК, "");
// Заменить табуляции на точку с запятой для выгрузки
Строка = СтрЗаменить(Строка, Символы.Таб, ";");
// Убрать неразрывные пробелы из чисел, скопированных из Excel
ЧислоСтрокой = СтрЗаменить(ЧислоСтрокой, Символ(160), "");
ЧислоСтрокой = СтрЗаменить(ЧислоСтрокой, " ", "");
Неразрывный пробел (код 160) — классическая ловушка при разборе чисел и сумм: визуально он неотличим от обычного пробела, но СтрЗаменить с обычным пробелом его не находит, а преобразование к числу завершается ошибкой. Если данные приходят из внешних источников, удаляйте оба варианта.
Альтернативные способы: Лев, Сред, Прав и разбор строки
Иногда замену удобнее выполнить не поиском, а конструированием строки из частей. Функции Лев, Сред, Прав и СтрДлина позволяют собрать новое значение по известным позициям — например, заменить символ в фиксированной позиции кода или артикула.
// Заменить третий символ в коде фиксированной длины
Код = "АБВ123";
НовыйКод = Лев(Код, 2) + "Х" + Сред(Код, 4);
// Результат: "АБХ123"
Для сложных сценариев — замена по маске, обработка разделителей, работа со списками — полезны СтрРазделить и СтрСоединить: строка разбивается в массив, элементы обрабатываются по отдельности, затем собираются обратно. В толстом клиенте и на сервере доступны также регулярные выражения через COM-объект VBScript.RegExp, но это решение зависит от платформы и операционной системы, поэтому в кроссплатформенных решениях его избегают.
Сравнение вариантов
Универсальный способ для точной замены всех вхождений; не подходит для поиска без учёта регистра и масок
Замена по известным позициям в строках фиксированной структуры; требует точного знания длины
Обработка списков и разделителей; избыточно для простой одиночной замены
Замена по маске; зависит от ОС и недоступна в веб-клиенте и мобильной платформе
Проверка результата и отладка
После замены полезно убедиться, что она действительно произошла и не затронула лишнего. Минимальный набор проверок: искомый фрагмент отсутствует, длина строки изменилась ожидаемо, количество вхождений нового фрагмента совпадает с расчётным.
Как проверить результат
Возвращает 0 — старых вхождений не осталось
Возвращает позицию > 0 — замена не сработала или сработала частично
Равно ожидаемому числу замен
Больше ожидаемого — новый фрагмент уже встречался в тексте
Разница соответствует разнице длин фрагментов, умноженной на число замен
Неожиданная длина — заменено лишнее или ничего не заменено
При отладке в конфигураторе используйте табло (Shift+F9), чтобы увидеть реальное содержимое строки, включая непечатаемые символы. Если строка длинная, выведите её в сообщение или сохраните в текстовый документ и откройте в редакторе с отображением служебных символов.
Что важно запомнить
СтрЗаменить возвращает новую строку и заменяет все вхождения с учётом регистра. Результат всегда присваивайте переменной, проверяйте через СтрНайти и СтрЧислоВхождений, а при данных из внешних источников очищайте неразрывные пробелы и служебные символы.
Частые вопросы
Почему СтрЗаменить не меняет мою строку?
Функция не изменяет исходную переменную, а возвращает новое значение. Запись вида СтрЗаменить(Текст, "а", "б") без присваивания ничего не делает. Правильно: Текст = СтрЗаменить(Текст, "а", "б").
Как заменить только первое вхождение подстроки?
Найдите позицию через СтрНайти, затем соберите строку: Лев(Строка, Позиция - 1) + Замена + Сред(Строка, Позиция + СтрДлина(Искомое)). СтрЗаменить такой режим не поддерживает — она всегда заменяет все вхождения.
Как удалить фрагмент из строки?
Передайте пустую строку третьим параметром: СтрЗаменить(Текст, "удаляемое", ""). Это стандартный и безопасный способ удаления подстроки.
Работает ли СтрЗаменить на клиенте в управляемых формах?
Да, функция доступна на тонком, толстом и веб-клиенте, а также на сервере. Никакой передачи данных на сервер для строковых операций не требуется — выполняйте их там, где удобнее по логике кода.
Как заменить текст в неограниченной строке или многострочном поле?
Точно так же — ограничений по длине у СтрЗаменить нет. Переносы строк указывайте через Символы.ПС и Символы.ВК, если нужно работать с построчной структурой. Для очень больших текстов учитывайте, что каждая замена создаёт новую строку в памяти.
Можно ли заменить значение в реквизите объекта напрямую?
СтрЗаменить работает только со значением строки. Для реквизита объекта нужно получить объект методом ПолучитьОбъект(), присвоить реквизиту результат замены и вызвать Записать(). В запросе замену строки выполнить нельзя — там доступны только функции выборки и сравнения.