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

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

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

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

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

Оба способа рабочие, но ведут себя по-разному с точки зрения производительности и удобства. Метод Выгрузить() помещает весь результат в память, тогда как Выбрать() позволяет читать данные построчно. Понимание разницы помогает писать код, который не будет тормозить на больших объёмах данных.

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

Базовый механизм: выполнение запроса и его результат

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

Минимальный шаблон выглядит так:

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

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

"ВЫБРАТЬ ПЕРВЫЕ 1

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

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

|ИЗ

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

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

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

Получение первой строки через Выгрузить()

Метод Выгрузить() преобразует результат запроса в таблицу значений. После этого к строкам можно обращаться по индексу: первая строка имеет индекс 0. Это самый короткий путь, когда нужна одна строка и заранее известно, что результат небольшой.

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

Если ТаблицаРезультата.Количество() > 0 Тогда

Строка = ТаблицаРезультата[0];

Товар = Строка.Товар;

Артикул = Строка.Артикул;

КонецЕсли;

Ключевой момент — обязательная проверка Количество() > 0 перед обращением по индексу. Если запрос ничего не вернул, попытка прочитать ТаблицаРезультата[0] вызовет ошибку «Индекс находится за границами массива», и выполнение кода прервётся. Это одна из самых частых причин падения обработок в реальных базах.

Если нужна не первая, а конкретная строка по условию, используют метод Найти() таблицы значений:

Строка = ТаблицаРезультата.Найти(ИскомыйАртикул, "Артикул");

Если Строка <> Неопределено Тогда

Товар = Строка.Товар;

КонецЕсли;

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

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

Метод Выбрать() возвращает выборку — объект для последовательного чтения строк. Переход к следующей строке выполняется методом Следующий(), который возвращает Истина, если строка есть, и Ложь, если данные закончились. Для получения одной строки достаточно одного вызова:

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

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

Товар = Выборка.Товар;

Артикул = Выборка.Артикул;

Иначе

// Запрос ничего не вернул

КонецЕсли;

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

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

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

Подходит для небольших результатов, когда нужен произвольный доступ по индексу, поиск через Найти(), сортировка или многократный обход. Минус: весь результат целиком помещается в память.

Выбрать() — выборка запроса

Подходит для больших результатов и однократного последовательного обхода. Экономит память, но не даёт обращаться к строкам по индексу и возвращаться назад.

ПЕРВЫЕ 1 в тексте запроса

Оптимально, когда нужна ровно одна строка: ограничение накладывается на уровне СУБД, лишние данные не передаются вовсе.

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

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

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

Возврат Неопределено;

КонецЕсли;

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

Порядок получения одной строки из запроса
  1. 1
    Создайте объект Запрос и задайте текст с конструкцией ПЕРВЫЕ 1, если нужна одна строка
  2. 2
    Установите параметры запроса через УстановитьПараметр()
  3. 3
    Выполните запрос: Результат = Запрос.Выполнить()
  4. 4
    Проверьте результат: Если Результат.Пустой() Тогда — обработайте отсутствие данных
  5. 5
    Получите строку: Выборка.Следующий() или Таблица = Результат.Выгрузить(); Строка = Таблица[0]
  6. 6
    Прочитайте поля строки через точку: Строка.ИмяПоля

Обход всех строк в цикле

Когда нужна не одна строка, а обработка всего результата, выборка обходится в цикле Пока:

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

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

Сообщить(Строка(Выборка.Товар) + ": " + Выборка.Артикул);

КонецЦикла;

Аналогичный обход таблицы значений после Выгрузить() выполняется циклом Для Каждого:

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

Сообщить(Строка(Строка.Товар) + ": " + Строка.Артикул);

КонецЦикла;

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

Группировки, итоги и обход по группам

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

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

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

// Строка итога по группе

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

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

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

КонецЦикла;

КонецЦикла;

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

Типичные ошибки при получении строки

Большинство проблем при работе со строками результата запроса сводится к нескольким повторяющимся причинам. Их легко избежать, если знать заранее.

