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