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

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

Как вытащить данные из табличной части 1С

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

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

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

Как устроена табличная часть и почему это важно

Каждая табличная часть — отдельная таблица в базе данных, связанная с объектом-владельцем по ссылке. У неё есть собственные реквизиты (колонки) и служебное поле «НомерСтроки». Обращение к данным идёт либо через объект в памяти (если документ уже открыт или получен методом ПолучитьОбъект()), либо через запрос напрямую к таблице.

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

Обход табличной части в коде: базовый способ

Если у вас есть ссылка на документ, данные табличной части доступны через свойство с её именем. Типичный код обхода выглядит так:

ДокОбъект = СсылкаНаДокумент.ПолучитьОбъект();

Для Каждого СтрокаТЧ Из ДокОбъект.Товары Цикл

Сообщить(СтрокаТЧ.Номенклатура);

Сообщить(СтрокаТЧ.Количество);

Сообщить(СтрокаТЧ.Сумма);

КонецЦикла;

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

Для доступа к колонке по имени, заданному строкой (например, имя колонки приходит параметром), используйте квадратные скобки: СтрокаТЧ["Количество"]. Это основа универсальных выгрузок, где состав колонок неизвестен заранее.

Выгрузка табличной части в таблицу значений

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

ТЗ = СсылкаНаДокумент.Товары.Выгрузить();

ТЗ.Свернуть("Номенклатура", "Количество,Сумма");

ТЗ.Сортировать("Сумма Убыв");

Методу Выгрузить() можно передать список колонок строкой — Выгрузить(, "Номенклатура,Количество") — чтобы не тащить в память лишние данные. Также есть вариант ВыгрузитьКолонку("Номенклатура"), возвращающий массив значений одной колонки.

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

Получение данных запросом без загрузки объекта

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

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

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

"ВЫБРАТЬ

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

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

| СУММА(Товары.Количество) КАК Количество

|ИЗ

| Документ.РеализацияТоваровУслуг.Товары КАК Товары

|ГДЕ

| Товары.Ссылка.Дата МЕЖДУ &НачалоПериода И &КонецПериода

|СГРУППИРОВАТЬ ПО

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

Результат запроса обходится через Выбрать() или выгружается в таблицу значений методом Выгрузить(). Для отчётов на СКД табличная часть подключается так же — как набор данных с обращением к таблице через точку.

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

bsl
ВЫБРАТЬ Т.Ссылка, Т.Номенклатура, Т.Количество ИЗ Документ.РеализацияТоваровУслуг.Товары КАК Т ГДЕ Т.Ссылка = &Ссылка

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

Если цель — просто получить строки в Excel, программировать не обязательно. В управляемых формах большинства конфигураций табличную часть можно вывести через меню «Ещё → Вывести список» (в некоторых версиях — «Вывести таблицу»): платформа сформирует табличный документ, который сохраняется в XLSX, CSV или MXL.

Второй вариант — выделить нужные строки (Ctrl+A для всех, Ctrl+клик для выборочных) и скопировать их в буфер обмена, затем вставить в Excel. Переносятся только видимые колонки, поэтому сначала настройте состав колонок через «Ещё → Изменить форму» или настройку списка.

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

Сравнение способов

Обход в коде через объект

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

Запрос к табличной части

Оптимален для чтения и отчётов по многим документам. Только чтение, требует знания языка запросов.

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

Удобен для обработки одного объекта: свёртки, сортировки, поиск. Требует обратной загрузки при изменениях.

Вывести список / копипаст

Быстрый ручной способ без кода. Не подходит для регулярных и объёмных выгрузок.

Выгрузка в Excel и внешние форматы программно

Для автоматической выгрузки табличной части в файл используют табличный документ: заполняете его построчно и сохраняете методом Записать() с типом файла XLSX или CSV. Пример минимального кода:

ТабДок = Новый ТабличныйДокумент;

НомерСтроки = 1;

Для Каждого СтрокаТЧ Из СсылкаНаДокумент.Товары Цикл