Типичные ошибки
01
Обращение к ТаблицаРезультата[0] без проверки Количество() > 0 — ошибка «Индекс за границами массива» на пустом результате
02
Чтение полей выборки без вызова Следующий() — до первого вызова Следующий() выборка не позиционирована на строке, поля возвращают NULL или Неопределено
03
Опечатка в имени поля: Выборка.Артикл вместо Выборка.Артикул — ошибка «Поле объекта не обнаружено»; имя должно совпадать с псевдонимом в тексте запроса (КАК Артикул)
04
Использование Выгрузить() для результата в сотни тысяч строк — избыточный расход памяти и риск падения сеанса; для больших данных нужна выборка
05
Отсутствие ПЕРВЫЕ 1, когда нужна одна строка — запрос выбирает лишние данные, а код берёт первую попавшуюся без гарантии порядка
06
Получение строки без УПОРЯДОЧИТЬ ПО — «первая строка» без сортировки не детерминирована, на разных СУБД порядок может отличаться

Отдельно стоит ситуация с NULL. Если в запросе используются левые соединения, в полях строки может оказаться значение NULL, а не пустая ссылка. Перед использованием такое поле проверяют через ЕСТЬNULL в тексте запроса или функцией проверки в коде — иначе сравнения и арифметика с этим полем дадут неожиданный результат.

Проверка корректности полученной строки

После того как строка получена, стоит убедиться, что данные в ней именно те, что ожидались. Это особенно актуально при отладке запросов с соединениями и группировками.

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

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

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

Результат.Пустой() = Ложь, таблица содержит ожидаемое число строк

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

Пустой результат при данных, которые точно есть в базе — проверьте параметры и условия ГДЕ

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

Поля содержат значения ожидаемых типов (ссылка, число, строка)

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

В полях NULL или Неопределено там, где должны быть данные — проверьте соединения и ЕСТЬNULL

Порядок строк
Норма

Первая строка соответствует заданной сортировке УПОРЯДОЧИТЬ ПО

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

Порядок случайный — в запросе нет сортировки, а код рассчитывает на конкретную первую строку

Имена полей
Норма

Обращение Строка.ИмяПоля работает без ошибок

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

Ошибка «Поле не обнаружено» — псевдоним в запросе не совпадает с именем в коде

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

Итог

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

Строку из запроса 1С получают через Выгрузить() с обращением по индексу или через выборку с методом Следующий(). Всегда проверяйте результат на пустоту, добавляйте ПЕРВЫЕ 1 и УПОРЯДОЧИТЬ ПО, когда нужна одна конкретная строка, и используйте выборку вместо выгрузки для больших объёмов данных.

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

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

Даже при «гарантированно» непустом результате проверка обязательна: данные могут измениться, а код должен быть устойчив. Минимальный безопасный вариант — Выборка = Результат.Выбрать(); Если Выборка.Следующий() Тогда ... КонецЕсли;. Дополнительно используйте ПЕРВЫЕ 1 в тексте запроса, чтобы не выбирать лишние данные.

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

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

Почему при обращении к полю выборки возникает ошибка «Поле объекта не обнаружено»?

Имя поля в коде не совпадает с псевдонимом в тексте запроса. Проверьте, что в запросе поле объявлено с нужным псевдонимом через КАК (например, «Номенклатура.Артикул КАК Артикул»), и в коде используется именно этот псевдоним с учётом регистра букв не требуется, но написание должно совпадать посимвольно.

Как получить строку по определённому условию, а не первую?

Лучше всего перенести условие в сам запрос через секцию ГДЕ — тогда СУБД вернёт только нужные строки. Если результат уже выгружен в таблицу значений, используйте метод Найти(Значение, "ИмяКолонки") или НайтиСтроки() с структурой отбора для нескольких условий.

Что делать, если в полях строки приходит NULL?

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

Можно ли получить строку результата запроса без цикла и выборки?

Да: выгрузите результат методом Выгрузить() и обратитесь к строке по индексу — ТаблицаРезультата[0]. Но перед этим обязательно проверьте ТаблицаРезультата.Количество() > 0, иначе на пустом результате код завершится с ошибкой выхода индекса за границы.