К статье
Практический материал

Разработка и Конфигурация · 11 мин

Как получить результат запроса в 1С

Как получить результат запроса в 1С: методы Выполнить, Выбрать, Выгрузить, обход выборки, проверка на пустоту. Примеры кода, типичные ошибки и ответы на вопросы.

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

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

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

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

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

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

"ВЫБРАТЬ

| Номенклатура.Ссылка КАК Товар,

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

|ИЗ

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

|ГДЕ

| Номенклатура.Артикул = &Артикул";

Запрос.УстановитьПараметр("Артикул", "Т-1001");

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

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

Обход результата через Выбрать()

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

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

Пока Выборка.Следующий() Цикл

Сообщить(Выборка.Наименование);

// Работа с Выборка.Товар и другими полями

КонецЦикла;

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

Выборка с группировкой и итогами

Если запрос содержит итоги (ИТОГИ ПО), выборку можно обходить иерархически. Для этого в метод Выбрать() передаётся параметр ОбходРезультатаЗапроса.ПоГруппировкам, а внутри обхода групп открывается вложенная выборка по детальным записям.

ВыборкаГруппы = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);

Пока ВыборкаГруппы.Следующий() Цикл

// Итог по группе

ВыборкаДетали = ВыборкаГруппы.Выбрать();

Пока ВыборкаДетали.Следующий() Цикл

// Детальные записи внутри группы

КонецЦикла;

КонецЦикла;

Выгрузка результата в таблицу значений

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

ТаблицаТоваров = РезультатЗапроса.Выгрузить();

Для Каждого СтрокаТовара Из ТаблицаТоваров Цикл

Сообщить(СтрокаТовара.Наименование);

КонецЦикла;

// Поиск конкретной строки

НайденнаяСтрока = ТаблицаТоваров.Найти("Т-1001", "Артикул");

Если запрос возвращает иерархические данные с итогами, выгрузку можно выполнить в дерево значений, передав параметр ОбходРезультатаЗапроса.ПоГруппировкамСИерархией. Это используется для отображения древовидных структур на форме.

Выбрать() или Выгрузить()

Выбрать()

Подходит для последовательной обработки больших объёмов; экономит память, но не даёт произвольного доступа к строкам и их количества

Выгрузить() в таблицу значений

Подходит, когда нужны сортировка, поиск, свёртка и повторные обходы; требует больше памяти на больших выборках

Выгрузить() в дерево значений

Подходит для иерархических данных с группировками, например для дерева на форме

Проверка результата на пустоту

Прежде чем обходить выборку, часто нужно понять, есть ли вообще данные. Для этого у результата запроса есть метод Пустой(), который возвращает Истина, если запрос не вернул ни одной строки. Это быстрее и чище, чем выгружать таблицу и проверять её количество строк.

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

Если РезультатЗапроса.Пустой() Тогда

Сообщить("Данные не найдены");

Возврат;

КонецЕсли;

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

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

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

Если Выборка.Следующий() Тогда

Остаток = Выборка.КоличествоОстаток;

Иначе

Остаток = 0;

КонецЕсли;

Порядок получения результата запроса
  1. 1
    Создайте объект: Запрос = Новый Запрос
  2. 2
    Задайте текст запроса через свойство Текст
  3. 3
    Установите параметры методом УстановитьПараметр
  4. 4
    Выполните запрос: Результат = Запрос.Выполнить()
  5. 5
    Проверьте Результат.Пустой() при необходимости
  6. 6
    Обойдите данные через Выбрать() или выгрузите через Выгрузить()

Параметры запроса и безопасность

Любые переменные условия в тексте запроса передаются через параметры — методом УстановитьПараметр("Имя", Значение). В тексте параметр обозначается символом амперсанда: &Артикул. Платформа сама подставляет значение с учётом типа данных.

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

Если параметр — массив или список значений, в тексте используется конструкция В (&СписокТоваров) или В ИЕРАРХИИ (&Группа). Платформа корректно обработает коллекцию без ручной сборки перечислений.

Пакетные запросы и временные таблицы

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

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

"ВЫБРАТЬ Товары.Ссылка ПОМЕСТИТЬ ВТ_Отбор

|ИЗ Справочник.Номенклатура КАК Товары

|ГДЕ Товары.Поставщик = &Поставщик

|;

|ВЫБРАТЬ Остатки.Номенклатура, Остатки.КоличествоОстаток

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

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

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

Типичные ошибки при получении результата

Большинство проблем с результатом запроса связано не с самим запросом, а с неверной обработкой. Знание типовых ошибок экономит часы отладки.

Типичные ошибки
01
Обращение к полю результата без выборки: РезультатЗапроса.Наименование — ошибка, сначала нужен Выбрать() и Следующий()
02
Отсутствие проверки Следующий() при чтении единственного значения: если запрос вернул ноль строк, обращение к полю даст неопределённое поведение или ошибку
03
Пропуск установки параметра: запрос падает с сообщением о незаданном параметре
04
Задвоение имён полей: два поля с одинаковым именем в выборке приводят к ошибке выполнения
05
Обход выборки дважды: после полного обхода курсор в конце, повторный цикл ничего не вернёт — нужно заново получить выборку
06
Сравнение NULL с значением: незаполненные поля левого соединения возвращают NULL, проверяйте через ЕСТЬ NULL или ЕСТЬNULL()

Отдельного внимания заслуживает значение NULL. При левом соединении, если в присоединяемой таблице нет подходящей записи, её поля возвращают NULL, а не пустую ссылку или ноль. Сравнение Если Выборка.Склад = Неопределено не сработает — используйте функцию ЕСТЬNULL(Поле, ЗначениеПоУмолчанию) прямо в тексте запроса.

Контрольные точки

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

Количество строк
Норма

Пустой() = Ложь и обход возвращает ожидаемое число записей

Тревожный признак

Пустой() = Истина при заведомо существующих данных — проверяйте условия и параметры

Значения полей
Норма

Поля содержат данные ожидаемых типов

Тревожный признак

В полях NULL или пустые значения — проверяйте соединения и ЕСТЬNULL

Производительность
Норма

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

Тревожный признак

Запрос внутри цикла или без индексированных условий — переносите в пакетный запрос

FAQ

Чем отличается Выбрать() от Выгрузить()?

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

Как узнать количество строк результата запроса?

У объекта РезультатЗапроса нет свойства с количеством. Варианты: выгрузить в таблицу значений и взять Количество(), добавить в запрос агрегат КОЛИЧЕСТВО() или проверить только факт наличия данных методом Пустой().

Как получить одно значение из запроса?

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

Почему запрос падает с ошибкой «Поле не найдено»?

Имя поля в обращении через выборку не совпадает с именем (псевдонимом) в тексте запроса. Проверьте секцию ВЫБРАТЬ: обращаться можно только по тем именам, которые заданы после КАК, либо по исходным именам полей без псевдонимов.

Можно ли выполнить запрос к данным другого запроса?

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

Что возвращает запрос, если данных нет?

Запрос без агрегатов возвращает пустой результат — Пустой() даст Истина. Запрос с агрегатными функциями без ГРУППИРОВКИ ПО возвращает одну строку с NULL в агрегатах, поэтому Пустой() будет Ложь, а значения нужно обрабатывать через ЕСТЬNULL.

Итог

Что важно запомнить

Результат запроса получают методом Выполнить(), данные извлекают через Выбрать() с обходом Следующий() или Выгрузить() в таблицу значений. Проверяйте Пустой(), передавайте условия через параметры и обрабатывайте NULL функцией ЕСТЬNULL.