При обработке контактной информации и сопоставлении адресов с адресным классификатором (ФИАС / КЛАДР) разработчики могут столкнуться с синтаксической ошибкой выполнения запроса. Проблема возникает, когда в названии адресного объекта встречаются символы двойных кавычек — например, ул. Полка "Нормандия-Неман" или названия организаций в адресах доставки. Разберем детально, почему возникает данная ситуация и как правильно её исправить.
Проанализируем типовую ситуацию формирования динамического текста запроса, выясним причины сбоя синтаксического анализатора и рассмотрим несколько вариантов решения: от быстрого экранирования до рефакторинга кода на использование параметров.
В некоторых механизмах разбора адресов текст запроса к регистру сведений РегистрСведений.АдресныеОбъекты формируется динамически через шаблоны подстановки строк вместо передачи значений через параметры запроса. Рассмотрим пример такого кода:
Шаблон = " ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.АдресныеОбъекты КАК %1
| ПО (%1.КодСубъектаРФ = НаселенныйПункт.КодСубъектаРФ)
| И (%1.КодОкруга = НаселенныйПункт.КодОкруга)
| И (%1.КодРайона = НаселенныйПункт.КодРайона)
| И (%1.КодГорода = НаселенныйПункт.КодГорода)
| И (%1.КодВнутригородскогоРайона = НаселенныйПункт.КодВнутригородскогоРайона)
| И (%1.КодНаселенногоПункта = НаселенныйПункт.КодНаселенногоПункта)
| И (%1.Наименование = ""%2"")
| И (%1.Сокращение = ""%3"") ";
Когда значение переменной содержит кавычки (например, Полка "Нормандия-Неман"), прямая подстановка в шаблон ""%2"" разрывает строковый литерал внутри языка запросов 1С. В результате синтаксический анализатор платформы выдает ошибку разбора текста запроса.
Если требуется быстро устранить ошибку без глобального изменения логики формирования динамического запроса, необходимо правильно заэкранировать символ кавычки во входной строке.
Посмотрим на правила экранирования в платформе «1С:Предприятие»:
"").Если выполнить избыточное экранирование (например, заменить одну кавычку на четыре или восемь), синтаксической ошибки не будет, но запрос не найдет запись в классификаторе, так как будет искать наименование с лишними кавычками. Корректная конструкция выглядит следующим образом:
// Экранируем кавычки для корректной вставки в литерал текста запроса:
ТестПараметр = СтрЗаменить(Тест, """", """"""");
Разберем по шагам, как это работает:
"""" передает во встроенном языке одну кавычку (").""""""" передает строку из двух кавычек ("").""%2"" значение внутри литерала запроса будет содержать корректно экранированную кавычку, и поиск по классификатору выполнится без ошибок.Наиболее надежный и архитектурно правильный способ решения проблемы — отказ от конкатенации строковых литералов в тексте запроса и переход на параметры запроса. Параметры платформы 1С автоматически обрабатывают любые спецсимволы, кавычки и переводы строк, исключая возможность синтаксических ошибок.
Рассмотрим, как модифицировать условие соединения:
// Изменяем условие в тексте запроса
ТекстСоединения = " ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.АдресныеОбъекты КАК АдресныеОбъектыУлица
| ПО (АдресныеОбъектыУлица.КодСубъектаРФ = НаселенныйПункт.КодСубъектаРФ)
| И (АдресныеОбъектыУлица.КодГорода = НаселенныйПункт.КодГорода)
| И (АдресныеОбъектыУлица.Наименование = &НаименованиеУлицы)
| И (АдресныеОбъектыУлица.Сокращение = &СокращениеУлицы)";
// Устанавливаем параметры перед выполнением
Запрос.Текст = Запрос.Текст + ТекстСоединения;
Запрос.УстановитьПараметр("НаименованиеУлицы", Адрес.Улица);
Запрос.УстановитьПараметр("СокращениеУлицы", Адрес.Сокращение);
Преимущества параметризации:
Если ошибка возникает в типовом модуле конфигурации, находящейся на поддержке, не обязательно снимать её с поддержки. Достаточно переопределить проблемный метод через механизм расширений:
&ИзменениеИКонтроля или &Вместо для замены формирования условия соединения на вызов с установкой параметров либо с предварительным вызовом СтрЗаменить.Если после устранения синтаксической ошибки адрес все равно не сопоставляется с классификатором, проанализируем вид используемых кавычек в базе. В базах ФИАС/ГАР наименования могут быть внесены с типографскими кавычками-ёлочками (« ») либо вовсе без кавычек:
«: Alt + 0171»: Alt + 0187Если в исходной строке используются обычные прямые кавычки, а в базе классификатора — типографские, точное строковое равенство не сработает. В таком случае перед сопоставлением рекомендуется выполнять нормализацию строки (удаление кавычек или приведение их к единому виду).