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