Запуск запроса в 1С 8.3: консоль, конфигуратор и код
Содержание
Запустить запрос в 1С можно тремя путями: внешней обработкой «Консоль запросов» в режиме 1С:Предприятие, окном вычисления выражений в отладчике Конфигуратора и программно — объектом Запрос в коде модуля. Для разовой проверки текста запроса подойдёт консоль, для отладки боевого алгоритма — отладчик, а в рабочем решении запрос всегда выполняется из кода.
Ниже — как это сделать в каждом варианте: где взять консоль, как увидеть результат прямо в отладчике, как собрать объект Запрос, передать параметры с правильными типами и понять, почему запрос работает медленно.
Коротко, какой способ под какую задачу:
| Способ | Когда применять | Что нужно |
|---|---|---|
| Консоль запросов | Разовая проверка текста, подбор отбора, конструктор | Внешняя обработка, права на её открытие |
| Отладчик Конфигуратора | Запрос уже в коде, нужно увидеть его результат на данных | Включённая отладка, права конфигуратора |
Объект Запрос в коде | Рабочее решение, регулярное выполнение | Модуль конфигурации или расширения |
Консоль запросов в режиме 1С:Предприятие
«Консоль запросов» — это внешняя обработка (.epf), которую подключают к рабочей базе. Своей консоли в стандартной поставке платформы нет, обработка входит в комплект инструментов разработчика на диске ИТС и в типовых поставках как дополнительная обработка.
Порядок действий:
- Откройте базу в режиме
1С:Предприятие. - Меню
Файл → Открытьи укажите файл обработкиКонсольЗапросов.epf. - В поле текста запроса введите или вставьте текст.
- Нажмите
F8или кнопку «Выполнить» — результат появится в нижней таблице.
Если в вашей базе включён «Профиль безопасности», открытие внешних обработок может быть запрещено администратором. Тогда обработку подключают через НСИ и администрирование → Печатные формы, отчёты и обработки → Дополнительные отчёты и обработки с правами администратора.
Консоль удобна тем, что рядом с полем запроса есть конструктор запроса (кнопка «Конструктор»), а параметры она определяет из текста автоматически и предлагает заполнить их значениями из базы. Это самый быстрый способ проверить, что ВЫБРАТЬ возвращает именно то, что вы ждёте, не трогая код конфигурации.
Если язык запросов пока в новинку, начинайте не с чистого текста, а с конструктора: он показывает дерево метаданных — все справочники, документы, регистры и их поля. Поля перетаскивают в таблицы запроса мышью, задают соединения и условия, а готовый текст конструктор собирает сам. Потом этот текст уже правят руками — так быстрее запоминаются имена таблиц и синтаксис секций.
Выполняйте в консоли только запросы на выборку. Платформенный язык запросов 1С не умеет изменять данные — он только читает их, поэтому «сломать» базу запросом нельзя. Но тяжёлый запрос в рабочей базе в разгар дня нагрузит сервер СУБД, поэтому проверочные прогоны по большим таблицам лучше делать на копии.
Выполнение запроса в отладчике Конфигуратора
В самом Конфигураторе нет отдельного окна «запустить запрос» — запрос выполняется внутри кода, а результат смотрят в отладчике. Это нужно, когда запрос уже написан в модуле и важно увидеть, что он вернул на конкретных данных.
Как получить результат:
- Поставьте точку останова (
F9) на строке послеЗапрос.Выполнить(). - Запустите отладку конфигурации (
F5) или подключитесь к работающему сеансу черезОтладка → Подключение. - Когда выполнение остановится на точке, откройте окно «Вычислить выражение» (
Shift + F9). - Введите выражение
Результат.Выгрузить()и нажмите «Рассчитать».
В нижней части окна «Вычислить выражение» появится таблица значений — её можно развернуть по колонкам и строкам. Так вы увидите реальный результат, не добавляя в код временный вывод в сообщения.
Чтобы отладка в режиме предприятия заработала, в конфигурации должна быть включена возможность отладки: Сервис → Параметры → Запуск 1С:Предприятия → Отладка, галка «Разрешить отладку». Для серверной базы отладку по протоколу HTTP включают при запуске сервиса.
Второй приём — окно «Табло» (Отладка → Табло). В него перетаскивают переменную Результат или добавляют выражение Запрос.Выполнить().Выгрузить(), и значение обновляется на каждом шаге. Табло удобнее, когда нужно следить сразу за несколькими переменными.
Программный запуск запроса в коде
В рабочем решении запрос выполняется из кода — в модуле объекта, формы, общем модуле или обработчике. Схема всегда одинаковая: создать объект, задать текст, установить параметры, выполнить, обойти результат.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Остатки.Номенклатура КАК Номенклатура,
| Остатки.КоличествоОстаток КАК Количество
|ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки(&Дата, Склад = &Склад) КАК Остатки";
Запрос.УстановитьПараметр("Дата", ТекущаяДата());
Запрос.УстановитьПараметр("Склад", ВыбранныйСклад);
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
Сообщить(Выборка.Номенклатура.Наименование + ": " + Выборка.Количество);
КонецЦикла;
Разберём, что здесь делает каждый метод:
Новый Запрос— создаёт объект. Текст можно передать сразу:Новый Запрос(ТекстЗапроса).Выполнить()— отправляет запрос в СУБД и возвращаетРезультатЗапроса.Выбрать()— даёт выборку для построчного обхода.Выгрузить()— складывает весь результат в таблицу значений за один вызов.
Когда строк немного и они нужны целиком, короче Выгрузить():
Таблица = Запрос.Выполнить().Выгрузить();
Для Каждого Строка Из Таблица Цикл
Сообщить(Строка.Номенклатура);
КонецЦикла;
Если нужно выполнить несколько запросов подряд (например, сначала создать временную таблицу, потом читать из неё), используют пакет. Текст запросов разделяют точкой с запятой, а выполняют методом ВыполнитьПакет() — он возвращает массив результатов по каждому запросу пакета.
Текст запроса не собирайте склейкой строк с подстановкой значений. Для этого есть параметры: так запрос кэшируется на стороне СУБД и не ломается на спецсимволах.
Если запрос содержит итоги по уровням (ИТОГИ … ПО), результат обходят по группировкам. Метод Выбрать() принимает параметр способа обхода:
Выборка = Результат.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока Выборка.Следующий() Цикл
Сообщить("Группа: " + Выборка.Склад + ", итого: " + Выборка.Количество);
ВыборкаСтрок = Выборка.Выбрать();
Пока ВыборкаСтрок.Следующий() Цикл
Сообщить(" " + ВыборкаСтрок.Номенклатура);
КонецЦикла;
КонецЦикла;
Внешний цикл идёт по группам, вложенный Выбрать() — по детальным строкам внутри каждой группы. Так из одного запроса разворачивают двухуровневый отчёт без повторного обращения к базе.
Параметры запроса и типы данных
Параметр в тексте запроса обозначается амперсандом: &Дата, &Склад, &Контрагент. Значение задают методом УстановитьПараметр("ИмяБезАмперсанда", Значение). Имя пишут без &.
Главное правило — тип значения параметра должен совпадать с типом поля, с которым идёт сравнение. Распространённые ошибки:
- в параметр ссылочного поля передают строку с наименованием, а не саму ссылку на элемент справочника;
- дату передают строкой
"01.01.2026"вместо значения типаДата; - в параметр булева поля кладут число
1вместоИстина.
Для списка значений в условии В (&Список) передают массив, список значений или таблицу — платформа развернёт их сама:
МассивНоменклатуры = Новый Массив;
МассивНоменклатуры.Добавить(Товар1);
МассивНоменклатуры.Добавить(Товар2);
Запрос.Текст = "ВЫБРАТЬ Ссылка ИЗ Справочник.Номенклатура
|ГДЕ Ссылка В (&Список)";
Запрос.УстановитьПараметр("Список", МассивНоменклатуры);
Параметры виртуальных таблиц (остатки, обороты, срез последних) передаются не методом УстановитьПараметр, а прямо в скобках после имени таблицы: Остатки(&НаДату, Организация = &Организация). Первый параметр — момент времени, второй — условие отбора. Это частая путаница: условие по складу или организации для регистра лучше ставить именно в параметры виртуальной таблицы, а не в секцию ГДЕ — так отбор отрабатывает до агрегации, и запрос быстрее.
Если параметр объявлен в тексте, но значение не установлено, платформа подставит NULL. Запрос при этом не упадёт, но вернёт пустой результат — и причину долго ищут. Проверяйте, что все &Параметры заполнены.
С датами в параметрах виртуальных таблиц важна граница. Остатки «на конец дня» берут на момент КонецДня(ДатаОтчёта), иначе движения, сделанные в этот день, в результат не попадут. Для оборотов задают две границы — начало и конец периода, причём конец тоже выравнивают на КонецДня, чтобы захватить последние сутки целиком. Передача «голой» даты без выравнивания времени — типичная причина, когда в отчёте не хватает последнего дня.
Замер производительности и анализ выполнения
Запрос, который «подвисает», разбирают по шагам. Сначала измеряют, где уходит время, потом смотрят, как СУБД его выполняет.
Замер времени в отладчике. Запустите отладку и включите Отладка → Замер производительности. Платформа покажет таблицу: сколько раз вызвана каждая строка кода и сколько суммарно заняла. Строка с Выполнить() сразу покажет долю запроса в общем времени процедуры.
Технологический журнал. Для серверной базы включают событие DBMSSQL в технологическом журнале — в лог попадает текст запроса, уже переведённый на язык СУБД, с длительностью в микросекундах. Так видно, какой именно запрос тяжёлый, когда их в процедуре несколько.
План выполнения на уровне СУБД. Собственно план (какие индексы и соединения использует СУБД) платформа не показывает — его снимают средствами самой СУБД. Для MS SQL Server это SQL Server Profiler или свойство «Включить фактический план выполнения» в SQL Server Management Studio: текст запроса из техжурнала выполняют в студии и смотрят, где идёт полный перебор таблицы вместо поиска по индексу.
На что обращать внимание в тексте запроса, не доходя до профайлера:
- соединения с подзапросами и вложенными виртуальными таблицами — их СУБД не всегда оптимизирует;
- отбор в
ГДЕпо полю соединённой таблицы вместо условия в самом соединении; ВЫБРАТЬ *и лишние поля, которые тянут данные, не нужные результату;- обращение через точку к реквизитам ссылки (
Номенклатура.Поставщик.ИНН) в больших выборках — каждое такое обращение превращается в неявное соединение.
Переписать тяжёлый запрос часто помогает временная таблица: вынести предварительный отбор в ПОМЕСТИТЬ ВременнаяТаблица, проиндексировать нужное поле (ИНДЕКСИРОВАТЬ ПО) и соединять уже с ней. Для работы временных таблиц объекту Запрос назначают менеджер временных таблиц: Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц. Тогда таблица, помещённая первым запросом пакета, доступна следующим.
Ещё один приём — объединять однотипные выборки через ОБЪЕДИНИТЬ ВСЕ, а не выполнять несколько отдельных запросов в цикле. Один запрос к СУБД почти всегда дешевле, чем десяток мелких: каждый вызов Выполнить() — это отдельное обращение к серверу базы данных.
Частые ошибки при выполнении запроса
УстановитьПараметр для объявленного &Параметра. Результат пустой или ошибка типа.ГДЕ вместо параметра виртуальной таблицы, соединение с подзапросом, обращение к реквизитам через точку в большой выборке. Разберите через техжурнал и временные таблицы.СГРУППИРОВАТЬ ПО. Либо оберните его в СУММ/МАКСИМУМ, либо добавьте в группировку.&Дата указывает на момент раньше первых движений, либо соединение ВНУТРЕННЕЕ отбросило строки без пары. Проверьте границы периода и тип соединения.Отдельно про тип соединения. ВНУТРЕННЕЕ СОЕДИНЕНИЕ оставляет только строки, у которых есть пара в обеих таблицах. Если ждёте все строки левой таблицы (а правая может быть пустой) — нужно ЛЕВОЕ СОЕДИНЕНИЕ, иначе часть данных «пропадает» без ошибки.
Частые вопросы
Можно ли запросом изменить или удалить данные в 1С?
UPDATE или DELETE в нём нет. Изменяют данные через объектную модель (запись документов, наборов записей регистров), а запрос лишь готовит выборку для этой обработки.Чем отличается `Выбрать()` от `Выгрузить()`?
Выбрать() даёт курсор для построчного обхода в цикле Пока … Следующий() — экономит память на больших результатах. Выгрузить() сразу кладёт весь результат в таблицу значений, с которой удобно работать как с коллекцией. Для сотен тысяч строк берите Выбрать().Где взять обработку «Консоль запросов»?
Нужны ли права разработчика, чтобы выполнить запрос?
Как передать в запрос список значений?
Массив или СписокЗначений, заполните его и установите в параметр, который стоит в условии В (&Параметр). Платформа сама развернёт коллекцию в список для СУБД.