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

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

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

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

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

Ошибки при работе с табличными частями возникают чаще всего из-за путаницы между ссылкой и объектом, обращения к несуществующему имени или попытки модифицировать данные через выборку. Ниже разобраны основные сценарии с примерами кода на встроенном языке 1С, которые работают в типовых и самописных конфигурациях.

Обращение к табличной части через объект документа

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

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

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

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

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

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

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

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

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

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

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

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

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

КонецЦикла;

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

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

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

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

"ВЫБРАТЬ

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

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

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

|ИЗ

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

|ГДЕ

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

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

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

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

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

КонецЦикла;

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

Работа с табличной частью в модуле формы

В управляемой форме документа табличная часть доступна через реквизит формы Объект. Обращение выглядит как Объект.Товары, и это коллекция данных формы, а не объект базы данных напрямую. Изменения попадут в базу только после записи документа.

&НаКлиенте

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

ИтогоПоДокументу = 0;

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

ИтогоПоДокументу = ИтогоПоДокументу + Строка.Сумма;

КонецЦикла;

Сообщить("Итого: " + ИтогоПоДокументу);

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

Для текущей строки табличной части на форме используется элемент формы, связанный с таблицей. Через него получают текущие данные без перебора всей коллекции:

&НаКлиенте

Процедура ТоварыПриИзменении(Элемент)

ТекущиеДанные = Элементы.Товары.ТекущиеДанные;

Если ТекущиеДанные <> Неопределено Тогда

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

КонецЕсли;

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

Поиск строк по имени и другим условиям

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

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

// Поиск одной строки по номенклатуре

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

Если НайденнаяСтрока = Неопределено Тогда

Сообщить("Товар не найден в табличной части");

Иначе

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

КонецЕсли;

// Поиск всех строк по отбору

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

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

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

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

КонецЦикла;

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

Динамическое обращение по имени через строку

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

ИмяТабличнойЧасти = "Товары";

ТабличнаяЧасть = ДокументОбъект[ИмяТабличнойЧасти];

Для Каждого Строка Из ТабличнаяЧасть Цикл

Сообщить(Строка.НомерСтроки);

КонецЦикла;

Перебор всех табличных частей документа через метаданные выглядит так:

МетаданныеДокумента = ДокументСсылка.Метаданные();

Для Каждого ТабЧасть Из МетаданныеДокумента.ТабличныеЧасти Цикл

Сообщить("Табличная часть: " + ТабЧасть.Имя);

КонецЦикла;

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

bsl
Если ДокументСсылка.Метаданные().ТабличныеЧасти.Найти("Товары") <> Неопределено Тогда
    ТабЧасть = ДокументОбъект["Товары"];
КонецЕсли;

Типичные ошибки и ограничения

Первая частая ошибка — обращение к табличной части через ссылку: ДокументСсылка.Товары вызовет ошибку, потому что ссылка содержит только реквизиты шапки. Вторая — опечатка в имени табличной части при динамическом обращении через квадратные скобки: платформа не проверяет строку на этапе компиляции, и ошибка проявится только в момент выполнения.

Третья группа проблем связана с транзакциями. Если документ открыт другим пользователем, вызов ПолучитьОбъект() и последующая запись могут завершиться конфликтом блокировок. В массовых обработках рекомендуется оборачивать запись в попытку/исключение и фиксировать ошибки в журнале регистрации, а не прерывать весь процесс.

Ещё одно ограничение: в толстом клиенте обычных форм доступ к табличной части идёт через элемент управления ТабличноеПоле с другим API, а в тонком и веб-клиенте недоступны некоторые серверные методы. Код, написанный для обычного приложения, при переносе в управляемые формы почти всегда требует переработки обращений к табличным частям.

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

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

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

Если документ проводится, помните, что Записать() с режимом проведения может отказать в записи из-за контроля остатков или других проверок. В этом случае табличная часть в базе останется в прежнем состоянии, даже если в памяти вы её изменили. Всегда анализируйте результат выполнения записи и сообщения об ошибках.

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

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

Количество строк после записи
Норма

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

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

Строк меньше или больше — обработка прервалась или добавила дубли

Значения реквизитов строк
Норма

Поля изменены согласно логике обработки

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

Значения старые — Записать() не был вызван или завершился ошибкой

Журнал регистрации
Норма

Нет ошибок за время работы обработки

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

Ошибки блокировок или проведения — требуется анализ транзакций

Часто задаваемые вопросы

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

Откройте конфигуратор, найдите нужный документ в дереве конфигурации и раскройте ветку «Табличные части» — там перечислены все имена. Программно список получают через ДокументСсылка.Метаданные().ТабличныеЧасти.

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

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

Почему Объект.Товары недоступен в клиентской процедуре формы?

В управляемой форме реквизит Объект доступен и на клиенте, но только для чтения отдельных типов и перебора. Если возникает ошибка, проверьте, что процедура не помечена директивой, ограничивающей контекст, и что обработчик привязан к правильному элементу формы.

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

Имя табличной части уникально только внутри одного вида документа. У разных видов документов могут быть табличные части с одинаковыми именами, поэтому в универсальном коде всегда работайте через метаданные конкретной ссылки.

Что быстрее: перебор строк объекта или запрос?

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

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

Получите объект документа и вызовите метод Очистить(): ДокументОбъект.Товары.Очистить(). Затем запишите документ. Удаление в цикле по одной строке менее эффективно и чревато ошибками индексации.

Итог

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

Табличная часть доступна как свойство объекта документа по её имени из конфигуратора. Ссылку сначала преобразуйте в объект, для чтения без изменений используйте запрос, а при динамическом обращении по строковому имени проверяйте существование табличной части через метаданные. Любые изменения фиксируйте вызовом Записать() и контролируйте результат.