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