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

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

1С: как обратиться к колонке табличной части

Как обратиться к колонке табличной части документа в 1С: перебор строк, ТекущиеДанные, Итог(), выгрузка колонки. Примеры кода для тонкого и обычного клиента.

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

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

Ниже разобраны все основные способы с примерами кода, которые работают как в управляемых, так и в обычных формах, с пояснением типичных ошибок — например, почему обращение Объект.Товары.Количество без указания строки вызывает ошибку.

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

Самый простой случай — когда известна позиция строки. Индексация строк табличной части начинается с нуля, поэтому первая строка — это Товары[0]. После получения строки к колонке обращаются по её имени, как к свойству:

// Прочитать значение колонки "Количество" первой строки

КоличествоПервойСтроки = Объект.Товары[0].Количество;

// Записать значение в колонку "Цена" второй строки

Объект.Товары[1].Цена = 1500;

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

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

ИмяКолонки = "Сумма";

Значение = Объект.Товары[0][ИмяКолонки];

Перебор всех строк и работа с колонкой в цикле

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

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

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

КонецЦикла;

Переменная цикла (СтрокаТовары) — это ссылка на реальную строку коллекции, а не её копия. Все присвоения внутри цикла сразу изменяют данные объекта. Это удобно, но опасно, если внутри цикла удалять или добавлять строки: коллекция изменится «на ходу», и перебор собьётся. Для удаления строк используйте обратный цикл по индексу от последней строки к первой.

// Безопасное удаление строк с нулевым количеством

Для Сч = 1 По Объект.Товары.Количество() Цикл

Индекс = Объект.Товары.Количество() - Сч;

Если Объект.Товары[Индекс].Количество = 0 Тогда

Объект.Товары.Удалить(Индекс);

КонецЕсли;

КонецЦикла;

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

Если нужна сумма по числовой колонке, не обязательно писать цикл — у табличной части есть метод Итог(), который принимает имя колонки строкой:

СуммаДокумента = Объект.Товары.Итог("Сумма");

ВсегоКоличество = Объект.Товары.Итог("Количество");

Метод работает только с числовыми колонками. Если передать имя колонки строкового или ссылочного типа, получите ошибку или нулевой результат — тип колонки задаётся в конфигураторе, и его стоит проверить заранее.

Чтобы получить все значения колонки списком — например, для запроса или проверки дублей — используйте ВыгрузитьКолонку(). Метод возвращает массив значений указанной колонки:

МассивНоменклатуры = Объект.Товары.ВыгрузитьКолонку("Номенклатура");

// Типичное применение — запрос по всем позициям табличной части

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

Запрос.Текст = "ВЫБРАТЬ Ссылка, Остаток ИЗ РегистрНакопления.Остатки.Остатки(, Номенклатура В (&Список))";

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

Сравнение вариантов

Итог("Сумма")

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

ВыгрузитьКолонку()

Возвращает массив всех значений колонки; подходит для запросов и поиска дублей, но не даёт доступа к другим колонкам строки

Цикл Для Каждого

Универсальный способ: доступны все колонки строки и любая логика, но кода больше

Обращение к колонке в форме: ТекущиеДанные и текущая строка

В модуле формы на клиенте объект документа доступен как реквизит формы, но для работы с «выделенной» пользователем строкой применяется свойство ТекущиеДанные элемента формы табличной части. Оно возвращает объект с колонками текущей строки:

&НаКлиенте

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

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

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

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

КонецЕсли;

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

Проверка на Неопределено обязательна: если табличная часть пуста или фокус не установлен, ТекущиеДанные вернёт Неопределено, и обращение к колонке вызовет ошибку «Поле объекта не обнаружено». Это одна из самых частых ошибок начинающих разработчиков.

Разница между ТекущиеДанные и ТекущаяСтрока

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

ИдСтроки = Элементы.Товары.ТекущаяСтрока;

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

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

Цена = СтрокаДанных.Цена;

КонецЕсли;

Обращение к колонке на сервере в управляемой форме

В серверных процедурах управляемой формы Объект — это данные формы, а не «настоящий» объект документа. Для полноценной работы (например, обмена данными или записи) объект получают через РеквизитФормыВЗначение("Объект"), после чего обращение к колонкам идёт обычным способом. Для простого чтения колонки достаточно обращения к Объект.Товары напрямую — данные формы поддерживают тот же синтаксис.

Обращение к колонке в запросе

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

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

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

"ВЫБРАТЬ

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

| СУММА(Товары.Количество) КАК Количество

|ИЗ

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

|ГДЕ

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

|СГРУППИРОВАТЬ ПО

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

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

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

Типичные ошибки и как их избежать

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

Вторая группа ошибок — опечатки и несовпадение имён. Имя колонки в коде должно точно совпадать с именем в конфигураторе, включая регистр не имеет значения, но имеет значение каждый символ. Если колонка называется КоличествоУпаковок, обращение к Количество вернёт ошибку или, что хуже, при динамическом обращении через квадратные скобки — Неопределено без явного сообщения.

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

Третья типичная проблема — путаница между данными формы и объектом в управляемых формах. Код, который работал в обычном приложении (ЭтотОбъект.Товары), в управляемой форме требует обращения через реквизит Объект, а для записи — преобразования через РеквизитФормыВЗначение() и обратно через ЗначениеВРеквизитФормы().

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

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

Значение колонки после присвоения
Норма

В отладчике строка содержит новое значение

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

Значение не изменилось — возможно, изменена копия строки, а не строка коллекции

Итог по числовой колонке
Норма

Совпадает с ручным пересчётом нескольких строк

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

Ноль при заполненных строках — проверьте имя и тип колонки

Работа обработчика в форме
Норма

При изменении количества сумма пересчитывается

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

Ошибка при пустой табличной части — нет проверки ТекущиеДанные на Неопределено

FAQ

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

Используйте обращение через квадратные скобки: Строка[ИмяКолонки], где ИмяКолонки — строковая переменная. Этот приём удобен для универсальных процедур, обрабатывающих разные табличные части. Учтите: при неверном имени метод вернёт Неопределено без ошибки, поэтому результат стоит проверять.

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

Напрямую по индексу колонки в прикладном коде обратиться нельзя — колонки доступны только по имени. Если нужно перебрать все колонки, получите их описание через метаданные: Строка.Владелец().Колонки у выгруженной таблицы значений или Метаданные.Документы.ИмяДокумента.ТабличныеЧасти.ИмяТЧ.Реквизиты.

Почему Итог() возвращает ноль, хотя строки заполнены?

Чаще всего причина в неверном имени колонки или в том, что колонка не числового типа — например, цена хранится как строка. Проверьте тип колонки в конфигураторе. Также убедитесь, что вызываете метод у заполненной табличной части, а не у пустой копии.

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

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

Чем ВыгрузитьКолонку() отличается от Выгрузить()?

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

Работает ли обращение к ТекущиеДанные на сервере?

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

Итог

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

Колонка табличной части всегда доступна через строку: по индексу, в цикле Для Каждого или через ТекущиеДанные в форме. Для агрегатов используйте Итог() и ВыгрузитьКолонку(). Проверяйте ТекущиеДанные на Неопределено и не изменяйте состав коллекции внутри цикла перебора.