Разработка и Конфигурация · 9 мин
Как выразить запрос 1С как строку
Как преобразовать запрос 1С в строку: Запрос.Текст, консоль запросов, получение текста из схемы СКД и отладка. Примеры кода и типичные ошибки.
Задача «выразить запрос 1С как строку» возникает в нескольких ситуациях: нужно получить текст уже созданного объекта Запрос, сформировать текст запроса динамически в виде строки, извлечь запрос из схемы компоновки данных или передать текст запроса между процедурами. Во всех случаях речь идёт о работе со строковым представлением текста на языке запросов 1С.
Язык запросов 1С — это декларативный язык, похожий на SQL, но со своими особенностями: виртуальные таблицы, параметры с амперсандом, иерархия, разрезы итогов. Текст запроса в конфигураторе хранится как обычная строка, поэтому его можно читать, изменять и собирать программно. Ниже разобраны основные способы получения и формирования такой строки, а также типичные ошибки.
Что такое текст запроса как строка в 1С
Объект встроенного языка «Запрос» имеет свойство Текст типа Строка. Именно в нём хранится весь текст запроса: секции ВЫБРАТЬ, ИЗ, ГДЕ, СГРУППИРОВАТЬ ПО, УПОРЯДОЧИТЬ ПО и другие. Присвоив этой строке значение, вы задаёте запрос; прочитав её — получаете текущий текст.
Важно понимать разницу между тремя вещами, которые часто путают: текст запроса (строка на языке запросов), результат запроса (таблица значений или выборка) и представление результата в виде строки. Запрос «выразить как строку» обычно означает первое — получить именно исходный текст, а не данные.
Получение текста из объекта Запрос
Самый простой сценарий — запрос уже создан, и нужно получить его текст как строку, например для записи в журнал, передачи в другую функцию или сравнения. Для этого достаточно прочитать свойство Текст:
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ Номенклатура.Ссылка ИЗ Справочник.Номенклатура КАК Номенклатура";
ТекстКакСтрока = Запрос.Текст; // строка с текстом запроса
Если запрос был создан через конструктор запроса в модуле, текст уже находится в свойстве Текст после инициализации — дополнительных действий не требуется. Обратите внимание: свойство возвращает строку в том виде, в каком она была присвоена, включая переносы строк и отступы.
Для запросов, заданных через построитель запроса (объект ПостроительЗапроса), текст формируется автоматически и доступен через ПостроительЗапроса.Текст после вызова метода ЗаполнитьНастройки или установки свойств построителя.
Извлечение текста запроса из схемы компоновки данных
В отчётах на СКД текст запроса хранится внутри схемы, а не в объекте Запрос. Чтобы получить его как строку, нужно обратиться к набору данных типа «Запрос»:
Схема = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
ТекстЗапроса = Схема.НаборыДанных[0].Запрос;
Этот приём полезен при отладке отчётов: можно вывести текст запроса в сообщение, скопировать в консоль запросов и проверить, какие данные фактически выбираются. Если в схеме несколько наборов данных, перебирайте коллекцию НаборыДанных и проверяйте тип каждого элемента — свойство Запрос есть только у наборов типа «Запрос».
Аналогично текст можно извлечь из динамического списка: в форме списка через свойство ДинамическийСписок.ТекстЗапроса (при установленном флаге произвольного запроса) или программно через реквизит формы типа ДинамическийСписок.
Динамическое формирование текста запроса строкой
Когда структура запроса зависит от условий — например, пользователь выбрал разные отборы — текст собирают конкатенацией строк. Типовой шаблон выглядит так:
ТекстЗапроса = "ВЫБРАТЬ Товары.Ссылка, Товары.Наименование
|ИЗ Справочник.Номенклатура КАК Товары";
Если ЗначениеЗаполнено(ОтборПоГруппе) Тогда
ТекстЗапроса = ТекстЗапроса + "
|ГДЕ Товары.Родитель = &Группа";
КонецЕсли;
Запрос = Новый Запрос(ТекстЗапроса);
Используйте вертикальную черту в начале каждой строки литерала — это стандартный способ записи многострочных строк во встроенном языке. Переносы внутри текста запроса не влияют на его выполнение, но делают строку читаемой при выводе в сообщения или журнал.
Параметры всегда передавайте через УстановитьПараметр, а не подстановкой значений прямо в строку. Подстановка строковых значений в текст запроса конкатенацией — частая причина ошибок синтаксиса (незакрытые кавычки) и потенциальная уязвимость, если значение приходит от пользователя.
Использование консоли запросов и конструктора
Конструктор запроса в конфигураторе работает в обе стороны: он не только строит текст визуально, но и разбирает существующую строку. Если у вас есть текст запроса в виде строки, вставьте его в конструктор — получите наглядную структуру таблиц, связей и полей, которую удобно править.
Внешние консоли запросов (обработки с диска ИТС или аналоги) позволяют вставить строку текста, заполнить параметры и сразу увидеть результат. Это основной инструмент проверки динамически сформированных запросов: скопируйте значение переменной ТекстЗапроса из отладчика (через «Вычислить выражение») и выполните его в консоли.
Учтите ограничение конструктора: он не понимает запросы с инструкциями СКД в фигурных скобках и некоторые редкие конструкции. Если конструктор отказывается открывать текст, это не всегда означает ошибку в запросе — проверьте текст выполнением.
Преобразование результата запроса в строку
Иногда под «выразить запрос как строку» понимают другое: получить результат выполнения в строковом виде, например одно значение одного поля. Для этого запрос выполняют, выбирают строку и обращаются к полю:
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
РезультатСтрокой = Строка(Выборка.Наименование);
КонецЕсли;
Если нужно собрать несколько значений в одну строку — например, список артикулов через запятую — используйте цикл по выборке с накоплением в переменной-строке и разделителем. Для больших объёмов эффективнее собирать значения в массив и соединять через СтрСоединить, чем многократно конкатенировать строки.
Помните, что функция Строка() для ссылочных типов возвращает представление объекта, а не уникальный идентификатор. Если нужен именно GUID ссылки, используйте XMLСтрока(Ссылка) или Ссылка.УникальныйИдентификатор().
Как проверить результат
Видна полная инструкция ВЫБРАТЬ...ИЗ... без обрывов
Строка пустая или обрезана — проверьте момент чтения свойства Текст
Запрос выполняется без исключения, результат содержит ожидаемые строки
Ошибка синтаксиса — ищите пропущенные пробелы на стыках конкатенации
Все параметры из текста (&Имя) установлены через УстановитьПараметр
Ошибка «Параметр не найден» — значит параметр объявлен в тексте, но не установлен
Безопасность и ограничения при работе со строками запросов
Динамическая сборка текста запроса — мощный, но рискованный приём. Главное правило: никогда не вставляйте в текст запроса данные, введённые пользователем, без параметров. Платформа 1С не допускает классических SQL-инъекций в полном объёме (запрос не может содержать нескольких инструкций), но подстановка строк может сломать синтаксис или изменить логику отбора.
Ещё одно ограничение: нельзя динамически подставлять имена таблиц и полей через параметры — параметры работают только для значений. Если имя таблицы должно выбираться по условию, формируйте текст конкатенацией, но строго из заранее заданного списка допустимых имён, а не из произвольного ввода.
При изменении текста запроса в рабочей базе через внешние обработки помните: ошибка в тексте проявится только в момент выполнения. Всегда тестируйте динамически сформированный запрос на копии базы или в консоли запросов до включения кода в рабочий функционал.
Что важно запомнить
Текст запроса — обычная строка в свойстве Запрос.Текст. Из СКД его берут через НаборыДанных[0].Запрос, динамически собирают конкатенацией с вертикальной чертой. Значения передавайте только параметрами, а результат проверяйте в консоли запросов.
Частые вопросы
Как вывести текст запроса в сообщение для отладки?
Вызовите Сообщить(Запрос.Текст) после присвоения текста и до выполнения. В режиме отладки удобнее использовать «Вычислить выражение» на переменной запроса и раскрыть свойство Текст — так видно строку целиком, включая переносы.
Можно ли выполнить запрос, текст которого хранится в строковой переменной?
Да. Создайте объект через Новый Запрос(ТекстСтрокой) или присвойте строку свойству Текст, установите параметры и вызовите Выполнить(). Никакой специальной компиляции строки не требуется.
Почему текст запроса из СКД не выполняется в консоли запросов?
Скорее всего, в тексте есть инструкции компоновки данных в фигурных скобках — например, {ГДЕ (...)} или {ВЫБРАТЬ ...}. Удалите эти секции или используйте консоль, поддерживающую расширение языка запросов для СКД.
Как передать список значений в запрос строкой?
Напрямую строкой — никак. Передайте массив или список значений через УстановитьПараметр, а в тексте используйте условие В (&Список). Платформа сама развернёт коллекцию в перечень значений.
Чем отличается Запрос.Текст от ПостроительЗапроса.Текст?
Запрос.Текст — это текст, который вы задали сами. ПостроительЗапроса.Текст формируется автоматически из настроек построителя (выбранные поля, отборы, порядок) и обновляется при изменении настроек.
Как получить строковое представление GUID ссылки из запроса?
Выберите ссылку в запросе, затем в коде примените XMLСтрока(Ссылка) — получится строка вида уникального идентификатора. Обратное преобразование выполняется через XMLЗначение с указанием типа.