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