Как правильно передать запрос со строковыми литералами в оператор Выполнить()?

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

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

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

Выясним причину: почему путаются кавычки?

В платформе 1С строковый литерал ограничивается двойными кавычками. Если внутри строки требуется указать символ кавычки, его необходимо удвоить (""). В запросах 1С литералы строк также обрамляются кавычками. Когда мы помещаем исполняемый код в строку для оператора Выполнить(), возникает двойная вложенность:

  1. Внешний уровень — строка самого оператора Выполнить("...").
  2. Промежуточный уровень — текст запроса на языке 1С, передаваемый в конструктор: Новый Запрос("...").
  3. Внутренний уровень — строковый литерал языка запросов внутри самого запроса.

В результате для представления одной кавычки во внутреннем запросе разработчику приходится писать сразу четыре кавычки подряд, что крайне неудобно для чтения и сопровождения кода.

Способ 1. Вынесение текста запроса в отдельную переменную

Проанализируем наиболее практичный и читаемый вариант, предложенный участниками обсуждения: вынести текст запроса за пределы динамически исполняемой строки. В этом случае мы формируем текст запроса обычным способом в текущем контексте, а внутри оператора Выполнить() просто ссылаемся на созданную переменную по имени.

Посмотрим на пример реализации:


ТекстЗапроса = "ВЫБРАТЬ ""АБВ"" КАК П";
Выполнить("Запрос = Новый Запрос(ТекстЗапроса); 
| ТЗ = Запрос.Выполнить().Выгрузить(); 
| Сообщить(ТЗ[0].П);");

Поскольку переменная ТекстЗапроса находится в той же области видимости, оператор Выполнить() видит её напрямую. Это полностью избавляет нас от необходимости многократного экранирования текста запроса внутри исполняемой строки.

Способ 2. Экранирование кавычек в одной строке (учетверение)

Если по каким-либо причинам требуется уместить всю конструкцию строго в одну строку без объявления предварительных переменных, разберем по шагам правило экранирования. Каждая кавычка в тексте запроса должна быть продублирована для строкового литерала конструктора запроса, а затем вся эта комбинация повторно дублируется для строкового литерала оператора Выполнить().

Посмотрим на пример монолитной строки:


Выполнить("Запрос = Новый Запрос(""ВЫБРАТЬ """"АБВ"""" КАК П""); ТЗ = Запрос.Выполнить().Выгрузить(); Сообщить(ТЗ[0].П);");

Здесь литерал ""АБВ"" для конструктора запроса превращается в """"АБВ"""" внутри общей строки. Важно помнить: такой подход сильно усложняет отладку и повышает риск синтаксической ошибки при малейшем изменении запроса.

Способ 3. Использование параметров запроса вместо строковых литералов

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

Разберем пример:


ТекстЗапроса = "ВЫБРАТЬ &МояСтрока КАК П";
Выполнить("Запрос = Новый Запрос(ТекстЗапроса);
| Запрос.УстановитьПараметр(""МояСтрока"", ""АБВ"");
| ТЗ = Запрос.Выполнить().Выгрузить();
| Сообщить(ТЗ[0].П);");

В данном случае строка "АБВ" передается в метод Запрос.УстановитьПараметр() как обычное значение, и в самом тексте запроса кавычки не требуются вовсе.

Способ 4. Формирование кавычек через Символ(34) и СтрШаблон()

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

  1. Функция Символ(34) — возвращает символ двойной кавычки по его коду в таблице символов. Заменяет написание кавычек конкатенацией: Символ(34) + "АБВ" + Символ(34).
  2. Функция СтрШаблон() — позволяет подставить значения в текст по маске (например, %1), что исключает многократную склейку кавычек вручную.

Ограничения и подводные камни оператора Выполнить()

Проанализируем важные технические особенности, о которых необходимо помнить при использовании оператора Выполнить() вместе с запросами:

  1. Клиент-серверный контекст: Объект Запрос доступен только на стороне сервера (или в толстом клиенте). Если выполнить вызов Выполнить() с кодом запроса на тонком клиенте, платформа выбросит исключение времени выполнения о неизвестном типе объекта. Код должен выполняться строго на сервере.
  2. Сложность отладки: Код, передаваемый в Выполнить(), не позволяет устанавливать точки останова в конфигураторе. При ошибке отладчик укажет лишь на строчку с самим оператором Выполнить(), не сообщая деталей о внутренней ошибке.
  3. Производительность: Строка внутри оператора компилируется каждый раз заново. В циклических операциях такой вызов существенно снижает быстродействие по сравнению с обычным вызовом процедур и функций.
  4. Архитектурная избыточность: В большинстве прикладных задач сам оператор Выполнить() не нужен. Сам объект Запрос по умолчанию принимает любую динамически сформированную строку в конструкторе: Запрос = Новый Запрос(СформированныйТекст);. Прибегать к Выполнить() имеет смысл только в случаях, когда из внешнего источника поступает законченный алгоритм обработки данных на встроенном языке.
← На главную