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