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

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

Как в 1С получить идентификатор строки

Как в 1С получить идентификатор строки табличной части, таблицы значений и динамического списка: ТекущаяСтрока, ПолучитьИдентификатор, примеры кода и ошибки.

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

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

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

Что именно вы хотите получить: три разных «идентификатора»

Прежде чем писать код, определите, с каким контекстом вы работаете. От этого зависит весь дальнейший подход, и именно здесь допускают больше всего ошибок.

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

Второй случай — модуль объекта или серверная процедура, где табличная часть доступна как коллекция строк. Здесь никаких идентификаторов формы нет: строки адресуются по индексу (с нуля) или по номеру строки (с единицы, свойство НомерСтроки).

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

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

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

&НаКлиенте

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

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

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

Возврат; // таблица пустая, строки нет

КонецЕсли;

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

Сообщить("Выбрана строка с номером " + ТекущиеДанные.НомерСтроки);

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

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

Если таблица пустая или фокус снят, ТекущаяСтрока возвращает Неопределено. Проверка на это значение обязательна — иначе НайтиПоИдентификатору(Неопределено) вернёт Неопределено, и следующее обращение к полю строки вызовет ошибку выполнения.

Порядок действий
  1. 1
    Определите имя элемента формы, отображающего таблицу (смотрите в дереве элементов формы)
  2. 2
    Получите идентификатор: Элементы.ИмяТаблицы.ТекущаяСтрока
  3. 3
    Проверьте, что значение не равно Неопределено
  4. 4
    Получите данные строки: Объект.ИмяТабличнойЧасти.НайтиПоИдентификатору(Идентификатор)
  5. 5
    Работайте с полями строки через полученный объект ДанныеФормыСтруктура

Обратная задача: получить идентификатор по известной строке

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

&НаКлиенте

Процедура НайтиИАктивизироватьСтроку(Команда)

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

Если СтрокаТовара.Номенклатура = ИскомаяНоменклатура Тогда

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

Прервать;

КонецЕсли;

КонецЦикла;

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

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

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

Идентификация строк в табличной части без формы

В модуле объекта, в серверной процедуре без контекста формы или в фоновом задании работа с табличной частью идёт через индексы и номера строк. Пытаться получить «идентификатор формы» здесь бессмысленно — его не существует.

// Индекс строки — с нуля

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

// Номер строки — с единицы, хранится в самой строке

НомерСтроки = НайденнаяСтрока.НомерСтроки;

// Поиск строки по условию

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

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

Если нужно передать «идентификатор» строки между серверными вызовами, надёжнее всего передавать НомерСтроки или уникальный ключ строки (например, ключ связи в механизмах вроде серий или подарков). Индекс использовать рискованно: при удалении строки из середины коллекции индексы всех последующих строк сдвигаются.

Идентификатор строки в динамическом списке

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

&НаКлиенте

Процедура ОткрытьВыбранныйДокумент(Команда)

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

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

Возврат;

КонецЕсли;

ПоказатьЗначение(, СсылкаНаДокумент);

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

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

Проверка результата и типичные ошибки

После получения идентификатора убедитесь, что дальнейший код работает с реальной строкой. Минимальный набор проверок: идентификатор не Неопределено, НайтиПоИдентификатору() вернул строку, а у полученной строки заполнены ожидаемые поля.

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

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

Значение ТекущаяСтрока
Норма

Число (для таблицы значений) или ссылка (для динамического списка)

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

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

Результат НайтиПоИдентификатору()
Норма

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

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

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

Тип значения в динамическом списке
Норма

Ссылка на объект нужного типа

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

СтрокаГруппировкиДинамическогоСписка — список сгруппирован

Типичные ошибки
01
Использовать ТекущаяСтрока как индекс коллекции: Объект.Товары[ТекущаяСтрока] — идентификатор формы не совпадает с индексом, обращение идёт не к той строке или вызывает ошибку
02
Забыть проверку на Неопределено при пустой таблице — падение на НайтиПоИдентификатору или обращении к полю строки
03
Хранить идентификатор формы между серверными вызовами после пересоздания данных формы — идентификаторы пересчитываются, сохранённое значение указывает не туда
04
Вызывать ПолучитьИдентификатор() в модуле объекта — метод доступен только для данных формы, вне формы его нет
05
Путать НомерСтроки (с единицы) и индекс (с нуля) — смещение на одну строку при программной обработке

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

Выбор подхода под вашу задачу

Маршрут решения

Как выбрать действие

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

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

Итог

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

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

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

Чем идентификатор строки отличается от номера строки?

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

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

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

Можно ли получить идентификатор строки в обычном (неуправляемом) приложении?

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

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

Используйте свойство ВыделенныеСтроки элемента формы: Элементы.Товары.ВыделенныеСтроки. Оно возвращает массив идентификаторов. Пройдите по массиву циклом и для каждого идентификатора вызовите НайтиПоИдентификатору() с проверкой результата на Неопределено.

ТекущаяСтрока динамического списка вернула странное значение, не ссылку. Что это?

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

Как передать строку таблицы с клиента на сервер?

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