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

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

Как выразить запрос 1С как строку

Как преобразовать запрос 1С в строку: Запрос.Текст, консоль запросов, получение текста из схемы СКД и отладка. Примеры кода и типичные ошибки.

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

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

Что такое текст запроса как строка в 1С

Объект встроенного языка «Запрос» имеет свойство Текст типа Строка. Именно в нём хранится весь текст запроса: секции ВЫБРАТЬ, ИЗ, ГДЕ, СГРУППИРОВАТЬ ПО, УПОРЯДОЧИТЬ ПО и другие. Присвоив этой строке значение, вы задаёте запрос; прочитав её — получаете текущий текст.

Важно понимать разницу между тремя вещами, которые часто путают: текст запроса (строка на языке запросов), результат запроса (таблица значений или выборка) и представление результата в виде строки. Запрос «выразить как строку» обычно означает первое — получить именно исходный текст, а не данные.

Получение текста из объекта Запрос

Самый простой сценарий — запрос уже создан, и нужно получить его текст как строку, например для записи в журнал, передачи в другую функцию или сравнения. Для этого достаточно прочитать свойство Текст:

Запрос = Новый Запрос;

Запрос.Текст = "ВЫБРАТЬ Номенклатура.Ссылка ИЗ Справочник.Номенклатура КАК Номенклатура";

ТекстКакСтрока = Запрос.Текст; // строка с текстом запроса

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

Для запросов, заданных через построитель запроса (объект ПостроительЗапроса), текст формируется автоматически и доступен через ПостроительЗапроса.Текст после вызова метода ЗаполнитьНастройки или установки свойств построителя.

Извлечение текста запроса из схемы компоновки данных

В отчётах на СКД текст запроса хранится внутри схемы, а не в объекте Запрос. Чтобы получить его как строку, нужно обратиться к набору данных типа «Запрос»:

Схема = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");

ТекстЗапроса = Схема.НаборыДанных[0].Запрос;

Этот приём полезен при отладке отчётов: можно вывести текст запроса в сообщение, скопировать в консоль запросов и проверить, какие данные фактически выбираются. Если в схеме несколько наборов данных, перебирайте коллекцию НаборыДанных и проверяйте тип каждого элемента — свойство Запрос есть только у наборов типа «Запрос».

Аналогично текст можно извлечь из динамического списка: в форме списка через свойство ДинамическийСписок.ТекстЗапроса (при установленном флаге произвольного запроса) или программно через реквизит формы типа ДинамическийСписок.

Динамическое формирование текста запроса строкой

Когда структура запроса зависит от условий — например, пользователь выбрал разные отборы — текст собирают конкатенацией строк. Типовой шаблон выглядит так:

ТекстЗапроса = "ВЫБРАТЬ Товары.Ссылка, Товары.Наименование

|ИЗ Справочник.Номенклатура КАК Товары";

Если ЗначениеЗаполнено(ОтборПоГруппе) Тогда

ТекстЗапроса = ТекстЗапроса + "

|ГДЕ Товары.Родитель = &Группа";

КонецЕсли;

Запрос = Новый Запрос(ТекстЗапроса);

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

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

Типичные ошибки
01
Подстановка значений прямо в текст запроса конкатенацией вместо параметров — приводит к синтаксическим ошибкам и риску инъекций
02
Забытая вертикальная черта в начале строки многострочного литерала — компилятор выдаёт ошибку ещё до выполнения
03
Выполнение текста из СКД с фигурными скобками в обычном Запросе — платформа не распознаёт инструкции компоновки
04
Изменение свойства Текст после вызова Выполнить() без повторного выполнения — результат остаётся от старого текста

Использование консоли запросов и конструктора

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

Внешние консоли запросов (обработки с диска ИТС или аналоги) позволяют вставить строку текста, заполнить параметры и сразу увидеть результат. Это основной инструмент проверки динамически сформированных запросов: скопируйте значение переменной ТекстЗапроса из отладчика (через «Вычислить выражение») и выполните его в консоли.

Учтите ограничение конструктора: он не понимает запросы с инструкциями СКД в фигурных скобках и некоторые редкие конструкции. Если конструктор отказывается открывать текст, это не всегда означает ошибку в запросе — проверьте текст выполнением.

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

Иногда под «выразить запрос как строку» понимают другое: получить результат выполнения в строковом виде, например одно значение одного поля. Для этого запрос выполняют, выбирают строку и обращаются к полю:

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

Если Выборка.Следующий() Тогда

РезультатСтрокой = Строка(Выборка.Наименование);

КонецЕсли;

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

Помните, что функция Строка() для ссылочных типов возвращает представление объекта, а не уникальный идентификатор. Если нужен именно GUID ссылки, используйте XMLСтрока(Ссылка) или Ссылка.УникальныйИдентификатор().

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

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

Текст запроса выведен в сообщение или журнал
Норма

Видна полная инструкция ВЫБРАТЬ...ИЗ... без обрывов

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

Строка пустая или обрезана — проверьте момент чтения свойства Текст

Выполнение динамически собранного текста
Норма

Запрос выполняется без исключения, результат содержит ожидаемые строки

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

Ошибка синтаксиса — ищите пропущенные пробелы на стыках конкатенации

Параметры запроса
Норма

Все параметры из текста (&Имя) установлены через УстановитьПараметр

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

Ошибка «Параметр не найден» — значит параметр объявлен в тексте, но не установлен

Безопасность и ограничения при работе со строками запросов

Динамическая сборка текста запроса — мощный, но рискованный приём. Главное правило: никогда не вставляйте в текст запроса данные, введённые пользователем, без параметров. Платформа 1С не допускает классических SQL-инъекций в полном объёме (запрос не может содержать нескольких инструкций), но подстановка строк может сломать синтаксис или изменить логику отбора.

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

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

Итог

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

Текст запроса — обычная строка в свойстве Запрос.Текст. Из СКД его берут через НаборыДанных[0].Запрос, динамически собирают конкатенацией с вертикальной чертой. Значения передавайте только параметрами, а результат проверяйте в консоли запросов.

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

Как вывести текст запроса в сообщение для отладки?

Вызовите Сообщить(Запрос.Текст) после присвоения текста и до выполнения. В режиме отладки удобнее использовать «Вычислить выражение» на переменной запроса и раскрыть свойство Текст — так видно строку целиком, включая переносы.

Можно ли выполнить запрос, текст которого хранится в строковой переменной?

Да. Создайте объект через Новый Запрос(ТекстСтрокой) или присвойте строку свойству Текст, установите параметры и вызовите Выполнить(). Никакой специальной компиляции строки не требуется.

Почему текст запроса из СКД не выполняется в консоли запросов?

Скорее всего, в тексте есть инструкции компоновки данных в фигурных скобках — например, {ГДЕ (...)} или {ВЫБРАТЬ ...}. Удалите эти секции или используйте консоль, поддерживающую расширение языка запросов для СКД.

Как передать список значений в запрос строкой?

Напрямую строкой — никак. Передайте массив или список значений через УстановитьПараметр, а в тексте используйте условие В (&Список). Платформа сама развернёт коллекцию в перечень значений.

Чем отличается Запрос.Текст от ПостроительЗапроса.Текст?

Запрос.Текст — это текст, который вы задали сами. ПостроительЗапроса.Текст формируется автоматически из настроек построителя (выбранные поля, отборы, порядок) и обновляется при изменении настроек.

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

Выберите ссылку в запросе, затем в коде примените XMLСтрока(Ссылка) — получится строка вида уникального идентификатора. Обратное преобразование выполняется через XMLЗначение с указанием типа.