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

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

Как заменить текст в запросе 1С

Как заменить текст прямо в запросе 1С: ограничения функции СтрЗаменить, работа через ПОДСТРОКА, временные таблицы и постобработку результата запроса.

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

Основные рабочие подходы: использование функции СтрЗаменить в выражениях запроса (доступна не во всех версиях платформы и контекстах), комбинация функций ПОДСТРОКА и поиска вхождения, а также вынос замены из запроса в код на встроенном языке после получения результата. Выбор зависит от версии платформы, объёма данных и того, где именно нужен результат.

Ниже разобраны все три способа с примерами кода, ограничениями и признаками того, когда какой вариант выбирать. Отдельно рассмотрены типичные ошибки — от потери данных при обрезке строк до падения производительности на больших таблицах.

Где именно нужна замена: определяем контекст задачи

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

Если запрос выполняется из кода и результат выгружается в таблицу значений, проще всего сделать замену уже после запроса — встроенный язык даёт полноценную функцию СтрЗаменить без ограничений. Если же замена нужна внутри выборки СКД или в поле динамического списка, придётся работать средствами языка запросов.

Отдельный случай — замена текста для соединения таблиц. Здесь замена должна выполняться именно в запросе, до соединения, иначе условие связи не сработает. Это самый требовательный сценарий, и для него обычно используют временные таблицы или функциональные выражения.

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

Как выбрать действие

Запрос выполняется из кода, результат в таблице значенийВыполните замену после запроса через СтрЗаменить встроенного языка
Замена нужна в СКД или выражении запросаИспользуйте СтрЗаменить в выражении запроса, если версия платформы поддерживает
Нужно соединить таблицы по очищенной строкеПодготовьте нормализованное поле во временной таблице до соединения

Функция СтрЗаменить в выражениях запроса

В актуальных версиях платформы «1С:Предприятие 8.3» в языке выражений запросов и СКД доступна функция СтрЗаменить(Строка, ПодстрокаПоиска, ПодстрокаЗамены). Она заменяет все вхождения подстроки и возвращает результат. Это самый прямой способ, когда он поддерживается.

Пример: убрать пробелы из номера документа в поле запроса:

Запрос.Текст =

"ВЫБРАТЬ

