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

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

Как в 1С получить строку таблицы формы

Разбираем, как в 1С получить строку таблицы формы: текущие данные, поиск по идентификатору, обход коллекции, типичные ошибки и примеры кода.

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

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

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

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

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

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

Получение текущей строки на клиенте

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

&НаКлиенте

Процедура ПриНажатииКнопки(Команда)

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

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

ПоказатьПредупреждение(, "Строка не выбрана");

Возврат;

КонецЕсли;

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

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

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

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

Получение строки по идентификатору на сервере

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

&НаСервере

Процедура ОбработатьСтрокуНаСервере()

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

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

Возврат;

КонецЕсли;

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

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

ТекСтрока.Цена = ПересчитатьЦену(ТекСтрока.Номенклатура);

КонецЕсли;

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

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

Как получить выделенную строку на сервере
  1. 1
    Прочитайте Элементы.ИмяТаблицы.ТекущаяСтрока — это числовой идентификатор
  2. 2
    Проверьте, что идентификатор не равен Неопределено
  3. 3
    Вызовите Коллекция.НайтиПоИдентификатору(Идентификатор)
  4. 4
    Проверьте результат на Неопределено и работайте со строкой

Обход всех строк коллекции

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

&НаКлиенте

Процедура ПроверитьЗаполнение()

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

Если Не ЗначениеЗаполнено(Строка.Количество) Тогда

Сообщить("Не заполнено количество в строке " + Строка.НомерСтроки);

КонецЕсли;

КонецЦикла;

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

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

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

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

Если Найденные.Количество() > 0 Тогда

Строка = Найденные[0];

КонецЕсли;

Особенности для динамических списков и деревьев

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

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

Способы получения строки

ТекущиеДанные

Только клиент, выделенная строка, быстро. Не работает на сервере

НайтиПоИдентификатору

Клиент и сервер, нужен идентификатор строки. Универсальный способ

НайтиСтроки

Поиск по значениям колонок, возвращает массив. Не ищет по выделению

Цикл по коллекции

Полный обход всех строк. Для деревьев нужна рекурсия

Типичные ошибки и как их проверить

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

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

Типичные ошибки
01
Вызов ТекущиеДанные на сервере — свойство доступно только на клиенте, используйте НайтиПоИдентификатору
02
Чтение колонок без проверки на Неопределено — падение при невыбранной строке
03
Поиск строки по экранному номеру — после сортировки индексы не совпадают, используйте идентификатор
04
Ожидание числового идентификатора у динамического списка — там ТекущаяСтрока содержит ссылку
Контрольные точки

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

Тип полученного значения
Норма

Объект с доступными колонками строки

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

Неопределено — строка не выбрана или идентификатор устарел

Изменение значения в строке
Норма

Изменение сразу видно в таблице на форме

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

Меняется копия данных, форма не обновляется — проверьте, что работаете с реквизитом формы

Работа после серверного вызова
Норма

Идентификаторы строк сохранились, выделение на месте

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

Коллекция пересоздана, старые идентификаторы не находят строки

FAQ

Чем ТекущиеДанные отличается от ТекущаяСтрока?

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

Почему НайтиПоИдентификатору возвращает Неопределено?

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

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

В модуле объекта табличная часть доступна напрямую как коллекция: ЭтотОбъект.Товары. Понятия «текущая строка» там нет — работайте циклом или НайтиСтроки(). Интерактивное выделение существует только на форме.

Можно ли изменить строку через ТекущиеДанные на клиенте?

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

Как узнать индекс текущей строки в коллекции?

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

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

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

Итог

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

Текущую строку на клиенте берите через ТекущиеДанные, на сервере — через ТекущаяСтрока и НайтиПоИдентификатору. Всегда проверяйте результат на Неопределено, а для поиска по значениям используйте НайтиСтроки. Для динамических списков ТекущаяСтрока — это ссылка, а не идентификатор.