Разработка и Конфигурация · 10 мин
Как обратиться к реквизиту табличной части на форме 1С
Как программно обратиться к реквизиту табличной части на управляемой и обычной форме 1С: ЭлементыФормы, ЭтаФорма, ТекущиеДанные, примеры кода и типичные ошибки.
Обращение к реквизиту табличной части на форме — одна из самых частых задач при доработке конфигураций 1С. Сложность в том, что путь к данным зависит от типа формы (управляемая или обычная), от того, нужна ли текущая строка или конкретная по индексу, и от того, где выполняется код — на клиенте или на сервере.
Ключевой принцип: табличная часть на форме — это не сам реквизит объекта, а элемент формы, связанный с данными. Поэтому обращение вида Элементы.Товары.Количество не сработает — сначала нужно получить строку таблицы (текущую или по индексу), и только потом читать или менять её реквизит.
Ниже разобраны рабочие способы для управляемых и обычных форм, обращение по индексу и по текущей строке, типичные ошибки и способы проверить результат.
Что нужно понять перед обращением к данным
На форме существуют два разных слоя: данные формы (реквизиты формы, включая табличные части объекта) и элементы формы (визуальные таблицы, поля, колонки). Элемент формы только отображает данные и управляет интерактивностью — текущей строкой, выделением, видимостью. Само значение хранится в данных.
Отсюда главное правило: чтобы прочитать или изменить значение реквизита табличной части, нужно получить строку данных. Есть два пути: взять текущую строку через элемент формы (ТекущиеДанные) или обратиться к строке напрямую в данных по индексу или итератором в цикле.
Управляемая форма: обращение к текущей строке
Самый частый сценарий — получить значение из той строки, которую пользователь сейчас редактирует. Для этого используется свойство ТекущиеДанные элемента формы типа «Таблица»:
&НаКлиенте
Процедура ТоварыКоличествоПриИзменении(Элемент)
ТекСтрока = Элементы.Товары.ТекущиеДанные;
Если ТекСтрока = Неопределено Тогда
Возврат;
КонецЕсли;
ТекСтрока.Сумма = ТекСтрока.Количество * ТекСтрока.Цена;
КонецПроцедуры
Здесь Элементы.Товары — элемент формы (таблица), ТекущиеДанные — объект типа «ДанныеФормыЭлементКоллекции», через который доступны реквизиты строки: ТекСтрока.Номенклатура, ТекСтрока.Цена и так далее.
Обязательно проверяйте ТекущиеДанные на Неопределено: если таблица пустая или строка потеряла фокус, свойство вернёт Неопределено, и обращение к реквизиту вызовет ошибку «Поле объекта не обнаружено».
Управляемая форма: обращение по индексу и перебор строк
Если нужна не текущая, а конкретная строка, обращайтесь к данным объекта напрямую. В форме документа табличная часть доступна через основной реквизит формы Объект:
&НаСервере
Процедура ЗаполнитьЦеныНаСервере()
Для Каждого СтрокаТовары Из Объект.Товары Цикл
СтрокаТовары.Цена = ПолучитьЦену(СтрокаТовары.Номенклатура);
СтрокаТовары.Сумма = СтрокаТовары.Количество * СтрокаТовары.Цена;
КонецЦикла;
КонецПроцедуры
Обращение по индексу выглядит так: Объект.Товары[0].Количество — первая строка, индексация с нуля. Количество строк — Объект.Товары.Количество().
Важный нюанс: на клиенте в управляемой форме Объект тоже доступен для чтения и изменения табличных частей (это данные формы), поэтому простые переборы можно делать и в клиентских процедурах. Серверные вызовы нужны, когда внутри цикла требуется запрос к базе данных.
Обычная форма: ЭлементыФормы и ТекущиеДанные
В обычных формах (режим обычного приложения, платформа 8.2/8.3) синтаксис отличается именем коллекции элементов — ЭлементыФормы вместо Элементы:
Процедура ТоварыПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
Если ДанныеСтроки.Количество > 100 Тогда
ОформлениеСтроки.ЦветФона = WebЦвета.СветлоЖелтый;
КонецЕсли;
КонецПроцедуры
Процедура КнопкаЗаполнитьНажатие(Элемент)
ТекСтрока = ЭлементыФормы.Товары.ТекущиеДанные;
Если ТекСтрока <> Неопределено Тогда
Сообщить("В текущей строке: " + ТекСтрока.Номенклатура);
КонецЕсли;
КонецПроцедуры
В обычной форме табличное поле также предоставляет ТекущаяСтрока — саму строку табличной части, а перебор выполняется напрямую по коллекции Товары или Объект.Товары в зависимости от того, как устроен реквизит формы.
Как обратиться извне: из другой формы или модуля
Иногда нужно прочитать реквизит табличной части открытой формы извне — например, из обработки или другой формы. Для этого используется ПолучитьФорму() или ссылка на уже открытую форму, после чего обращение идёт через её реквизиты:
ФормаДокумента = ПолучитьФорму("Документ.РеализацияТоваровУслуг.Форма.ФормаДокумента");
// Для открытой формы — через параметры или владельца
ДанныеСтроки = ФормаДокумента.Объект.Товары[0];
СуммаПервойСтроки = ДанныеСтроки.Сумма;
Такой подход хрупок: форма может быть закрыта, а её структура — измениться при обновлении конфигурации. Надёжнее передавать данные через параметры формы, оповещения (Оповестить / ОбработкаОповещения) или через объект в базе данных.
Табличная часть как реквизит формы (не объекта)
В некоторых формах — особенно внешних обработок и сложных документах — таблица на форме связана не с табличной частью объекта, а с отдельным реквизитом формы типа «ТаблицаЗначений» (в данных формы — ДанныеФормыКоллекция). Тогда обращение идёт по имени реквизита формы:
&НаКлиенте
Процедура ПересчитатьИтог(Команда)
Итог = 0;
Для Каждого Строка Из ТаблицаРасчета Цикл
Итог = Итог + Строка.Сумма;
КонецЦикла;
ИтогоПоТаблице = Итог;
КонецПроцедуры
Здесь ТаблицаРасчета — реквизит формы. Текущая строка по-прежнему доступна через Элементы.ТаблицаРасчета.ТекущиеДанные. Отличить такой случай просто: посмотрите в конфигураторе свойство ПутьКДанным элемента формы — там будет указано, к чему привязана таблица.
Какой способ выбрать
Как проверить, что обращение работает
Самый быстрый способ отладки — вывести значение через Сообщить() или поставить точку останова и посмотреть в табло значение выражения Элементы.Товары.ТекущиеДанные. Если в табло отображается «Неопределено» — проблема в фокусе строки, если «Поле объекта не обнаружено» — неверное имя реквизита или таблицы.
Проверьте также, что имя элемента формы совпадает с именем в коде с учётом регистра не обязательно, но по написанию — обязательно: переименование элемента в конфигураторе без правки кода — частая причина ошибок после доработок.
Как проверить результат
Объект с полями строки табличной части
Неопределено — нет активной строки
Совпадает с именем колонки табличной части в конфигураторе
Опечатка — ошибка «Поле объекта не обнаружено»
Указывает на Объект.Товары или реквизит формы
Пустое или неверное — таблица не связана с данными
Новое значение сразу видно на форме
Значение меняется в данных, но не отображается — проверьте привязку колонки
FAQ: частые вопросы
Чем ТекущаяСтрока отличается от ТекущиеДанные?
ТекущаяСтрока — это идентификатор строки (число для ДанныеФормыКоллекция или ссылка на строку), а ТекущиеДанные — объект с самими значениями реквизитов строки. Для чтения и изменения значений используйте ТекущиеДанные; идентификатор нужен для метода НайтиПоИдентификатору и методов вроде ОкончаниеПеретаскивания.
Как обратиться к реквизиту табличной части на сервере, если ТекущиеДанные недоступны?
ТекущиеДанные — клиентское свойство элемента формы, на сервере его нет. Передайте на сервер идентификатор строки (Элементы.Товары.ТекущаяСтрока) и получите данные через РеквизитФормы.НайтиПоИдентификатору(Идентификатор), либо работайте напрямую с Объект.Товары по индексу.
Почему возникает ошибка «Поле объекта не обнаружено»?
Три основные причины: ТекущиеДанные равны Неопределено (нет активной строки), опечатка в имени реквизита или таблицы, либо обращение идёт к элементу формы вместо данных. Проверьте в отладчике, какой именно объект получен, и сверьте имена с конфигуратором.
Как изменить реквизит всех строк табличной части одной командой?
Используйте цикл Для Каждого по Объект.ИмяТабличнойЧасти и присваивайте значение каждой строке. Если внутри цикла нужны данные из базы (цены, остатки), выполняйте обработку на сервере, чтобы не плодить серверные вызовы на каждую строку.
Можно ли обратиться к табличной части документа, не открывая форму?
Да, через объект в базе данных: ДокументОбъект = Ссылка.ПолучитьОбъект(); затем ДокументОбъект.Товары[0].Количество. Для чтения без блокировки лучше использовать запрос к табличной части — он быстрее и не требует получения всего объекта.
Что делать, если таблица на форме называется иначе, чем табличная часть?
Имя элемента формы и имя табличной части могут различаться. В коде Элементы.ИмяЭлементаФормы используется имя элемента, а Объект.ИмяТабличнойЧасти — имя из метаданных. Точную связь показывает свойство ПутьКДанным таблицы в конфигураторе.
Что важно запомнить
Данные табличной части живут в реквизитах формы, а элементы формы — только отображение. Текущую строку читают через Элементы.Таблица.ТекущиеДанные с обязательной проверкой на Неопределено, произвольные строки — через Объект.ТабличнаяЧасть по индексу или в цикле. Имя элемента формы и имя табличной части могут не совпадать — сверяйтесь со свойством ПутьКДанным.