ТабДок.Область(НомерСтроки, 1).Текст = Строка(СтрокаТЧ.Номенклатура);

ТабДок.Область(НомерСтроки, 2).Текст = СтрокаТЧ.Количество;

НомерСтроки = НомерСтроки + 1;

КонецЦикла;

ТабДок.Записать("C:\Выгрузка\Товары.xlsx", ТипФайлаТабличногоДокумента.XLSX);

Для обмена с другими системами чаще применяют JSON или XML: таблицу значений обходят в цикле и формируют структуры/соответствия, которые сериализуются штатной ЗаписьJSON. На управляемых формах помните про разделение клиент-сервер: запись файла выполняется на сервере, а передача пользователю — через временное хранилище.

Порядок действий для программной выгрузки
  1. 1
    Определите имя табличной части в конфигураторе (свойства объекта, закладка «Данные»)
  2. 2
    Выберите способ: запрос для чтения многих документов, объект — для одного
  3. 3
    Напишите обход строк или текст запроса с нужными колонками
  4. 4
    Проверьте результат на одном документе с известным содержимым
  5. 5
    Добавьте обработку пустых табличных частей и ошибок перед запуском на полном объёме

Типичные ошибки и как их проверить

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

Вторая группа проблем — типы данных. Колонка «Номенклатура» содержит ссылку, а не строку: при выгрузке в текст или сравнении со строкой получите либо ошибку, либо представление вместо кода. Явно преобразуйте значения (Строка(), или вытаскивайте нужный реквизит через точку — СтрокаТЧ.Номенклатура.Код).

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

Типичные ошибки
01
Обращение по имени с формы вместо имени из метаданных — ошибка «Поле не обнаружено»
02
Сравнение ссылки со строкой — условие никогда не срабатывает, выборка пустая
03
Запрос без фильтра по проведённости — в выгрузку попадают черновики и помеченные на удаление
04
ПолучитьОбъект() в цикле по тысячам ссылок — обработка работает в разы медленнее запроса
05
Изменение выгруженной таблицы значений в ожидании, что объект обновится сам — данные теряются без Загрузить()
Контрольные точки

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

Количество выгруженных строк
Норма

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

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

Строк меньше — вероятно, сработал скрытый фильтр или группировка

Итоговые суммы
Норма

Сумма по колонке равна итогу в документе

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

Расхождение — проверьте свёртку дублей и отбор проведённых

Значения ссылочных колонок
Норма

В файле читаемые наименования или коды

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

В выгрузке «Объект не найден» или пустые значения — битые ссылки

FAQ

Как узнать имя табличной части, если она называется иначе, чем на форме?

Откройте конфигуратор, найдите объект в дереве конфигурации и разверните ветку «Табличные части» — там указаны программные имена. Подпись на форме задаётся отдельно и может не совпадать с именем.

Можно ли обратиться к табличной части, не зная её имени заранее?

Да. Через метаданные: Ссылка.Метаданные().ТабличныеЧасти возвращает коллекцию описаний, а к самой части обращаются по индексу или имени из этой коллекции: ДокОбъект[Описание.Имя]. Так строят универсальные обработки выгрузки.

Почему запрос к табличной части возвращает больше строк, чем видно в документе?

Обычно дело в соединениях: если присоединить справочник с дублями или вторую табличную часть без условия, строки перемножаются. Проверьте секции СОЕДИНЕНИЕ и условия связи, а также отбор по конкретной ссылке.

Как выгрузить табличную часть из внешней обработки на управляемой форме?

Логику чтения и формирования файла размещайте в серверной процедуре (директива &НаСервере), файл сохраняйте во временное хранилище через ПоместитьВоВременноеХранилище, а на клиенте забирайте методом ПолучитьФайл или НачатьПолучениеФайлов.

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

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

Можно ли вытащить табличную часть из помеченного на удаление документа?

Да, данные физически остаются в базе до удаления помеченных объектов, и запрос их вернёт. Но включать такие строки в отчёты и выгрузки обычно не следует — добавляйте условие на ПометкаУдаления = ЛОЖЬ или Проведен.

Итог

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

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