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