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

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

Как получить текущую строку табличной части в 1С

Как получить текущую строку табличной части в 1С 8.3: Элементы.Таблица.ТекущиеДанные, ТекущаяСтрока, обход строк, типовые ошибки и примеры кода для разработчика.

Получение текущей строки табличной части — одна из самых частых задач при доработке форм документов и справочников в 1С:Предприятие 8.3. Она возникает, когда нужно прочитать значения колонок строки, которую выделил пользователь, пересчитать итоги, подставить данные в другие реквизиты или проверить заполнение перед записью.

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

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

Где вообще существует «текущая строка»

Текущая строка — это строка, на которой стоит курсор в табличном поле формы. Она определяется визуальным элементом, а не данными. Поэтому обратиться к ней можно только через элемент формы типа «Таблица» (ТаблицаФормы), который отображает табличную часть, динамический список или таблицу значений.

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

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

Получение текущей строки в управляемой форме

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

&НаКлиенте

Процедура ТоварыПриАктивизацииСтроки(Элемент)

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

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

Возврат; // строка не выбрана

КонецЕсли;

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

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

Объект, возвращаемый ТекущиеДанные, поддерживает чтение и запись: присвоив ТекСтрока.Цена = 100, вы измените данные прямо в форме, и пользователь увидит результат. Однако это не та же самая строка коллекции, а её представление в формате ДанныеФормыСтруктура — у него нет методов коллекции, только поля.

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

Порядок действий
  1. 1
    Найдите в дереве элементов формы таблицу, связанную с табличной частью, и запомните её имя (например, Товары).
  2. 2
    В нужном обработчике напишите: ТекСтрока = Элементы.Товары.ТекущиеДанные;
  3. 3
    Добавьте проверку: Если ТекСтрока = Неопределено Тогда Возврат; КонецЕсли;
  4. 4
    Читайте или изменяйте поля: ТекСтрока.Количество, ТекСтрока.Сумма и т.д.
  5. 5
    Проверьте результат, выделив строку в форме и убедившись, что обработчик срабатывает.

ТекущаяСтрока и НайтиПоИдентификатору

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

&НаКлиенте

Процедура КомандаПоказатьСтроку(Команда)

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

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

Возврат;

КонецЕсли;

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

Сообщить("Номер строки: " + СтрокаКоллекции.НомерСтроки);

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

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

Обратите внимание: НайтиПоИдентификатору доступен и на клиенте, и на сервере, поэтому связка «ТекущаяСтрока → НайтиПоИдентификатору» — стандартный способ передать выбранную строку в серверную процедуру: на клиенте берут идентификатор, передают его параметром, а на сервере находят строку.

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

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

Быстрый доступ к значениям колонок для чтения и записи. Подходит для большинства обработчиков на клиенте. Не даёт методов коллекции и индекса строки.

ТекущаяСтрока + НайтиПоИдентификатору

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

Обход коллекции Объект.Товары

Единственный вариант в модуле объекта и на сервере, где нет понятия текущей строки. Подходит для пересчёта всех строк, а не одной выделенной.

Работа в обычных формах

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

Процедура ТоварыПриАктивизацииСтроки(Элемент)

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

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

Возврат;

КонецЕсли;

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

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

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

Обход всех строк и работа в модуле объекта

Когда нужна не выделенная строка, а все строки табличной части (пересчёт сумм, проверка заполнения, проведение), используют цикл по коллекции. Этот код одинаково работает в модуле объекта и на сервере формы:

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

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

КонецЦикла;

// Доступ по индексу

ПерваяСтрока = Объект.Товары[0]; // если коллекция не пуста

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

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

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

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

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

КонецЕсли;

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

Самая частая ошибка — отсутствие проверки на Неопределено. ТекущиеДанные возвращает Неопределено, когда табличная часть пуста, таблица не в фокусе или пользователь снял выделение. Любое обращение к полю такого «объекта» роняет код.

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

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

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

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

Быстрый способ убедиться, что строка получена правильно — вывести её ключевые поля через Сообщить() или поставить точку останова и посмотреть переменную в табло отладчика. В отладчике объект ДанныеФормыСтруктура раскрывается и показывает значения всех колонок строки.

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

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

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

ТекущиеДанные при выделенной строке
Норма

Возвращает объект, поля читаются, НомерСтроки совпадает с видимой строкой

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

Возвращает Неопределено при явно выделенной строке — проверьте имя элемента формы

Поведение на пустой табличной части
Норма

Код проходит проверку на Неопределено и завершается без ошибок

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

Ошибка «Поле объекта не обнаружено»

Передача строки на сервер
Норма

НайтиПоИдентификатору находит строку с тем же НомерСтроки

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

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

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

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

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

Как получить текущую строку в модуле объекта документа?

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

Почему ТекущиеДанные возвращает Неопределено?

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

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

Да, на клиенте в управляемой форме присваивание вида ТекСтрока.Цена = 100 изменяет данные формы, и пользователь сразу видит результат. В обычной форме изменения попадают напрямую в строку табличной части объекта.

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

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

Как получить текущую строку таблицы значений на форме?

Точно так же, как для табличной части: через Элементы.<ИмяТаблицы>.ТекущиеДанные. Разница лишь в том, что для таблицы значений (ДанныеФормыКоллекция на основе ТЗ) строка тоже ищется по идентификатору через НайтиПоИдентификатору, а не по индексу исходной таблицы значений.

Итог

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

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