При разработке интерфейсов для мобильных устройств, веб-клиента или сенсорных терминалов часто возникает необходимость реализовать собственную программную навигацию по табличной части (например, кнопки перелистывания «Вверх» и «Вниз» на определенное количество позиций). Разберем частую проблему, когда попытка манипулировать свойством ТекущаяСтрока как обычным порядковым числом (индексом) приводит к ошибкам или перестает работать после очистки и повторного заполнения таблицы.
Проанализируем механику работы таблиц в управляемом интерфейсе 1С 8.3. Разработчики часто путают два схожих по смыслу понятия:
ТекущаяСтрока) — это уникальный внутренний системный идентификатор строки элемента формы. Свойство ТекущаяСтрока имеет тип Произвольный и хранит именно этот числовой или иной идентификатор, а не номер строки.Рассмотрим, что происходит при очистке таблицы. Когда мы вызываем метод Очистить() для коллекции ДанныеФормыКоллекция и затем добавляем новые элементы, платформа не сбрасывает внутренний счетчик идентификаторов. Идентификаторы новых строк продолжают возрастать (например, 101, 102, 103 и так далее).
Если в коде выполняется арифметическая операция с вычитанием или прибавлением фиксированного числа к свойству ТекущаяСтрока (например, Элементы.Таблица.ТекущаяСтрока = Нажатие - 6), то после очистки таблицы такая логика ломается. Присваиваемое значение перестает соответствовать реальным идентификаторам существующих строк.
Выясним, как организовать корректное перемещение по строкам без риска обращения к несуществующим идентификаторам. Для этого свяжем позиционирование элемента формы ТекущаяСтрока с методом коллекции ПолучитьИдентификатор().
Разберем алгоритм по шагам:
Элементы.Таблица.ТекущиеДанные.Индекс().0 до Количество() - 1).ПолучитьИдентификатор().ТекущаяСтрока элемента таблицы.Рассмотрим пример клиентского кода для кнопки пролистывания таблицы вверх на 6 строк:
&НаКлиенте
Процедура КомандаЛистатьВверх(Команда)
// Получаем текущие данные выделенной строки
ТекДанные = Элементы.ПоискПоШК.ТекущиеДанные;
Если ТекДанные = Неопределено Тогда
Возврат;
КонецЕсли;
// Определяем индекс текущей строки в коллекции
ТекИндекс = Объект.ТоварыПоиска.Индекс(ТекДанные);
// Вычисляем новый индекс со смещением (например, на 6 строк вверх)
Смещение = 6;
НовыйИндекс = Макс(0, ТекИндекс - Смещение);
// Получаем строку коллекции по новому индексу
НоваяСтрока = Объект.ТоварыПоиска[НовыйИндекс];
// Активируем нужную строку по ее уникальному идентификатору
Элементы.ПоискПоШК.ТекущаяСтрока = НоваяСтрока.ПолучитьИдентификатор();
КонецПроцедуры
Для пролистывания вниз алгоритм будет аналогичным, но с ограничением по максимальному индексу коллекции:
&НаКлиенте
Процедура КомандаЛистатьВниз(Команда)
ТекДанные = Элементы.ПоискПоШК.ТекущиеДанные;
Если ТекДанные = Неопределено Тогда
Возврат;
КонецЕсли;
ВсегоСтрок = Объект.ТоварыПоиска.Количество();
Если ВсегоСтрок = 0 Тогда
Возврат;
КонецЕсли;
ТекИндекс = Объект.ТоварыПоиска.Индекс(ТекДанные);
Смещение = 6;
// Ограничиваем максимальный индекс размером коллекции
НовыйИндекс = Мин(ВсегоСтрок - 1, ТекИндекс + Смещение);
НоваяСтрока = Объект.ТоварыПоиска[НовыйИндекс];
Элементы.ПоискПоШК.ТекущаяСтрока = НоваяСтрока.ПолучитьИдентификатор();
КонецПроцедуры
Посмотрим на ситуацию, когда необходимо полностью снять выделение со строки или сбросить текущую позицию (например, при полной очистке списка поиска). Присвоение числа 0 в данном случае является ошибкой, так как ноль воспринимается платформой как идентификатор строки со значением 0.
Чтобы корректно сбросить выделение, присвоим свойству ТекущаяСтрока значение Неопределено:
&НаКлиенте
Процедура СброситьВыделениеТаблицы()
Элементы.ПоискПоШК.ТекущаяСтрока = Неопределено;
КонецПроцедуры
Важно помнить, что в веб-клиенте и мобильном приложении корректное отображение подсвечивания строк также зависит от свойства таблицы ИспользованиеТекущейСтроки. Для постоянного визуального выделения активной позиции рекомендуется устанавливать для этого свойства значение ОтображениеВыделения.