Работа с запросами в 1С:Предприятие — неотъемлемая часть разработки, но иногда требуется получить текстовое представление запроса для отладки, логирования или динамического выполнения. Например, при передаче запроса в API, сохранении в журнал или анализе производительности. В этой статье разберём все способы преобразования объекта Запрос в строку, включая нюансы работы с параметрами и временными таблицами.

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

1. Базовый метод: использование свойства Текст

Самый простой способ получить строку запроса — обратиться к свойству Текст объекта Запрос. Этот метод подходит для статических запросов без параметров:

```1c

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

Запрос.Текст = "ВЫБРАТЬ

| Номенклатура.Наименование,

| СУММА(ДокументСклад.Количество) КАК Количество

|ИЗ

| Документ.ПоступлениеТоваров КАК ДокументСклад

|ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура

|ПО ДокументСклад.Номенклатура = Номенклатура.Ссылка

|СГРУППИРОВАТЬ ПО Номенклатура.Наименование";

ТекстЗапроса = Запрос.Текст;

// Результат: полный текст запроса с переносами строк

```

⚠️ Внимание: Этот метод вернёт только исходный текст без подставленных значений параметров. Если запрос содержит параметры (например, ГДЕ Дата > &ДатаНачала), в строке останутся плейсхолдеры &ИмяПараметра.

  • ✅ Простота использования
  • ✅ Сохраняет форматирование
  • ❌ Не подставляет значения параметров
  • ❌ Не работает с динамически сформированными запросами
📊 Какой способ преобразования запроса в строку вы используете чаще?
Свойство Текст
Метод ПолучитьТекст()
КонструкторЗапроса
Свой вариант

2. Метод ПолучитьТекст() для запросов с параметрами

Для запросов с параметрами лучше использовать метод ПолучитьТекст(), который возвращает текст с подставленными значениями. Это актуально для отладки, когда нужно увидеть финальный SQL-подобный запрос:

```1c

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

Запрос.Текст = "ВЫБРАТЬ

| Клиенты.Наименование,

| Документы.Дата

|ИЗ

| Справочник.Клиенты КАК Клиенты

|ЛЕВОЕ СОЕДИНЕНИЕ Документ.ЗаказыКлиентов КАК Документы

|ПО Клиенты.Ссылка = Документы.Клиент

|ГДЕ Документы.Дата > &ДатаНачала";

Запрос.УстановитьПараметр("ДатаНачала", НачалоДня(ТекущаяДата()));

ТекстСПараметрами = Запрос.ПолучитьТекст();

// Результат: "...ГДЕ Документы.Дата > '2026-05-15 00:00:00'"

```

Ключевое отличие от свойства Текст: метод ПолучитьТекст() заменяет плейсхолдеры &ИмяПараметра на фактические значения, что критично для анализа реально выполняемого запроса.

💡

