Разработка и Конфигурация · 10 мин
Как заменить строку в запросе 1С
Разбираем, как заменить подстроку в запросе 1С: функция ВЫРАЗИТЬ и ПОДСТРОКА, ограничения языка запросов, замена через СтрЗаменить после выгрузки и типовые ошибки.
В языке запросов 1С нет прямого аналога функции REPLACE из классического SQL: встроенной функции замены подстроки внутри текста запроса не существует. Это частая причина вопросов у разработчиков, которые хотят, например, убрать пробелы из артикула, заменить символ в наименовании или привести строку к нужному виду прямо в выборке. Рабочие решения существуют, но выбор зависит от задачи: где именно нужна замена — в условии отбора, в выходном поле или в соединении таблиц.
Основные подходы таковы: обработка строки до передачи в запрос (параметром), использование функций ПОДСТРОКА, ЛЕВ, ПРАВ и конкатенации для точечных замен по известной позиции, а также выгрузка результата и обработка средствами встроенного языка через функцию СтрЗаменить. Ниже разобраны все варианты с конкретным синтаксисом, ограничениями и критериями выбора.
Почему в запросе 1С нельзя просто написать REPLACE
Язык запросов 1С — это декларативный диалект, ориентированный на выборку и агрегацию данных, а не на строковые преобразования. Набор строковых функций в нём ограничен: доступны ПОДСТРОКА, ЛЕВ, ПРАВ, ДЛИНАСТРОКИ, СОКРЛ, СОКРП, СОКРЛП, ВРЕГ, НРЕГ и оператор конкатенации «+». Функции поиска позиции подстроки и замены по шаблону в стандартном синтаксисе отсутствуют.
Это архитектурное ограничение платформы, а не недоработка конкретной версии. Поэтому любая «замена строки в запросе» — это всегда один из трёх сценариев: предварительная обработка параметра, конструирование новой строки из частей внутри запроса или постобработка результата. Попытка найти скрытую функцию замены в документации бесполезна — её там нет.
Замена строки до запроса: функция СтрЗаменить
Самый надёжный и производительный способ — заменить подстроку до выполнения запроса и передать результат параметром. Это правильный выбор, когда заменённое значение используется в условии отбора, соединении или сравнении: вычисление выполняется один раз на клиенте или сервере, а не для каждой строки выборки.
АртикулОчищенный = СтрЗаменить(АртикулИсходный, " ", "");
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Артикул = &Артикул";
Запрос.УстановитьПараметр("Артикул", АртикулОчищенный);
Результат = Запрос.Выполнить().Выгрузить();
Функция СтрЗаменить работает с полным совпадением подстроки и заменяет все вхождения. Если нужно убрать только пробелы по краям, используйте СокрЛП. Для сложной нормализации (несколько символов, регистр) выполняйте цепочку преобразований до запроса — это читаемее, чем попытки встроить логику в текст запроса.
- 1Определите, какая подстрока и на что заменяется
- 2Выполните СтрЗаменить над исходной строкой во встроенном языке
- 3Передайте результат в запрос через УстановитьПараметр
- 4Проверьте выборку на контрольном значении с заменяемым символом
Сборка строки внутри запроса: ПОДСТРОКА и конкатенация
Если позиция заменяемого фрагмента известна заранее и фиксирована, строку можно собрать прямо в запросе. Например, требуется заменить третий символ кода на дефис: берём левую часть до позиции, добавляем новый символ и правую часть после неё.
ВЫБРАТЬ
ПОДСТРОКА(Товары.Код, 1, 2) + "-" + ПОДСТРОКА(Товары.Код, 4, 10) КАК КодНовый
ИЗ
Справочник.Товары КАК Товары
Этот приём работает только при известной длине и позиции. Если заменяемый символ «плавает» по строке, позицию придётся вычислять перебором в коде — внутри запроса функции поиска вхождения нет. Также помните, что ПОДСТРОКА нумерует символы с единицы, а при выходе за границы строки вернёт усечённый результат без ошибки, что может незаметно исказить данные.
Замена в результате: обработка после выгрузки
Когда заменить нужно значения в выходном поле отчёта или таблицы, часто проще выполнить запрос как есть, а затем пройтись по результату и обработать строки функцией СтрЗаменить. Это особенно удобно при выгрузке в таблицу значений: проходите циклом по колонке и перезаписываете значения.
ТаблицаРезультат = Запрос.Выполнить().Выгрузить();
Для Каждого СтрокаТаб Из ТаблицаРезультат Цикл
СтрокаТаб.Наименование = СтрЗаменить(СтрокаТаб.Наименование, " ", " ");
КонецЦикла;
Минус подхода — лишний проход по данным и невозможность использовать заменённое значение в дальнейших соединениях внутри того же запроса. Для больших выборок оценивайте объём: постобработка сотен тысяч строк заметно медленнее, чем передача готового параметра. Если заменённое значение нужно для отбора, постобработка не подходит в принципе.
Сравнение вариантов замены
Лучший вариант для условий и соединений; быстро, но меняет только входное значение, а не данные в таблицах
Подходит при фиксированной позиции замены; не работает с плавающей позицией и требует контроля длины
Универсально для выходных полей отчётов; лишний проход по данным, нельзя использовать в отборах
Замена в условии ПОДОБНО и фильтрация по шаблону
Частая реальная задача, которую ошибочно называют «заменой строки», — найти записи, где значение содержит определённый фрагмент, игнорируя лишние символы. Для этого в языке запросов есть оператор ПОДОБНО с символами-шаблонами: «%» — любая последовательность символов, «_» — один произвольный символ.
ВЫБРАТЬ
Номенклатура.Ссылка КАК Ссылка
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
Номенклатура.Наименование ПОДОБНО &Шаблон
Параметр шаблона формируйте в коде: Шаблон = "%" + СтрЗаменить(ИскомыйТекст, " ", "%") + "%"; — так поиск «красный шар» найдёт и «красный большой шар». Учтите, что ПОДОБНО с ведущим «%» не использует индекс и на больших таблицах работает медленно; для частых поисков рассмотрите полнотекстовый поиск платформы.
Если в данных регулярно встречаются двойные пробелы или неразрывные пробелы из копипасты, нормализуйте их один раз регламентным заданием по базе, а не в каждом запросе — это упростит все отборы и отчёты.
Типичные ошибки и как их избежать
Первая ошибка — попытка написать REPLACE или ЗАМЕНИТЬ в тексте запроса: конструктор запросов выдаст синтаксическую ошибку, а время будет потрачено на поиск несуществующей функции. Вторая — замена в выходном поле там, где значение потом используется для соединения: соединение идёт по исходным данным таблиц, а не по вычисленному полю, и строки не сойдутся.
Третья группа ошибок связана с невидимыми символами: неразрывный пробел (код 160) не совпадает с обычным пробелом, и СтрЗаменить с обычным пробелом его не найдёт. Если замена «не срабатывает», проверьте код символа через КодСимвола. Также помните, что СтрЗаменить не изменяет исходную строку по ссылке — результат нужно присвоить переменной.
Проверка результата и ограничения
После реализации замены проверьте три вещи: на контрольном значении с заменяемым фрагментом убедитесь, что замена произошла; на значении без фрагмента — что строка осталась неизменной; на граничных случаях (пустая строка, минимальная и максимальная длина) — что нет обрезания или неожиданных пустых значений. Для запросов удобно временно вывести рядом исходное и обработанное поле и сравнить их глазами на выборке из нескольких десятков строк.
Граница безопасной самостоятельной работы: замена в запросах и постобработка не меняют данные в базе и безопасны. Осторожность нужна, если вы решите нормализовать данные физически — обработкой, которая перезаписывает реквизиты объектов. Перед такой обработкой сделайте резервную копию, сначала выполните запуск в режиме «только отчёт о найденных значениях» и проверьте объём затрагиваемых записей.
Что важно запомнить
Функции REPLACE в языке запросов 1С нет. Для отборов заменяйте строку через СтрЗаменить до запроса и передавайте параметром, для выходных полей используйте ПОДСТРОКА с конкатенацией или постобработку результата, для поиска по фрагменту — оператор ПОДОБНО. Проверяйте невидимые символы и граничные значения.
Частые вопросы
Есть ли в запросе 1С функция ЗАМЕНИТЬ или REPLACE?
Нет. В языке запросов платформы такой функции не существует. Используйте СтрЗаменить во встроенном языке до запроса или после выгрузки, либо собирайте строку через ПОДСТРОКА и оператор «+» внутри запроса.
Как в запросе убрать пробелы из строки?
Для крайних пробелов есть функции СОКРЛ, СОКРП и СОКРЛП, которые работают прямо в запросе. Пробелы внутри строки запросом не удалить — обработайте значение через СтрЗаменить до запроса или после выгрузки результата.
СтрЗаменить не находит пробел, хотя он виден. Почему?
В данных часто встречается неразрывный пробел (код символа 160) или табуляция, скопированные из Excel или Word. Определите реальный код символа функцией КодСимвола и заменяйте именно его, например через Символ(160).
Можно ли использовать заменённое значение для соединения таблиц?
Только если замена выполнена до запроса и передана параметром, либо если во временной таблице вы заранее подготовили вычисленное поле и соединяетесь уже по нему. Соединение по выражению с ПОДСТРОКА технически возможно, но выполняется без индекса и медленно на больших таблицах.
Как заменить несколько разных символов в одной строке?
Выполните последовательную цепочку вызовов СтрЗаменить во встроенном языке, присваивая результат той же переменной. Для большого набора символов удобнее цикл по соответствию «что заменить → на что». Внутри одного запроса такую цепочку построить нельзя.
Что быстрее: замена параметром или постобработка результата?
Замена параметром до запроса всегда эффективнее: вычисление выполняется один раз. Постобработка требует прохода по всем строкам результата и оправдана только когда обрабатываются данные, полученные из базы, а не входные значения.