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