Запуск запроса в 1С 8.3: консоль, конфигуратор и код

· 9 мин

Содержание

Запустить запрос в 1С можно тремя путями: внешней обработкой «Консоль запросов» в режиме 1С:Предприятие, окном вычисления выражений в отладчике Конфигуратора и программно — объектом Запрос в коде модуля. Для разовой проверки текста запроса подойдёт консоль, для отладки боевого алгоритма — отладчик, а в рабочем решении запрос всегда выполняется из кода.

Ниже — как это сделать в каждом варианте: где взять консоль, как увидеть результат прямо в отладчике, как собрать объект Запрос, передать параметры с правильными типами и понять, почему запрос работает медленно.

Коротко, какой способ под какую задачу:

СпособКогда применятьЧто нужно
Консоль запросовРазовая проверка текста, подбор отбора, конструкторВнешняя обработка, права на её открытие
Отладчик КонфигуратораЗапрос уже в коде, нужно увидеть его результат на данныхВключённая отладка, права конфигуратора
Объект Запрос в кодеРабочее решение, регулярное выполнениеМодуль конфигурации или расширения

Консоль запросов в режиме 1С:Предприятие

«Консоль запросов» — это внешняя обработка (.epf), которую подключают к рабочей базе. Своей консоли в стандартной поставке платформы нет, обработка входит в комплект инструментов разработчика на диске ИТС и в типовых поставках как дополнительная обработка.

Порядок действий:

  1. Откройте базу в режиме 1С:Предприятие.
  2. Меню Файл → Открыть и укажите файл обработки КонсольЗапросов.epf.
  3. В поле текста запроса введите или вставьте текст.
  4. Нажмите F8 или кнопку «Выполнить» — результат появится в нижней таблице.

Если в вашей базе включён «Профиль безопасности», открытие внешних обработок может быть запрещено администратором. Тогда обработку подключают через НСИ и администрирование → Печатные формы, отчёты и обработки → Дополнительные отчёты и обработки с правами администратора.

Консоль удобна тем, что рядом с полем запроса есть конструктор запроса (кнопка «Конструктор»), а параметры она определяет из текста автоматически и предлагает заполнить их значениями из базы. Это самый быстрый способ проверить, что ВЫБРАТЬ возвращает именно то, что вы ждёте, не трогая код конфигурации.

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

Выполняйте в консоли только запросы на выборку. Платформенный язык запросов 1С не умеет изменять данные — он только читает их, поэтому «сломать» базу запросом нельзя. Но тяжёлый запрос в рабочей базе в разгар дня нагрузит сервер СУБД, поэтому проверочные прогоны по большим таблицам лучше делать на копии.

Выполнение запроса в отладчике Конфигуратора

В самом Конфигураторе нет отдельного окна «запустить запрос» — запрос выполняется внутри кода, а результат смотрят в отладчике. Это нужно, когда запрос уже написан в модуле и важно увидеть, что он вернул на конкретных данных.

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

  1. Поставьте точку останова (F9) на строке после Запрос.Выполнить().
  2. Запустите отладку конфигурации (F5) или подключитесь к работающему сеансу через Отладка → Подключение.
  3. Когда выполнение остановится на точке, откройте окно «Вычислить выражение» (Shift + F9).
  4. Введите выражение Результат.Выгрузить() и нажмите «Рассчитать».

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

Чтобы отладка в режиме предприятия заработала, в конфигурации должна быть включена возможность отладки: Сервис → Параметры → Запуск 1С:Предприятия → Отладка, галка «Разрешить отладку». Для серверной базы отладку по протоколу HTTP включают при запуске сервиса.

Второй приём — окно «Табло» (Отладка → Табло). В него перетаскивают переменную Результат или добавляют выражение Запрос.Выполнить().Выгрузить(), и значение обновляется на каждом шаге. Табло удобнее, когда нужно следить сразу за несколькими переменными.

Программный запуск запроса в коде

В рабочем решении запрос выполняется из кода — в модуле объекта, формы, общем модуле или обработчике. Схема всегда одинаковая: создать объект, задать текст, установить параметры, выполнить, обойти результат.

