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