Как исправить ошибку с кавычками в наименовании адреса при формировании запроса в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При обработке контактной информации и сопоставлении адресов с адресным классификатором (ФИАС / КЛАДР) разработчики могут столкнуться с синтаксической ошибкой выполнения запроса. Проблема возникает, когда в названии адресного объекта встречаются символы двойных кавычек — например, ул. Полка "Нормандия-Неман" или названия организаций в адресах доставки. Разберем детально, почему возникает данная ситуация и как правильно её исправить.

Проанализируем типовую ситуацию формирования динамического текста запроса, выясним причины сбоя синтаксического анализатора и рассмотрим несколько вариантов решения: от быстрого экранирования до рефакторинга кода на использование параметров.

Причина возникновения синтаксической ошибки

В некоторых механизмах разбора адресов текст запроса к регистру сведений РегистрСведений.АдресныеОбъекты формируется динамически через шаблоны подстановки строк вместо передачи значений через параметры запроса. Рассмотрим пример такого кода:


Шаблон = " ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.АдресныеОбъекты КАК %1
         |    ПО (%1.КодСубъектаРФ = НаселенныйПункт.КодСубъектаРФ)
         |        И (%1.КодОкруга = НаселенныйПункт.КодОкруга)
         |        И (%1.КодРайона = НаселенныйПункт.КодРайона)
         |        И (%1.КодГорода = НаселенныйПункт.КодГорода)
         |        И (%1.КодВнутригородскогоРайона = НаселенныйПункт.КодВнутригородскогоРайона)
         |        И (%1.КодНаселенногоПункта = НаселенныйПункт.КодНаселенногоПункта)
         |        И (%1.Наименование = ""%2"")
         |        И (%1.Сокращение = ""%3"") ";

Когда значение переменной содержит кавычки (например, Полка "Нормандия-Неман"), прямая подстановка в шаблон ""%2"" разрывает строковый литерал внутри языка запросов 1С. В результате синтаксический анализатор платформы выдает ошибку разбора текста запроса.

Способ 1. Корректное экранирование кавычек для строкового литерала запроса

Если требуется быстро устранить ошибку без глобального изменения логики формирования динамического запроса, необходимо правильно заэкранировать символ кавычки во входной строке.

Посмотрим на правила экранирования в платформе «1С:Предприятие»:

  1. В тексте запроса строковый литерал обрамляется кавычками. Чтобы внутри литерала запроса появилась одна кавычка, она должна быть удвоена ("").
  2. Во встроенном языке 1С сам символ кавычки в строковом литерале также экранируется удвоением.

Если выполнить избыточное экранирование (например, заменить одну кавычку на четыре или восемь), синтаксической ошибки не будет, но запрос не найдет запись в классификаторе, так как будет искать наименование с лишними кавычками. Корректная конструкция выглядит следующим образом:


// Экранируем кавычки для корректной вставки в литерал текста запроса:
ТестПараметр = СтрЗаменить(Тест, """", """"""");

Разберем по шагам, как это работает:

  1. Второй параметр """" передает во встроенном языке одну кавычку (").
  2. Третий параметр """"""" передает строку из двух кавычек ("").
  3. При подстановке полученной строки в шаблон запроса ""%2"" значение внутри литерала запроса будет содержать корректно экранированную кавычку, и поиск по классификатору выполнится без ошибок.

Способ 2. Перевод запроса на использование параметров (рекомендуемый подход)

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

Рассмотрим, как модифицировать условие соединения:


// Изменяем условие в тексте запроса
ТекстСоединения = " ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.АдресныеОбъекты КАК АдресныеОбъектыУлица
                  |    ПО (АдресныеОбъектыУлица.КодСубъектаРФ = НаселенныйПункт.КодСубъектаРФ)
                  |        И (АдресныеОбъектыУлица.КодГорода = НаселенныйПункт.КодГорода)
                  |        И (АдресныеОбъектыУлица.Наименование = &НаименованиеУлицы)
                  |        И (АдресныеОбъектыУлица.Сокращение = &СокращениеУлицы)";

// Устанавливаем параметры перед выполнением
Запрос.Текст = Запрос.Текст + ТекстСоединения;
Запрос.УстановитьПараметр("НаименованиеУлицы", Адрес.Улица);
Запрос.УстановитьПараметр("СокращениеУлицы", Адрес.Сокращение);

Преимущества параметризации:

  1. Полная безопасность от ошибок экранирования любых спецсимволов.
  2. Кэширование плана выполнения запроса СУБД (повышение производительности).
  3. Чистота и читаемость исходного кода.

Способ 3. Внесение исправлений через расширение конфигурации

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

  1. Создаем расширение конфигурации.
  2. Добавляем в расширение модуль, содержащий функцию компоновки адресного запроса.
  3. Используем аннотацию &ИзменениеИКонтроля или &Вместо для замены формирования условия соединения на вызов с установкой параметров либо с предварительным вызовом СтрЗаменить.

Проверка типографских кавычек в классификаторе

Если после устранения синтаксической ошибки адрес все равно не сопоставляется с классификатором, проанализируем вид используемых кавычек в базе. В базах ФИАС/ГАР наименования могут быть внесены с типографскими кавычками-ёлочками (« ») либо вовсе без кавычек:

  1. Код символа «: Alt + 0171
  2. Код символа »: Alt + 0187

Если в исходной строке используются обычные прямые кавычки, а в базе классификатора — типографские, точное строковое равенство не сработает. В таком случае перед сопоставлением рекомендуется выполнять нормализацию строки (удаление кавычек или приведение их к единому виду).

← На главную