Программирование в 1С

Как получить табличную часть документа в 1С программно: примеры кода

Коротко

Чтобы получить табличную часть документа в 1С, обратитесь к ней через объект или ссылку: Объект.Товары либо ДокументСсылка.Товары. Обход табличной части — цикл Для Каждого Строка Из Товары Цикл, доступ к значениям — по имени колонки (Строка.Номенклатура). Чтобы получить копию данных как таблицу значений, используйте Выгрузить().

Когда документов много или нужны только отдельные поля — быстрее получить данные табличной части запросом к таблице Документ.РеализацияТоваров.Товары, а не загружать объект целиком. Обращение к объекту меняет данные в базе, обращение к ссылке — только читает.

Как получить табличную часть документа: объект и ссылка

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

// Через объект — если планируем менять данные и записывать документ
ДокОбъект = ДокументСсылка.ПолучитьОбъект();
ТабЧасть = ДокОбъект.Товары;

// Через ссылку — только для чтения, без ПолучитьОбъект()
ТабЧасть = ДокументСсылка.Товары;

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

Метод Количество() возвращает число строк табличной части — удобно для проверки, что она не пуста, перед обходом.

Обход табличной части документа циклом

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

Сумма = 0;
Для Каждого СтрокаТЧ Из ДокументСсылка.Товары Цикл
    // доступ к колонкам по имени
    Сообщить(СтрокаТЧ.Номенклатура + " × " + СтрокаТЧ.Количество);
    Сумма = Сумма + СтрокаТЧ.Сумма;
КонецЦикла;
Сообщить("Итого по документу: " + Сумма);

Если нужно изменить значения во всех строках, обходите табличную часть у объекта и не забудьте записать документ — иначе правки останутся только в памяти:

ДокОбъект = ДокументСсылка.ПолучитьОбъект();
Для Каждого СтрокаТЧ Из ДокОбъект.Товары Цикл
    СтрокаТЧ.Сумма = СтрокаТЧ.Цена * СтрокаТЧ.Количество;
КонецЦикла;
ДокОбъект.Записать();

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

Получить конкретную строку табличной части можно по индексу (нумерация с нуля) методом Получить(), а найти строку по значению колонки — методами Найти() и НайтиСтроки():

ТабЧасть = ДокументСсылка.Товары;

// первая строка (индексация с нуля)
ПерваяСтрока = ТабЧасть.Получить(0);

// найти первую строку с нужной номенклатурой
НайденнаяСтрока = ТабЧасть.Найти(ИскомаяНоменклатура, "Номенклатура");
Если НайденнаяСтрока <> Неопределено Тогда
    Сообщить("Количество: " + НайденнаяСтрока.Количество);
КонецЕсли;
Найти
Значениеискомое значение в строке
Колонкиперечень колонок для поиска через запятую
Строка табличной части / Неопределено

Когда совпадений может быть несколько, используйте НайтиСтроки() — она возвращает массив всех подходящих строк по набору условий:

Отбор = Новый Структура;
Отбор.Вставить("Номенклатура", ИскомаяНоменклатура);
НайденныеСтроки = ДокументСсылка.Товары.НайтиСтроки(Отбор);
Для Каждого СтрокаТЧ Из НайденныеСтроки Цикл
    Сообщить("Строка № " + (СтрокаТЧ.НомерСтроки) + ", кол-во " + СтрокаТЧ.Количество);
КонецЦикла;
НайтиСтроки
ПараметрыОтбораструктура «имя колонки → значение», условия объединяются по И
Массив

Ключевое отличие: Найти() вернёт одну строку или Неопределено, а НайтиСтроки() — всегда массив (возможно, пустой).

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

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

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

// только нужные колонки
ТолькоНоменклатура = ДокументСсылка.Товары.Выгрузить(, "Номенклатура, Количество");

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

Обратная операция — Загрузить(<Таблица>): загружает таблицу значений с совпадающим набором колонок в табличную часть объекта (см. следующий раздел).

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

Когда документов много или нужны только отдельные поля, получить табличную часть запросом надёжнее и быстрее, чем читать объект целиком. Табличная часть доступна как отдельная таблица Документ.ИмяДокумента.ИмяТЧ:

Запрос = Новый Запрос;
Запрос.Текст =
    "ВЫБРАТЬ
    |   Товары.Ссылка КАК Документ,
    |   Товары.НомерСтроки КАК НомерСтроки,
    |   Товары.Номенклатура КАК Номенклатура,
    |   Товары.Количество КАК Количество,
    |   Товары.Сумма КАК Сумма
    |ИЗ
    |   Документ.РеализацияТоваров.Товары КАК Товары
    |ГДЕ
    |   Товары.Ссылка = &Ссылка
    |УПОРЯДОЧИТЬ ПО
    |   Товары.НомерСтроки";
Запрос.УстановитьПараметр("Ссылка", ДокументСсылка);

Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
    Сообщить(Выборка.Номенклатура + ": " + Выборка.Сумма);
КонецЦикла;

Если поля запроса совпадают по именам с колонками табличной части, результат можно загрузить в ТЧ одной строкой — без обхода в цикле:

ДокОбъект.Товары.Загрузить(Запрос.Выполнить().Выгрузить());

А когда нужна предварительная обработка строк — обходите выборку и заполняйте строки методом Добавить():

Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
    НоваяСтрока = ДокОбъект.Товары.Добавить();
    ЗаполнитьЗначенияСвойств(НоваяСтрока, Выборка);
КонецЦикла;

Частые ошибки при работе с табличной частью документа

  • Правки у ссылки, а не у объекта. Изменения строк, полученных через ДокументСсылка.Товары, недопустимы. Чтобы менять данные, нужен ПолучитьОбъект() и последующий Записать().
  • Забыли записать документ. Изменение значений в цикле без ДокОбъект.Записать() оставляет правки только в памяти — в базе всё по-старому.
  • Обращение к несуществующей колонке. Строка.Кол_во вместо Строка.Количество приводит к ошибке «Поле объекта не обнаружено». Имя колонки должно совпадать с конфигуратором именно вашей базы.
  • Индекс строки с единицы. Получить() нумерует строки с нуля, поэтому первая строка — Получить(0), а не Получить(1).
  • Проверка результата Найти() через .Пустая(). Метод возвращает строку табличной части или Неопределено — сравнивать нужно именно с Неопределено.
  • Чтение всего объекта ради нескольких полей. Перебор тысяч документов с ПолучитьОбъект() — источник тормозов. Получите данные табличной части запросом за одно обращение к СУБД.

Частые вопросы о табличной части документа в 1С

Как обойти табличную часть документа в цикле?

Используйте Для Каждого СтрокаТЧ Из ДокументСсылка.Товары Цикл и обращайтесь к колонкам по имени (СтрокаТЧ.Количество). Для чтения достаточно ссылки, для изменения — объект, полученный через ПолучитьОбъект(), с последующей записью.

Чем отличается получить табличную часть через объект и через ссылку?

Через ссылку (ДокументСсылка.Товары) данные только читаются. Через объект (ПолучитьОбъект().Товары) их можно изменять, но изменения попадут в базу лишь после Записать().

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

Обратитесь к таблице Документ.ИмяДокумента.ИмяТЧ в тексте запроса. Это быстрее чтения объекта, когда нужны отдельные поля или сразу много документов, а результат можно загрузить обратно в ТЧ методом Загрузить().