Как правильно записать данные колонки табличной части документа в структуру

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

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

Анализ причины ошибки «Поле объекта не обнаружено»

Разберем ситуацию, с которой столкнулся автор темы. Попытка выполнить код Структура.Вставить("Math", Док_Курсы.Летние.Математика) ошибочна по своей сути. Проанализируем структуру объектов 1С:

  1. Док_Курсы — это объект (или ссылка) документа.
  2. Летние — это табличная часть, которая представляет собой коллекцию строк.
  3. Математика — это реквизит строки этой табличной части.

Когда мы обращаемся к Док_Курсы.Летние, платформа возвращает нам всю коллекцию (таблицу) целиком. У самой таблицы (объекта коллекции) нет свойства Математика, оно есть только у конкретных строк, входящих в эту таблицу. Представьте себе таблицу в Excel: вы не можете спросить у всей таблицы «какое значение в колонке B?», не уточнив номер строки. Именно поэтому система выдает ошибку, так как пытается найти поле Математика непосредственно в объекте коллекции ТабличнаяЧасть.

Решение 1: Использование метода ВыгрузитьКолонку()

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

Рассмотрим пример правильного кода:


// Предположим, что Док_Курсы — это объект документа
МассивЗначений = Док_Курсы.Летние.ВыгрузитьКолонку("Математика");
Структура.Вставить("Math", МассивЗначений);

В данном случае в структуре под ключом Math будет храниться объект типа Массив. Это важно учитывать при дальнейшем чтении данных из структуры.

Решение 2: Проблема Ссылки и Объекта (Метод объекта не обнаружен)

Иногда при использовании метода ВыгрузитьКолонку() разработчик может столкнуться с новой ошибкой: «Метод объекта не обнаружен (ВыгрузитьКолонку)». Выясним причину этой ситуации. В 1С существует принципиальная разница между типами ДокументСсылка и ДокументОбъект.

У переменной типа Ссылка доступ к табличной части ограничен. Мы можем перебрать строки таблицы в цикле Для каждого, но у коллекции табличной части в контексте ссылки отсутствуют методы манипуляции данными, такие как Выгрузить() или ВыгрузитьКолонку(). Чтобы воспользоваться этими методами, необходимо получить объект документа.

Разберем по шагам, как это сделать:


// Если у нас есть только ссылка на документ
ДокСсылка = СсылкаНаДокумент; 

// Получаем объект документа (внимание: это требует обращения к БД и занимает ресурсы)
ДокОбъект = ДокСсылка.ПолучитьОбъект();

// Теперь метод ВыгрузитьКолонку будет доступен
МассивДанных = ДокОбъект.Летние.ВыгрузитьКолонку("Математика");
Структура.Вставить("Math", МассивДанных);

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

Решение 3: Особенности управляемых форм (ДанныеФормыКоллекция)

Проанализируем ситуацию, если код выполняется в модуле управляемой формы. В этом контексте табличная часть представлена типом ДанныеФормыКоллекция. У этого типа данных нет метода ВыгрузитьКолонку().

Если нам нужно собрать данные из таблицы на клиенте или в серверном методе формы без обращения к базе данных, мы можем использовать обход в цикле:


МассивЗначений = Новый Массив;
Для Каждого СтрокаТЧ Из Объект.Летние Цикл
    МассивЗначений.Добавить(СтрокаТЧ.Математика);
КонецЦикла;
Структура.Вставить("Math", МассивЗначений);

Этот способ универсален и работает как на клиенте, так и на сервере, независимо от того, является ли переменная объектом или данными формы.

Решение 4: Использование запроса — «Золотой стандарт»

Для получения данных из табличных частей наиболее правильным с точки зрения производительности считается использование запросов. Это позволяет избежать загрузки лишних данных в память (весь документ со всеми ТЧ) и сразу получить нужный результат.

Посмотрим на пример реализации:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   КурсыЛетние.Математика КАК ЗначениеПоля
    |ИЗ
    |   Документ.Курсы.Летние КАК КурсыЛетние
    |ГДЕ
    |   КурсыЛетние.Ссылка = &Ссылка";

Запрос.УстановитьПараметр("Ссылка", Док_Курсы_Ссылка);

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

Структура.Вставить("Math", МассивМатематика);

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

Резюме и рекомендации

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

Основные правила:

  1. Никогда не обращайтесь к реквизиту строки через точку от имени всей таблицы (ТЧ.ИмяРеквизита — ошибка).
  2. Для получения всех значений колонки в ДокументОбъект используйте ТЧ.ВыгрузитьКолонку("Имя").
  3. Если у вас ДокументСсылка, либо получите объект через ПолучитьОбъект(), либо используйте Запрос.
  4. При работе с управляемыми формами (ДанныеФормыКоллекция) используйте цикл Для каждого для заполнения массива.
  5. Помните, что в Структура при такой записи попадает Массив. Если вам нужно только одно значение (например, из первой строки), обращайтесь по индексу: Док_Курсы.Летние[0].Математика.

Используя эти методы, вы сможете гибко управлять данными документов и избегать распространенных ошибок типизации в 1С.

← На главную