Если параметр имеет сложный тип (например, массив или ссылка), в тексте запроса он будет представлен как временная таблица с уникальным именем (например, #Т1).

Способ Поддерживает параметры Форматирование Применение
Запрос.Текст ❌ Нет ✅ Сохраняет Простые статичные запросы
ПолучитьТекст() ✅ Да ✅ Сохраняет Отладка, логирование
КонструкторЗапроса ✅ Да ❌ Теряет Динамическое формирование

3. Динамическое формирование строки через КонструкторЗапроса

Когда запрос строится программно с использованием КонструктораЗапроса, получить его текстовое представление можно через метод Выгрузить(). Это актуально для сложных запросов, собираемых из отдельных частей:

```1c

Конструктор = Новый КонструкторЗапроса;

Конструктор.ИсточникиДанных.Добавить("Справочник.Номенклатура");

Конструктор.Выбрать.Добавить("Наименование");

Конструктор.Выбрать.Добавить("Артикул");

Конструктор.Условия.Добавить("ПометкаУдаления", ЗначениеЗаполнено(), Сравнение.Равно, Ложь);

ТекстЗапроса = Конструктор.Выгрузить().Текст;

// Результат: "ВЫБРАТЬ Номенклатура.Наименование, Номенклатура.Артикул ИЗ Справочник.Номенклатура КАК Номенклатура ГДЕ Номенклатура.ПометкаУдаления = ЛОЖЬ"

```

⚠️ Внимание: Метод Выгрузить() возвращает объект типа Запрос, у которого уже можно взять свойство Текст. При этом все условия и поля будут сгенерированы в виде единой строки без переносов.

Убедиться, что все источники данных добавлены|Проверить корректность условий отбора|Установить все необходимые параметры|Проверьте синтаксис финальной строки-->

4. Работа с временными таблицами и сложными конструкциями

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

```1c

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

Запрос.Текст = "ВЫБРАТЬ

| Товары.Наименование,

| Остатки.КоличествоОстаток

|ИЗ

| ВТОстаткиТоваров(&ДатаОтчета, ) КАК Остатки

|ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Товары

|ПО Остатки.Номенклатура = Товары.Ссылка";

Запрос.УстановитьПараметр("ДатаОтчета", ТекущаяДата());

// Получаем текст с подставленными временными таблицами

ТекстЗапроса = Запрос.ПолучитьТекст();

// В результате временная таблица будет заменена на #Т1, #Т2 и т.д.

```

Временные таблицы в тексте запроса обозначаются как #Т{Номер} (например, #Т1). Их содержимое не отображается в строке — только ссылка на псевдоним. Для полного анализа такого запроса потребуется отдельно выгружать данные временных таблиц.

Как выгрузить данные временной таблицы?

Чтобы увидеть содержимое временной таблицы (например, #Т1), используйте отдельный запрос к системной таблице v8temp (для SQL-версии 1С):

ВЫБРАТЬ * ИЗ #Т1

Или сохраните данные временной таблицы в физическую таблицу базы перед выполнением основного запроса.

5. Преобразование запроса в строку для внешних систем

При интеграции с внешними системами (например, передача запроса в REST API) часто требуется строгое форматирование без переносов и лишних пробелов. Для этого можно использовать регуляные выражения:

```1c

ТекстЗапроса = Запрос.ПолучитьТекст();

// Удаляем переносы и лишние пробелы

ТекстДляAPI = СтрЗаменить(ТекстЗапроса, Символы.ПС, " ");

ТекстДляAPI = СтрЗаменить(ТекстДляAPI, Символы.ВК, " ");

ТекстДляAPI = СтрЗаменить(ТекстДляAPI, " ", " "); // Двойные пробелы

ТекстДляAPI = СокрЛП(ТекстДляAPI); // Удаляем пробелы в начале/конце

```

Для передачи в JSON или XML дополнительно экранируйте специальные символы:

```1c

ТекстДляJSON = СтрШаблон("""%1""", ТекстДляAPI);

// или для XML:

ТекстДляXML = СтрЗаменить(ТекстДляAPI, """", """);

```

  • 📌 Для REST API часто требуется URL-энкодинг: используйте СтрЗаменить() для символов +, %, =
  • 🔄 При обмене с PostgreSQL или MS SQL учитывайте различия в синтаксисе (например, кавычки для имён полей)
  • 🛡️ Для безопасной передачи используйте Base64Строка():

```1c

ЗакодированныйЗапрос = Base64Строка(ТекстЗапроса);

// Декодируется на стороне получателя: Base64Значение(ЗакодированныйЗапрос)

```

6. Логирование запросов для отладки производительности

При анализе медленных запросов полезно сохранять их текст в журнал с метками времени. Пример функции для логирования:

```1c

Процедура ЗаписатьЗапросВЖурнал(Запрос, ИмяМетода = "") Экспорт

ТекстЗапроса = Запрос.ПолучитьТекст();

ТекстЛога = СтрШаблон(

"=== ЗАПРОС [%1] ===%2%3=== КОНЕЦ ЗАПРОСА ===",

?(ИмяМетода <> "", ИмяМетода, "БезИмени"),

Символы.ПС,

ТекстЗапроса

);

ЗаписьЖурналаРегистрации(ТекстЛога, УровеньЖурнала.Информация, , , "Запросы1С");

КонецПроцедуры

```

Для анализа времени выполнения добавьте замер:

```1c

Начало = ТекущаяДатаВремя();

Результат = Запрос.Выполнить();

Конец = ТекущаяДатаВремя();

Длительность = Конец - Начало;

ЗаписатьЗапросВЖурнал(Запрос, СтрШаблон("Время=%1мс", Длительность * 1000));

```

⚠️ Внимание: Логирование всех запросов в рабочей базе может значительно увеличить нагрузку на сервер. Используйте этот метод только для отладки или на тестовых копиях.

💡

Для анализа производительности важно логировать не только текст запроса, но и значения параметров, а также время выполнения.

7. Ошибки и ограничения при преобразовании в строку

При работе с преобразованием запросов в строки возможны типичные ошибки:

  1. Пропущенные параметры: Если не установить параметр через УстановитьПараметр(), метод ПолучитьТекст() вернёт ошибку.
  2. Слишком длинные запросы: В 1С:Предприятие 8.3 ограничение на длину строки — 260 символов для имени временной таблицы. При превышении возникнет исключение.
  3. Несовместимость синтаксиса: Запросы с конструкциями, специфичными для управляемых форм (например, ВЫБРАТЬ РАЗРЕШЕННЫЕ), не всегда корректно преобразуются в строку.

Пример обработки ошибок:

```1c

Попытка

ТекстЗапроса = Запрос.ПолучитьТекст();

Исключение

Сообщить(ОписаниеОшибки());

ТекстЗапроса = "ОШИБКА: " + ОписаниеОшибки();

КонецПопытки;

```

💡

Для отладки сложных запросов используйте Консоль запросов в режиме Отладка — она показывает финальный текст запроса с подставленными параметрами.

Часто задаваемые вопросы
Можно ли получить текст запроса после выполнения метода Выполнить()?

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

Как преобразовать запрос в строку с сохранением отступов для документации?

Используйте СтрЗаменить() для замены символов табуляции и переносов на HTML-теги (<br>,  ) или Markdown-разметку.

Почему в тексте запроса отображаются #Т1, #Т2 вместо реальных данных?

Это временные таблицы, создаваемые для параметров сложных типов (массивы, таблицы значений). Их содержимое не отображается в строке — только ссылка.

Как передать запрос в строку в внешнюю систему, если он содержит русские символы?

Используйте кодировку UTF-8 и функцию СтрВКодировкеВнутр():

ТекстUTF8 = СтрВКодировкеВнутр(ТекстЗапроса, "UTF-8");
Можно ли из строки снова создать объект Запрос?

Да, но только если строка содержит корректный синтаксис:

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

При этом параметры придётся устанавливать заново.