При разработке интерфейсов на управляемых формах 1С часто возникает неприятный эффект: в динамическом списке настроено свойство Автообновление (например, каждые 60 секунд), но при каждом срабатывании этого обновления курсор пользователя «прыгает» на самую первую строку. Это крайне неудобно для оперативной работы, так как сбивает фокус и заставляет пользователя заново искать строку, с которой он работал. Разберем подробно, почему это происходит и как правильно настроить динамический список, чтобы позиционирование сохранялось.
Для начала проанализируем внутренний механизм работы динамического списка. Чтобы после обновления данных (будь то программный метод Обновить() или автоматическое обновление) фокус остался на прежнем месте, платформа должна однозначно идентифицировать строку, которая была выделена до обновления. Для этой идентификации 1С использует Ключ строки.
Если после обновления данных платформа не может найти в новом наборе данных строку с тем же самым уникальным ключом, она считает текущую позицию потерянной и, следуя стандартному алгоритму, устанавливает курсор на самую первую запись в списке. Рассмотрим ситуации, при которых ключ может быть определен некорректно.
Чаще всего проблема кроется в свойстве Основная таблица динамического списка. Посмотрим на примере из практики, который обсуждался в сообществе. Допустим, у нас есть запрос, который выбирает данные из регистра сведений СостояниеВагонов, но в настройках динамического списка в качестве основной таблицы указан Документ.АктПриемкиВагона.
ВЫБРАТЬ
регСостояние.АктПриемки КАК АктПриемки,
докАкт.Дата КАК ДатаПоступления,
регСостояние.Вагон КАК Вагон
ИЗ
РегистрСведений.СостояниеВагонов КАК регСостояние
ЛЕВОЕ СОЕДИНЕНИЕ Документ.АктПриемкиВагона КАК докАкт
ПО регСостояние.АктПриемки = докАкт.Ссылка
ГДЕ
регСостояние.СостояниеВагона В(&СостоянияВагона)
Когда мы указываем основную таблицу (например, документ), платформа автоматически назначает полем ключа Ссылка этого документа. Однако, если в результате запроса (из-за особенностей данных или соединений) одна и та же ссылка документа встречается в нескольких строках списка, или если ссылка вовсе не заполнена (равна NULL), уникальность ключа нарушается. В момент автообновления 1С «запутывается» в этих дублях и сбрасывает фокус на начало списка.
Если использование основной таблицы приводит к сбросу строки, нам необходимо перейти к ручному управлению идентификацией. Рассмотрим по шагам, как это сделать в конфигураторе:
АктПриемки, если мы уверены, что он уникален для каждой строки регистра в данном контексте, либо комбинация АктПриемки + Вагон.Важный момент: Если вы работаете с регистром сведений, ключом строки обычно является набор всех его измерений. Только такая комбинация гарантирует, что платформа всегда найдет нужную строку при обновлении.
Иногда причина кроется не в настройках метаданных, а в коде формы. Проанализируем обработчик события ПриАктивизацииСтроки. Если в этом обработчике присутствуют серверные вызовы с контекстом (передача всей формы на сервер), это может вызвать побочный эффект при автообновлении. Платформа пытается обновить данные, это вызывает активацию строки, активация вызывает серверный переход, который в свою очередь может инициировать повторную отрисовку элементов формы.
Рекомендуется придерживаться следующих правил в ПриАктивизацииСтроки:
&НаСервереБезКонтекста.Рассмотрим еще несколько нюансов, которые могут влиять на «прыжки» курсора:
1. Сортировка данных: Если в списке установлена сложная сортировка по полям, которые не проиндексированы в базе данных, платформа может выполнять перестроение списка дольше обычного. В редких случаях при использовании Background data fetch (фонового получения данных) это приводит к визуальным артефактам позиционирования.
2. Свойство «ВосстанавливатьТекущуюСтроку»: Хотя автор темы упоминал, что эта галка (RestoreCurrentRow) ему не помогла, в общем случае она должна быть включена. Она отвечает за сохранение позиции при закрытии и повторном открытии формы, но также влияет на механизмы кэширования строк в памяти клиента.
3. Динамическое считывание данных: Если список очень большой и включено динамическое считывание, убедитесь, что ключевые поля не принимают значения NULL. Строки с пустыми ключами всегда конфликтуют между собой, заставляя фокус «улетать» вверх.
Чтобы окончательно решить проблему, выполним следующие действия:
Соблюдение этих правил обеспечит стабильную работу интерфейса, и автообновление динамического списка перестанет мешать комфортной работе пользователей.