Запрос = Новый Запрос;
Запрос.Текст =
    "ВЫБРАТЬ
    |    Остатки.Номенклатура КАК Номенклатура,
    |    Остатки.КоличествоОстаток КАК Количество
    |ИЗ
    |    РегистрНакопления.ТоварыНаСкладах.Остатки(&Дата, Склад = &Склад) КАК Остатки";

Запрос.УстановитьПараметр("Дата", ТекущаяДата());
Запрос.УстановитьПараметр("Склад", ВыбранныйСклад);

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

Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
    Сообщить(Выборка.Номенклатура.Наименование + ": " + Выборка.Количество);
КонецЦикла;

Разберём, что здесь делает каждый метод:

  • Новый Запрос — создаёт объект. Текст можно передать сразу: Новый Запрос(ТекстЗапроса).
  • Выполнить() — отправляет запрос в СУБД и возвращает РезультатЗапроса.
  • Выбрать() — даёт выборку для построчного обхода.
  • Выгрузить() — складывает весь результат в таблицу значений за один вызов.

Когда строк немного и они нужны целиком, короче Выгрузить():

Таблица = Запрос.Выполнить().Выгрузить();
Для Каждого Строка Из Таблица Цикл
    Сообщить(Строка.Номенклатура);
КонецЦикла;

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

Текст запроса не собирайте склейкой строк с подстановкой значений. Для этого есть параметры: так запрос кэшируется на стороне СУБД и не ломается на спецсимволах.

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

Выборка = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока Выборка.Следующий() Цикл
    Сообщить("Группа: " + Выборка.Склад + ", итого: " + Выборка.Количество);
    ВыборкаСтрок = Выборка.Выбрать();
    Пока ВыборкаСтрок.Следующий() Цикл
        Сообщить("   " + ВыборкаСтрок.Номенклатура);
    КонецЦикла;
КонецЦикла;

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

Параметры запроса и типы данных

Параметр в тексте запроса обозначается амперсандом: &Дата, &Склад, &Контрагент. Значение задают методом УстановитьПараметр("ИмяБезАмперсанда", Значение). Имя пишут без &.

Главное правило — тип значения параметра должен совпадать с типом поля, с которым идёт сравнение. Распространённые ошибки:

  • в параметр ссылочного поля передают строку с наименованием, а не саму ссылку на элемент справочника;
  • дату передают строкой "01.01.2026" вместо значения типа Дата;
  • в параметр булева поля кладут число 1 вместо Истина.

Для списка значений в условии В (&Список) передают массив, список значений или таблицу — платформа развернёт их сама:

МассивНоменклатуры = Новый Массив;
МассивНоменклатуры.Добавить(Товар1);
МассивНоменклатуры.Добавить(Товар2);

Запрос.Текст = "ВЫБРАТЬ Ссылка ИЗ Справочник.Номенклатура
               |ГДЕ Ссылка В (&Список)";
Запрос.УстановитьПараметр("Список", МассивНоменклатуры);

Параметры виртуальных таблиц (остатки, обороты, срез последних) передаются не методом УстановитьПараметр, а прямо в скобках после имени таблицы: Остатки(&НаДату, Организация = &Организация). Первый параметр — момент времени, второй — условие отбора. Это частая путаница: условие по складу или организации для регистра лучше ставить именно в параметры виртуальной таблицы, а не в секцию ГДЕ — так отбор отрабатывает до агрегации, и запрос быстрее.

Если параметр объявлен в тексте, но значение не установлено, платформа подставит NULL. Запрос при этом не упадёт, но вернёт пустой результат — и причину долго ищут. Проверяйте, что все &Параметры заполнены.

С датами в параметрах виртуальных таблиц важна граница. Остатки «на конец дня» берут на момент КонецДня(ДатаОтчёта), иначе движения, сделанные в этот день, в результат не попадут. Для оборотов задают две границы — начало и конец периода, причём конец тоже выравнивают на КонецДня, чтобы захватить последние сутки целиком. Передача «голой» даты без выравнивания времени — типичная причина, когда в отчёте не хватает последнего дня.

Замер производительности и анализ выполнения

