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

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

Как обратиться к табличной части документа в 1С

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

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

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

Что такое табличная часть и как узнать её имя

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

Там же видны имена реквизитов каждой строки: Номенклатура, Количество, Цена, Сумма. Обращение к реквизиту строки выполняется через точку: СтрокаТЧ.Номенклатура. Если вы работаете без доступа к конфигуратору, имена можно посмотреть через синтакс-помощник (Ctrl+Shift+F1) по типу «ДокументТабличнаяЧасть» или вывести структуру метаданных программно: ДокументОбъект.Метаданные().ТабличныеЧасти.

Обращение к ТЧ через объект документа

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

ДокументОбъект = Документы.РеализацияТоваровУслуг.СоздатьДокумент();

ДокументОбъект.Дата = ТекущаяДатаСеанса();

// Добавление строки в табличную часть

НоваяСтрока = ДокументОбъект.Товары.Добавить();

НоваяСтрока.Номенклатура = НайденныйТовар;

НоваяСтрока.Количество = 2;

НоваяСтрока.Цена = 1500;

ДокументОбъект.Записать();

Обход существующих строк выполняется циклом. Внутри цикла доступны все реквизиты строки:

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

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

Если СтрокаТЧ.Количество = 0 Тогда

Сообщить("В строке " + СтрокаТЧ.НомерСтроки + " нулевое количество");

КонецЕсли;

КонецЦикла;

После изменений обязательно вызывайте Записать(), иначе правки потеряются. Если документ проводимый и изменения должны отразиться в учёте, используйте Записать(РежимЗаписиДокумента.Проведение).

Обращение к ТЧ через запрос (только чтение)

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

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

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

"ВЫБРАТЬ

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

| Товары.Количество КАК Количество,

| Товары.Сумма КАК Сумма

|ИЗ

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

|ГДЕ

| Товары.Ссылка = &Ссылка";

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

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

Сообщить(Строка(Выборка.Номенклатура) + ": " + Выборка.Количество);

КонецЦикла;

У этого подхода два ограничения: данные доступны только для чтения, и через запрос нельзя вызвать прикладную логику записи документа (подстановку цен, пересчёт сумм, проверки). Зато запрос работает быстро и не блокирует документ, что критично для отчётов и пакетных обработок.

Объект или запрос

Через ПолучитьОбъект()

Подходит, когда нужно изменить строки, добавить или удалить их. Даёт доступ к методам объекта, но блокирует документ и медленнее на больших объёмах.

Через запрос к табличной части

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

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

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

Поиск и отбор строк в табличной части

Для поиска конкретной строки у коллекции ТЧ есть методы Найти() и НайтиСтроки(). Первый возвращает одну строку по значению реквизита, второй — массив строк по структуре отбора.

// Поиск одной строки

СтрокаТЧ = ДокументОбъект.Товары.Найти(НужныйТовар, "Номенклатура");

Если СтрокаТЧ <> Неопределено Тогда

СтрокаТЧ.Количество = СтрокаТЧ.Количество + 1;

КонецЕсли;

// Поиск нескольких строк по отбору

Отбор = Новый Структура("Номенклатура, Склад", НужныйТовар, ОсновнойСклад);

НайденныеСтроки = ДокументОбъект.Товары.НайтиСтроки(Отбор);

Для Каждого СтрокаТЧ Из НайденныеСтроки Цикл

СтрокаТЧ.Цена = ПолучитьЦену(СтрокаТЧ.Номенклатура);

КонецЦикла;

Обратите внимание: Найти() возвращает Неопределено, если строка не найдена, — обращение к реквизитам результата без проверки вызовет ошибку. Метод НайтиСтроки() в такой ситуации возвращает пустой массив, который безопасно обходить циклом без дополнительных проверок.

Порядок безопасного изменения строки
  1. 1
    Получите объект документа через Ссылка.ПолучитьОбъект()
  2. 2
    Найдите строку методом Найти() или НайтиСтроки()
  3. 3
    Проверьте, что результат не равен Неопределено
  4. 4
    Измените реквизиты строки и при необходимости пересчитайте зависимые суммы
  5. 5
    Вызовите ДокументОбъект.Записать() с нужным режимом записи
  6. 6
    Проверьте результат, открыв документ в пользовательском режиме

Работа с ТЧ на форме документа

В модуле формы обращение отличается: данные документа доступны через реквизит формы Объект. Обход строк выглядит так же, но добавлять и удалять строки на клиенте нужно с учётом контекста — часть методов коллекции доступна только на сервере.

&НаКлиенте

Процедура ПересчитатьИтоги(Команда)

ИтогСумма = 0;

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

СтрокаТЧ.Сумма = СтрокаТЧ.Количество * СтрокаТЧ.Цена;

ИтогСумма = ИтогСумма + СтрокаТЧ.Сумма;

КонецЦикла;

КонецПроцедуры

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

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

Метод Выгрузить() превращает табличную часть в таблицу значений — удобно для сортировки, свёртки по номенклатуре, передачи в функции и COM/HTTP-обмены. Метод Загрузить() выполняет обратное действие, полностью заменяя содержимое ТЧ.

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

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

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

// Полная замена табличной части

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

ДокументОбъект.Записать();

Помните, что Загрузить() очищает табличную часть перед заполнением. Если нужно добавить строки к существующим, используйте цикл с Добавить() или метод ЗагрузитьКолонку() для отдельной колонки.

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

Проверка результата и границы самостоятельной работы

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

Безопасная граница самостоятельной работы — тестовая копия базы. Любые обработки, массово изменяющие табличные части документов, сначала запускайте на копии и сверяйте итоги по нескольким документам вручную. В рабочей базе делайте резервную копию перед пакетными изменениями, особенно если обработка трогает проведённые документы закрытых периодов.

Контрольные точки

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

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

Количество строк и значения реквизитов совпадают с ожидаемыми

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

Строки дублируются, пропущены или содержат пустые реквизиты

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

Сумма по ТЧ сходится с итогом в шапке и печатной форме

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

Итог не пересчитан — требуется повторное проведение или вызов пересчёта

Движения по регистрам
Норма

После проведения регистры отражают новые данные табличной части

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

Движения соответствуют старым данным — документ не был перепроведён

Частые вопросы

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

Для чтения используйте запрос к таблице Документ.ИмяДокумента.ИмяТабличнойЧасти с отбором по параметру Ссылка. Для изменения вызовите Ссылка.ПолучитьОбъект(), внесите правки и запишите объект. Обратиться к ТЧ напрямую через ссылку (Ссылка.Товары) нельзя — это вызовет ошибку.

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

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

Почему обращение Ссылка.Товары вызывает ошибку?

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

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

Используйте индекс на единицу меньше номера: СтрокаТЧ = ДокументОбъект.Товары[НомерСтроки - 1]. Номер строки в ТЧ начинается с 1, а индексация коллекции — с 0. Перед обращением проверяйте, что номер не превышает значение ДокументОбъект.Товары.Количество().

Можно ли обратиться к ТЧ документа из другой информационной базы?

Напрямую встроенным языком — нет. Используйте COM-соединение, веб-сервисы, HTTP-сервисы или планы обмена. Через COM код будет аналогичным: получаете объект документа в подключённой базе и работаете с его табличной частью теми же методами, но учитывайте, что типы данных между базами совместимы только частично.

Как перебрать строки ТЧ всех документов за период?

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

Итог

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

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