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