Запрос, который «подвисает», разбирают по шагам. Сначала измеряют, где уходит время, потом смотрят, как СУБД его выполняет.

Замер времени в отладчике. Запустите отладку и включите Отладка → Замер производительности. Платформа покажет таблицу: сколько раз вызвана каждая строка кода и сколько суммарно заняла. Строка с Выполнить() сразу покажет долю запроса в общем времени процедуры.

Технологический журнал. Для серверной базы включают событие DBMSSQL в технологическом журнале — в лог попадает текст запроса, уже переведённый на язык СУБД, с длительностью в микросекундах. Так видно, какой именно запрос тяжёлый, когда их в процедуре несколько.

План выполнения на уровне СУБД. Собственно план (какие индексы и соединения использует СУБД) платформа не показывает — его снимают средствами самой СУБД. Для MS SQL Server это SQL Server Profiler или свойство «Включить фактический план выполнения» в SQL Server Management Studio: текст запроса из техжурнала выполняют в студии и смотрят, где идёт полный перебор таблицы вместо поиска по индексу.

На что обращать внимание в тексте запроса, не доходя до профайлера:

  • соединения с подзапросами и вложенными виртуальными таблицами — их СУБД не всегда оптимизирует;
  • отбор в ГДЕ по полю соединённой таблицы вместо условия в самом соединении;
  • ВЫБРАТЬ * и лишние поля, которые тянут данные, не нужные результату;
  • обращение через точку к реквизитам ссылки (Номенклатура.Поставщик.ИНН) в больших выборках — каждое такое обращение превращается в неявное соединение.

Переписать тяжёлый запрос часто помогает временная таблица: вынести предварительный отбор в ПОМЕСТИТЬ ВременнаяТаблица, проиндексировать нужное поле (ИНДЕКСИРОВАТЬ ПО) и соединять уже с ней. Для работы временных таблиц объекту Запрос назначают менеджер временных таблиц: Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц. Тогда таблица, помещённая первым запросом пакета, доступна следующим.

Ещё один приём — объединять однотипные выборки через ОБЪЕДИНИТЬ ВСЕ, а не выполнять несколько отдельных запросов в цикле. Один запрос к СУБД почти всегда дешевле, чем десяток мелких: каждый вызов Выполнить() — это отдельное обращение к серверу базы данных.

Частые ошибки при выполнении запроса

Диагностика: выберите симптом

Отдельно про тип соединения. ВНУТРЕННЕЕ СОЕДИНЕНИЕ оставляет только строки, у которых есть пара в обеих таблицах. Если ждёте все строки левой таблицы (а правая может быть пустой) — нужно ЛЕВОЕ СОЕДИНЕНИЕ, иначе часть данных «пропадает» без ошибки.

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

Можно ли запросом изменить или удалить данные в 1С?
Нет. Язык запросов 1С работает только на чтение — конструкций вроде UPDATE или DELETE в нём нет. Изменяют данные через объектную модель (запись документов, наборов записей регистров), а запрос лишь готовит выборку для этой обработки.
Чем отличается `Выбрать()` от `Выгрузить()`?
Выбрать() даёт курсор для построчного обхода в цикле Пока … Следующий() — экономит память на больших результатах. Выгрузить() сразу кладёт весь результат в таблицу значений, с которой удобно работать как с коллекцией. Для сотен тысяч строк берите Выбрать().
Где взять обработку «Консоль запросов»?
Она входит в комплект инструментов разработчика и в типовые конфигурации как дополнительная обработка. В типовых её открывают через раздел администрирования в списке дополнительных обработок. Если в базе её нет — обработку подключает администратор.
Нужны ли права разработчика, чтобы выполнить запрос?
Для запуска консоли запросов в предприятии права конфигуратора не нужны — хватает прав на открытие внешних обработок и на чтение нужных данных. Отладка же в Конфигураторе требует соответствующих прав и включённой возможности отладки.
Как передать в запрос список значений?
Создайте Массив или СписокЗначений, заполните его и установите в параметр, который стоит в условии В (&Параметр). Платформа сама развернёт коллекцию в список для СУБД.