Как в запросе 1С получить данные из табличной части, а не «ТаблицуЗначений»?

Программист 1С v8.3 (Управляемые формы)
← На главную

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

Анализ проблемы: почему запрос возвращает объект, а не данные?

Рассмотрим типичную ситуацию. У нас есть документ «ОтменаПриказа» с табличной частью «Договоры», в которой есть колонка «Договор». Задача — получить список всех договоров из этой табличной части. Разработчик пишет следующий код для выполнения и обхода запроса:


// Неправильный код обхода
Результат = Запрос.Выполнить(); 
Выборка = Результат.Выбрать(); 

Пока Выборка.Следующий() Цикл 
    // Здесь мы ожидаем получить таблицу значений и пытаемся ее перебрать
    ТЗДоговоры = Выборка.Договоры; 
    Для каждого СтрокаТЗ из ТЗДоговоры Цикл 
        // Эта строка кода выведет "СтрокаТаблицыЗначений"
        Сообщить(СтрокаТЗ); 
    КонецЦикла; 
КонецЦикла;

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


// Неправильный запрос
ВЫБРАТЬ
    ОтменаПриказа.Договоры // Мы выбираем ВСЮ табличную часть как одно поле
ИЗ
    Документ.ОтменаПриказа КАК ОтменаПриказа

В этом случае поле ОтменаПриказа.Договоры в результате запроса будет содержать не строки, а ссылку на объект — саму табличную часть. Платформа 1С воспринимает это как единое целое. Когда мы пытаемся перебрать этот объект, мы работаем не с данными, а со ссылкой на коллекцию, что и приводит к выводу системных представлений вроде «СтрокаТаблицыЗначений».

Фундаментальное правило: чтобы получить строки из табличной части, нужно обращаться в запросе непосредственно к ней как к источнику данных.

Правильное решение: запрос к табличной части и обход результата

Разберем по шагам, как исправить ситуацию и написать работающий код.

Шаг 1. Корректируем текст запроса

Главное изменение — в секции ИЗ мы должны указать полный путь к табличной части. В секции ВЫБРАТЬ мы указываем конкретные поля (колонки), которые нам нужны из этой табличной части.

Правильный запрос будет выглядеть так:


ВЫБРАТЬ
    ОтменаПриказаДоговоры.Договор
ИЗ
    Документ.ОтменаПриказа.Договоры КАК ОтменаПриказаДоговоры

Проанализируем его:

Шаг 2. Правильно обрабатываем результат запроса

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

  1. Обход через выборку (рекомендуемый способ). Это наиболее эффективный по производительности и использованию памяти метод. Он не загружает все данные в память сразу, а последовательно перебирает строки результата. Для этого используется метод РезультатЗапроса.Выбрать().

    
    // Создаем и настраиваем запрос
    Запрос = Новый Запрос;
    Запрос.Текст =
        "ВЫБРАТЬ
        |   ОтменаПриказаДоговоры.Договор
        |ИЗ
        |   Документ.ОтменаПриказа.Договоры КАК ОтменаПриказаДоговоры";
    
    // Выполняем запрос
    РезультатЗапроса = Запрос.Выполнить();
    
    // Создаем выборку для обхода результата
    Выборка = РезультатЗапроса.Выбрать();
    
    // Обходим результат в цикле
    Пока Выборка.Следующий() Цикл
        // Обращаемся к конкретному полю выборки по его имени
        ТекущийДоговор = Выборка.Договор;
        Сообщить(ТекущийДоговор);
    КонецЦикла;
    

    Как видите, здесь нет вложенных циклов. Мы напрямую обращаемся к полю Выборка.Договор, так как наш запрос уже вернул плоский список договоров.

  2. Выгрузка в ТаблицуЗначений. Этот способ используется, когда нужно загрузить все данные в память для дальнейшей обработки (сортировки, поиска, передачи на форму и т.д.). Для этого используется метод РезультатЗапроса.Выгрузить().

    
    РезультатЗапроса = Запрос.Выполнить();
    ТЗДоговоры = РезультатЗапроса.Выгрузить();
    
    // Теперь ТЗДоговоры - это обычная ТаблицаЗначений, которую можно перебирать
    Для каждого СтрокаТЗ Из ТЗДоговоры Цикл
        // Обращаемся к значению в конкретной колонке
        Сообщить(СтрокаТЗ.Договор);
    КонецЦикла;
    

    Обратите внимание на ключевую деталь: в цикле мы обращаемся к СтрокаТЗ.Договор, а не просто к СтрокаТЗ.

Разбор частых ошибок и полезные советы

Ошибка: вывод всей строки вместо значения колонки

Проблема, озвученная в теме форума («Выводятся не значения, а "СтрокаТаблицыЗначений"»), возникает, когда в цикле по таблице значений пытаются вывести саму строку, а не значение в ее колонке.

Совет: используйте консоль запросов для отладки

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

Если бы автор вопроса сначала выполнил свой запрос в консоли, он бы сразу увидел, что результат содержит одну колонку, в которой находится объект «ТаблицаЗначений», и понял бы, что запрос составлен неверно.

Таким образом, для получения данных из табличной части всегда указывайте ее как источник в секции ИЗ и выбирайте нужные поля в секции ВЫБРАТЬ. Для обработки результата предпочтительно использовать обход через выборку, а для отладки — незаменимый инструмент "Консоль запросов".

← На главную