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

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

Как обратиться к таблице значений на форме в 1С

Как обратиться к таблице значений на форме в 1С: обращение через реквизит формы, Элементы, ДанныеФормыВЗначение, перебор строк, типовые ошибки и примеры кода.

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

В управляемых формах платформа разделяет данные и их отображение. Элемент формы «Таблица» только показывает данные, а сами данные хранятся в реквизите формы. Поэтому программно читать и изменять строки нужно через реквизит, а не через элемент. Понимание этой связки снимает большинство проблем при работе с таблицами.

Ниже разобраны основные способы обращения к таблице значений на управляемой форме: через реквизит формы, через элемент формы, через ЭтаФорма и Объект, а также перебор строк, поиск, получение текущей строки и типичные ошибки с примерами кода.

Что такое таблица на форме и чем элемент отличается от данных

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

Ключевое правило: чтение и изменение данных выполняется через реквизит, а работа с отображением (текущая строка, видимость, оформление) — через элемент. Если вы пытаетесь прочитать строки через Элементы.Товары, то получите ошибку, потому что у элемента формы нет коллекции строк данных.

Проверить связь можно в конфигураторе: откройте форму, найдите элемент таблицы и посмотрите его свойство «ПутьКДанным» — там указано имя реквизита, с которым связан элемент. Именно это имя и используется в коде для доступа к данным.

Обращение к данным через реквизит формы

В модуле управляемой формы реквизиты доступны напрямую по имени или через ЭтаФорма. Оба варианта равнозначны:

// Оба варианта обращаются к одному и тому же реквизиту

ТЗ = ЭтаФорма.ТаблицаТоваров;

ТЗ = ТаблицаТоваров;

Дальше с полученной таблицей работают как с обычной таблицей значений: перебирают строки, добавляют, удаляют, ищут значения:

// Перебор всех строк

Для Каждого Строка Из ТаблицаТоваров Цикл

Сообщить(Строка.Номенклатура);

КонецЦикла;

// Добавление строки

НоваяСтрока = ТаблицаТоваров.Добавить();

НоваяСтрока.Номенклатура = Справочники.Номенклатура.НайтиПоНаименованию("Тест");

// Количество строк

КоличествоСтрок = ТаблицаТоваров.Количество();

Обратите внимание: колонки, к которым вы обращаетесь в коде (например, Строка.Номенклатура), должны существовать в реквизите формы. Если колонка не добавлена в реквизит, а есть только в элементе формы, обращение к ней вызовет ошибку «Поле объекта не обнаружено».

Получение текущей строки через элемент формы

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

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

Если ТекСтрока = Неопределено Тогда

Сообщить("Строка не выбрана");

Возврат;

КонецЕсли;

Сообщить(ТекСтрока.Номенклатура);

Важно проверять ТекущиеДанные на Неопределено: если таблица пустая или фокус не в ней, свойство вернёт Неопределено, и обращение к полям приведёт к ошибке. Также через элемент доступен идентификатор текущей строки:

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

Если Идентификатор <> Неопределено Тогда

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

КонецЕсли;

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

Порядок действий
  1. 1
    Определите имя реквизита формы типа ТаблицаЗначений через свойство ПутьКДанным элемента таблицы
  2. 2
    В коде обратитесь к данным: ЭтаФорма.ИмяРеквизита или просто ИмяРеквизита
  3. 3
    Для текущей строки используйте Элементы.ИмяТаблицы.ТекущиеДанные с проверкой на Неопределено
  4. 4
    Проверьте результат: изменения в реквизите сразу видны в таблице на форме

Обращение к табличной части объекта на форме

Если форма принадлежит документу или справочнику, таблица на форме часто отображает не отдельный реквизит, а табличную часть объекта. Тогда обращаться к ней нужно через реквизит Объект:

// Перебор строк табличной части "Товары" документа

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

СуммаДокумента = СуммаДокумента + Строка.Сумма;

КонецЦикла;

// Текущая строка табличной части

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

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

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

bsl
&НаСервере
Процедура СвернутьТаблицуНаСервере()
    ТЗ = ДанныеФормыВЗначение(ТаблицаТоваров, Тип("ТаблицаЗначений"));
    ТЗ.Свернуть("Номенклатура", "Количество,Сумма");
    ЗначениеВДанныеФормы(ТЗ, ТаблицаТоваров);
КонецПроцедуры

Поиск строк и работа с отбором

Для поиска нужных строк в таблице формы используются стандартные методы таблицы значений. Самый простой — НайтиСтроки() со структурой отбора:

