Разработка и Конфигурация · 11 мин
Как получить результат запроса в 1С
Как получить результат запроса в 1С: методы Выполнить, Выбрать, Выгрузить, обход выборки, проверка на пустоту. Примеры кода, типичные ошибки и ответы на вопросы.
Запрос в 1С — основной инструмент чтения данных из базы. Но написать текст запроса недостаточно: нужно правильно выполнить его и обработать результат. Платформа предлагает несколько способов получить данные — выборка с пошаговым обходом, выгрузка в таблицу значений или дерево, а также прямая проверка на пустоту. Выбор метода влияет на производительность и удобство дальнейшей работы с данными.
В этой статье разобраны все основные сценарии: создание объекта запроса, установка параметров, выполнение, обход результата циклом, выгрузка в таблицу значений, обработка иерархических данных и типичные ошибки, которые приводят к исключениям или неверным данным.
Создание и выполнение запроса: базовая последовательность
Работа с запросом всегда начинается с создания объекта Запрос и присвоения ему текста на встроенном языке запросов. Текст описывает, какие поля и из каких таблиц нужно получить, а также условия отбора. После этого запрос выполняется методом Выполнить(), который возвращает объект типа РезультатЗапроса.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Товар,
| Номенклатура.Наименование КАК Наименование
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Артикул = &Артикул";
Запрос.УстановитьПараметр("Артикул", "Т-1001");
РезультатЗапроса = Запрос.Выполнить();
Объект РезультатЗапроса сам по себе не содержит строк данных в удобном виде — это промежуточный объект, из которого данные извлекают методами Выбрать() или Выгрузить(). Попытка обратиться к полям результата напрямую приведёт к ошибке.
Обход результата через Выбрать()
Метод Выбрать() возвращает выборку из результата запроса — объект, который обходится построчно методом Следующий(). Каждая итерация даёт доступ к полям текущей строки по имени или индексу. Это самый распространённый способ обработки результата.
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
Сообщить(Выборка.Наименование);
// Работа с Выборка.Товар и другими полями
КонецЦикла;
Выборка подходит, когда данные обрабатываются последовательно: заполнение документов, расчёты, формирование сообщений. Преимущество метода — экономия памяти при больших объёмах, поскольку не требуется материализовать все строки одновременно. Недостаток — нельзя обратиться к произвольной строке или узнать количество записей без полного обхода.
Выборка с группировкой и итогами
Если запрос содержит итоги (ИТОГИ ПО), выборку можно обходить иерархически. Для этого в метод Выбрать() передаётся параметр ОбходРезультатаЗапроса.ПоГруппировкам, а внутри обхода групп открывается вложенная выборка по детальным записям.
ВыборкаГруппы = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока ВыборкаГруппы.Следующий() Цикл
// Итог по группе
ВыборкаДетали = ВыборкаГруппы.Выбрать();
Пока ВыборкаДетали.Следующий() Цикл
// Детальные записи внутри группы
КонецЦикла;
КонецЦикла;
Выгрузка результата в таблицу значений
Метод Выгрузить() преобразует результат запроса в таблицу значений — структуру данных, которую удобно сортировать, фильтровать, сворачивать и передавать между процедурами. Это стандартный способ, когда данные нужны целиком: для заполнения табличной части, отображения на форме или многократного поиска по строкам.
ТаблицаТоваров = РезультатЗапроса.Выгрузить();
Для Каждого СтрокаТовара Из ТаблицаТоваров Цикл
Сообщить(СтрокаТовара.Наименование);
КонецЦикла;
// Поиск конкретной строки
НайденнаяСтрока = ТаблицаТоваров.Найти("Т-1001", "Артикул");
Если запрос возвращает иерархические данные с итогами, выгрузку можно выполнить в дерево значений, передав параметр ОбходРезультатаЗапроса.ПоГруппировкамСИерархией. Это используется для отображения древовидных структур на форме.
Выбрать() или Выгрузить()
Подходит для последовательной обработки больших объёмов; экономит память, но не даёт произвольного доступа к строкам и их количества
Подходит, когда нужны сортировка, поиск, свёртка и повторные обходы; требует больше памяти на больших выборках
Подходит для иерархических данных с группировками, например для дерева на форме
Проверка результата на пустоту
Прежде чем обходить выборку, часто нужно понять, есть ли вообще данные. Для этого у результата запроса есть метод Пустой(), который возвращает Истина, если запрос не вернул ни одной строки. Это быстрее и чище, чем выгружать таблицу и проверять её количество строк.
РезультатЗапроса = Запрос.Выполнить();
Если РезультатЗапроса.Пустой() Тогда
Сообщить("Данные не найдены");
Возврат;
КонецЕсли;
Выборка = РезультатЗапроса.Выбрать();
Типовой сценарий — получение единственного значения. Если запрос гарантированно возвращает одну строку (например, агрегатную функцию или поиск по уникальному ключу), выборку обходят один раз и сразу читают поле:
Выборка = РезультатЗапроса.Выбрать();
Если Выборка.Следующий() Тогда
Остаток = Выборка.КоличествоОстаток;
Иначе
Остаток = 0;
КонецЕсли;
- 1Создайте объект: Запрос = Новый Запрос
- 2Задайте текст запроса через свойство Текст
- 3Установите параметры методом УстановитьПараметр
- 4Выполните запрос: Результат = Запрос.Выполнить()
- 5Проверьте Результат.Пустой() при необходимости
- 6Обойдите данные через Выбрать() или выгрузите через Выгрузить()
Параметры запроса и безопасность
Любые переменные условия в тексте запроса передаются через параметры — методом УстановитьПараметр("Имя", Значение). В тексте параметр обозначается символом амперсанда: &Артикул. Платформа сама подставляет значение с учётом типа данных.
Никогда не формируйте текст запроса конкатенацией строк с пользовательским вводом. Прямая подстановка строк в текст запроса не только ломает запрос на спецсимволах, но и создаёт риск некорректной выборки и усложняет отладку. Параметры решают обе проблемы и дополнительно позволяют платформе кэшировать план запроса.
Если параметр — массив или список значений, в тексте используется конструкция В (&СписокТоваров) или В ИЕРАРХИИ (&Группа). Платформа корректно обработает коллекцию без ручной сборки перечислений.
Пакетные запросы и временные таблицы
Один объект запроса может содержать несколько операторов, разделённых точкой с запятой, — пакетный запрос. Промежуточные результаты помещаются во временные таблицы (ПОМЕСТИТЬ ИмяТаблицы), а финальный оператор выбирает итоговые данные. Чтобы получить результаты всех операторов, используется метод ВыполнитьПакет(), возвращающий массив результатов.
Запрос.Текст =
"ВЫБРАТЬ Товары.Ссылка ПОМЕСТИТЬ ВТ_Отбор
|ИЗ Справочник.Номенклатура КАК Товары
|ГДЕ Товары.Поставщик = &Поставщик
|;
|ВЫБРАТЬ Остатки.Номенклатура, Остатки.КоличествоОстаток
|ИЗ РегистрНакопления.ОстаткиТоваров.Остатки(, Номенклатура В (ВЫБРАТЬ Ссылка ИЗ ВТ_Отбор)) КАК Остатки";
Результат = Запрос.Выполнить(); // результат последнего оператора
Метод Выполнить() возвращает результат последнего оператора пакета, а ВыполнитьПакет() — массив, где каждый элемент соответствует своему оператору. Для управления временными таблицами между разными запросами применяется объект МенеджерВременныхТаблиц.
Типичные ошибки при получении результата
Большинство проблем с результатом запроса связано не с самим запросом, а с неверной обработкой. Знание типовых ошибок экономит часы отладки.
Отдельного внимания заслуживает значение NULL. При левом соединении, если в присоединяемой таблице нет подходящей записи, её поля возвращают NULL, а не пустую ссылку или ноль. Сравнение Если Выборка.Склад = Неопределено не сработает — используйте функцию ЕСТЬNULL(Поле, ЗначениеПоУмолчанию) прямо в тексте запроса.
Как проверить результат
Пустой() = Ложь и обход возвращает ожидаемое число записей
Пустой() = Истина при заведомо существующих данных — проверяйте условия и параметры
Поля содержат данные ожидаемых типов
В полях NULL или пустые значения — проверяйте соединения и ЕСТЬNULL
Запрос выполняется за приемлемое время
Запрос внутри цикла или без индексированных условий — переносите в пакетный запрос
FAQ
Чем отличается Выбрать() от Выгрузить()?
Выбрать() возвращает выборку для последовательного построчного обхода и экономит память. Выгрузить() материализует все строки в таблицу значений, которую можно сортировать, фильтровать и обходить многократно. Для однократной обработки больших объёмов предпочтительнее выборка.
Как узнать количество строк результата запроса?
У объекта РезультатЗапроса нет свойства с количеством. Варианты: выгрузить в таблицу значений и взять Количество(), добавить в запрос агрегат КОЛИЧЕСТВО() или проверить только факт наличия данных методом Пустой().
Как получить одно значение из запроса?
Выполните запрос, получите выборку и вызовите Следующий() один раз внутри условия Если. Если запрос гарантированно возвращает одну строку (агрегат или поиск по уникальному ключу), после успешного Следующий() читайте нужное поле напрямую.
Почему запрос падает с ошибкой «Поле не найдено»?
Имя поля в обращении через выборку не совпадает с именем (псевдонимом) в тексте запроса. Проверьте секцию ВЫБРАТЬ: обращаться можно только по тем именам, которые заданы после КАК, либо по исходным именам полей без псевдонимов.
Можно ли выполнить запрос к данным другого запроса?
Да, через временные таблицы: первый запрос помещает результат в таблицу оператором ПОМЕСТИТЬ, второй читает её. Чтобы временная таблица была доступна между разными объектами запроса, им назначают общий МенеджерВременныхТаблиц.
Что возвращает запрос, если данных нет?
Запрос без агрегатов возвращает пустой результат — Пустой() даст Истина. Запрос с агрегатными функциями без ГРУППИРОВКИ ПО возвращает одну строку с NULL в агрегатах, поэтому Пустой() будет Ложь, а значения нужно обрабатывать через ЕСТЬNULL.
Что важно запомнить
Результат запроса получают методом Выполнить(), данные извлекают через Выбрать() с обходом Следующий() или Выгрузить() в таблицу значений. Проверяйте Пустой(), передавайте условия через параметры и обрабатывайте NULL функцией ЕСТЬNULL.