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