Как программно установить текущую строку динамического списка в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Часто при разработке на управляемых формах 1С возникает задача программно установить курсор на определенную строку динамического списка, например, после обновления данных. Начинающие разработчики иногда пытаются обратиться к списку как к массиву элементов, используя конструкции вроде Элементы.МойСписок.ТекущаяСтрока = МойСписок[0].ПолучитьИдентификатор(), и в результате получают ошибку исполнения. Разберем по шагам, почему возникает эта ошибка и как правильно позиционировать курсор в различных ситуациях.

Почему обращение по индексу вызывает ошибку?

Проанализируем ситуацию. В платформе 1С динамический список не является ни массивом, ни таблицей значений. Это специализированный объект интерфейса, предназначенный для порционного чтения данных из базы. К нему нельзя обратиться по индексу строки, так как не все данные загружены в оперативную память.

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

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

Позиционирование в списках справочников и документов

Если в качестве основной таблицы динамического списка выступает объект ссылочного типа (например, справочник или документ), то ключом позиционирования является сама ссылка на этот объект.

Рассмотрим пример установки текущей строки для ссылочных типов. Ссылку необходимо предварительно получить запросом или сохранить в переменную:


// ИскомаяСсылка - переменная, содержащая ссылку на документ или элемент справочника
Элементы.МойСписок.ТекущаяСтрока = ИскомаяСсылка;

Установка курсора в списках регистров сведений

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

Вам необходимо создать структуру, содержащую значения всех измерений регистра (и периода, если регистр периодический), а затем на её основе получить ключ:


Отбор = Новый Структура;
Отбор.Вставить("Измерение1", Значение1);
Отбор.Вставить("Измерение2", Значение2);

// Получаем ключ записи регистра
Ключ = РегистрыСведений.ИмяРегистра.СоздатьКлючЗаписи(Отбор);

// Устанавливаем текущую строку в списке
Элементы.МойСписок.ТекущаяСтрока = Ключ;

Решение проблемы асинхронного обновления списка

Обновление данных динамического списка (через метод Обновить()) происходит асинхронно. Если сразу в следующей строке кода попытаться установить свойство ТекущаяСтрока, список может еще не успеть перечитать данные из базы. В результате позиционирование не сработает, и курсор сбросится на первую строку.

Посмотрим на надежные подходы для решения этой проблемы:

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

Сохранение контекста при выполнении операций

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

Рассмотрим пример сохранения контекста:


// 1. Сохраняем текущую позицию
СохраненнаяСтрока = Элементы.МойСписок.ТекущаяСтрока;

// 2. Выполняем какие-либо действия...
// ...

// 3. Возвращаем фокус обратно
Элементы.МойСписок.ТекущаяСтрока = СохраненнаяСтрока;

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

← На главную