Отбор = Новый Структура("Номенклатура", ИскомаяНоменклатура);

НайденныеСтроки = ТаблицаТоваров.НайтиСтроки(Отбор);

Для Каждого Строка Из НайденныеСтроки Цикл

Строка.Цена = НоваяЦена;

КонецЦикла;

Для поиска первой подходящей строки можно использовать Найти() по значению в колонке. Если нужно найти строку по индексу, помните, что нумерация строк начинается с нуля: первая строка — ТаблицаТоваров[0], последняя — ТаблицаТоваров[ТаблицаТоваров.Количество() - 1].

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

Элементы.ТаблицаТоваров.ОтборСтрок = Новый ФиксированнаяСтруктура("Склад", ВыбранныйСклад);

// Снять отбор

Элементы.ТаблицаТоваров.ОтборСтрок = Неопределено;

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

Контекст выполнения: клиент и сервер

В управляемых формах код делится на клиентский и серверный, и это влияет на доступ к таблице. Реквизит формы типа «ТаблицаЗначений» доступен и на клиенте, и на сервере — это один из немногих типов, которые платформа передаёт между контекстами целиком. Поэтому перебор строк можно выполнять в клиентской процедуре без вызова сервера.

Однако методы ДанныеФормыВЗначение() и ЗначениеВДанныеФормы() доступны только на сервере. Если нужно свернуть таблицу, выгрузить её или выполнить запрос по её данным — оформляйте серверную процедуру и передавайте туда реквизит формы как параметр типа «ДанныеФормыКоллекция» либо работайте с ним напрямую в контексте формы.

Также учитывайте директивы компиляции: процедуры с &НаКлиенте не могут вызывать запросы и обращаться к базе данных, поэтому типовой шаблон — собрать данные из таблицы на клиенте, передать на сервер и там выполнить запрос.

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

Реквизит формы (ЭтаФорма.ИмяТаблицы)

Основной способ чтения и изменения данных. Работает на клиенте и сервере. Не подходит для методов настоящей ТаблицыЗначений без преобразования

Элементы.ИмяТаблицы

Только для отображения: текущая строка, отбор строк, видимость. Данные через него не читаются

Объект.ИмяТабличнойЧасти

Для форм документов и справочников, где таблица отображает табличную часть. Изменения попадают в объект при записи

ДанныеФормыВЗначение

Когда нужны методы ТаблицыЗначений: Свернуть, Выгрузить, Сортировать. Только на сервере, требует обратного преобразования

Проверка результата и отладка

После написания кода проверьте результат в пользовательском режиме: изменения в реквизите формы должны моментально отображаться в таблице. Если таблица визуально не обновилась — скорее всего, вы изменили не тот реквизит или локальную копию, а не реквизит формы.

Для отладки удобно выводить количество строк и содержимое первой строки через Сообщить() или использовать отладчик с точкой останова в модуле формы. В отладчике реквизит формы виден как коллекция, и можно раскрыть любую строку и проверить значения колонок.

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

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

Отображение данных
Норма

После изменения реквизита строки в таблице на форме обновились сразу

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

Данные в коде меняются, а на форме нет — изменён не тот реквизит или локальная копия

Обращение к колонке
Норма

Значение читается без ошибок

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

Ошибка «Поле объекта не обнаружено» — колонки нет в реквизите формы

Текущая строка
Норма

ТекущиеДанные возвращает строку с ожидаемыми значениями

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

Возвращается Неопределено — таблица пуста или фокус не в ней

Частые вопросы

Почему возникает ошибка «Поле объекта не обнаружено» при обращении к таблице?

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

Как получить выделенные строки, если включён множественный выбор?

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

Можно ли вызвать Свернуть() или Выгрузить() у реквизита формы напрямую?

Нет. Реквизит формы — это объект ДанныеФормыКоллекция, у него ограниченный набор методов. Сначала преобразуйте его на сервере через ДанныеФормыВЗначение(Реквизит, Тип("ТаблицаЗначений")), выполните нужные операции и верните результат через ЗначениеВДанныеФормы().

Как программно установить текущую строку таблицы?

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

В чём разница между ЭтаФорма.Таблица и Объект.Таблица?

Первый вариант — обращение к самостоятельному реквизиту формы типа ТаблицаЗначений, не связанному с данными объекта. Второй — обращение к табличной части документа или справочника, данные которого редактирует форма. Правильный путь виден в свойстве ПутьКДанным элемента таблицы.

Как очистить таблицу на форме?

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

Итог

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

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