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