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