| СтрЗаменить(РеализацияТоваров.Номер, "" "", """") КАК НомерБезПробелов

|ИЗ

| Документ.РеализацияТоваровУслуг КАК РеализацияТоваров";

Обратите внимание на двойные кавычки: внутри строки запроса кавычка экранируется удвоением. Подстрока замены может быть пустой строкой — так реализуется удаление символов.

Ограничение: функция доступна не во всех версиях платформы и не во всех контекстах выполнения. Если консоль запросов или построитель выдаёт ошибку «Функция не найдена», значит, в вашей версии этот вариант недоступен и нужно переходить к альтернативам ниже.

Замена через ПОДСТРОКА и поиск позиции

Когда СтрЗаменить в запросе недоступна, замену собирают из функций работы со строками: ПОДСТРОКА (извлечение части строки) и конкатенация через оператор +. Идея: взять часть строки до заменяемого фрагмента, добавить новое значение и присоединить остаток.

Пример: заменить первый символ кода на букву «А»:

ВЫБРАТЬ

"А" + ПОДСТРОКА(Номенклатура.Код, 2, 10) КАК НовыйКод

ИЗ

Справочник.Номенклатура КАК Номенклатура

Здесь ПОДСТРОКА(Код, 2, 10) возвращает строку начиная со второго символа, а литерал «А» подставляется в начало. Это полноценная замена фрагмента в известной позиции.

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

Замена после запроса в коде

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

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

ЧистыйНомер = СтрЗаменить(Выборка.Номер, "-", "");

// дальнейшая обработка

КонецЦикла;

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

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

Порядок действий при замене в коде
  1. 1
    Выполните запрос и получите таблицу значений или выборку
  2. 2
    В цикле обойдите строки результата
  3. 3
    Примените СтрЗаменить к нужному полю и запишите результат обратно или в новую переменную
  4. 4
    Проверьте несколько строк с типичными и крайними значениями (пустая строка, строка без искомой подстроки)

Замена для соединения таблиц через временные таблицы

Когда очищенная строка нужна как ключ связи, сначала формируют временную таблицу с нормализованным полем, а затем соединяются по нему. Нормализацию при этом часто выполняют в коде: выгружают данные, обрабатывают СтрЗаменить и загружают обратно через параметр-таблицу.

Запрос.УстановитьПараметр("ТаблицаКлючей", ПодготовленнаяТаблица);

Запрос.Текст =

"ВЫБРАТЬ

| Таб.Ключ КАК Ключ

|ПОМЕСТИТЬ ВТ_Ключи

|ИЗ

| &ТаблицаКлючей КАК Таб

|;

|ВЫБРАТЬ

| Док.Ссылка

|ИЗ

| Документ.ЗаказПокупателя КАК Док

| ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_Ключи КАК Ключи

| ПО СтрЗаменить(Док.Номер, "" "", """") = Ключи.Ключ";

Такой подход сочетает гибкость кода и скорость запроса: тяжёлая нормализация делается один раз, а соединение выполняется на стороне СУБД. На больших объёмах это заметно быстрее, чем построчный поиск в коде.

Учтите, что соединение по вычисляемому строковому выражению не использует индексы. На таблицах в сотни тысяч записей запрос может выполняться долго — в этом случае лучше хранить нормализованное значение в отдельном реквизите и индексировать его.

Типичные ошибки и ограничения

Первая частая ошибка — попытка использовать СтрЗаменить в тексте запроса там, где версия платформы её не поддерживает. Запрос падает с ошибкой ещё на этапе компиляции. Проверяйте доступность функции в консоли запросов на простом примере до переноса в рабочий код.

Вторая ошибка — обрезка результата. Если поле запроса типизировано как строка фиксированной длины, а замена увеличивает длину, значение может обрезаться. При необходимости приводите результат через ВЫРАЗИТЬ(... КАК Строка(200)) с запасом длины.

Третья ошибка — регистр символов. СтрЗаменить чувствительна к регистру: «АБВ» и «абв» — разные подстроки. Если нужен поиск без учёта регистра, предварительно приводите строку к одному регистру, но помните, что при этом изменится и сам результат.

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

Типичные ошибки
01
Использование СтрЗаменить в запросе на версии платформы без её поддержки — запрос не выполняется
02
Обрезка результата из-за фиксированной длины строкового поля — применяйте ВЫРАЗИТЬ с запасом длины
03
Игнорирование регистра символов — подстрока в другом регистре не заменяется
04
Соединение по вычисляемой строке на больших таблицах — резкое падение производительности без индекса
05
Замена текста в данных базы без теста на копии — необратимая порча информации

Проверка результата замены

После реализации замены проверьте её на контрольном наборе: строка с одним вхождением, с несколькими вхождениями, без вхождений, пустая строка и строка, целиком состоящая из заменяемой подстроки. Эти пять случаев покрывают практически все сценарии сбоев.

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

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

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

Строка с несколькими вхождениями подстроки
Норма

Заменены все вхождения

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

Заменено только часть вхождений или ни одного

Строка без искомой подстроки
Норма

Строка не изменилась

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

Строка искажена или обрезана

Длина результата
Норма

Соответствует ожиданию после замены

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

Хвост строки потерян из-за фиксированной длины поля

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

Итог

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

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

Есть ли в запросе 1С аналог SQL-функции REPLACE?

Специальной функции REPLACE в языке запросов нет. В современных версиях платформы в выражениях запросов доступна СтрЗаменить, которая выполняет ту же задачу. Если она недоступна, замену делают через ПОДСТРОКА либо в коде после выполнения запроса.

Почему запрос с СтрЗаменить выдаёт ошибку «функция не обнаружена»?

Функция поддерживается не во всех версиях платформы и не во всех контекстах выполнения запроса. Проверьте её на простом запросе в консоли; при ошибке перенесите замену в код или используйте конструкцию с ПОДСТРОКА.

Как заменить подстроку без учёта регистра?

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

Как удалить символы из строки в запросе?

Удаление — это замена на пустую строку: СтрЗаменить(Поле, "удаляемое", ""). Если функция недоступна, строку собирают заново через ПОДСТРОКА, пропуская ненужные позиции.

Можно ли использовать замену в условии ГДЕ?

Да, если функция СтрЗаменить поддерживается: выражение можно разместить в условии отбора, например ГДЕ СтрЗаменить(Номер, " ", "") = &Номер. Учтите, что такой отбор не использует индекс и на больших таблицах работает медленно.

Что быстрее: замена в запросе или в коде?

Для одиночной выборки разница незаметна. На больших объёмах выигрывает вариант, где замена не мешает индексам: либо замена в коде после простого запроса, либо предварительно нормализованное поле во временной таблице.