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