В практике разработки на платформе 1С:Предприятие 8.3 часто встречается задача: после обновления данных в дереве или таблице (например, используя флажок в динамическом списке) необходимо вернуть фокус на ту строку, где пользователь находился до обновления. Мы используем стандартный алгоритм: запоминаем ссылку, очищаем коллекцию, заполняем её заново, находим нужный элемент и устанавливаем свойство ТекущаяСтрока. Однако иногда этот механизм дает сбой — у большинства пользователей всё работает корректно, а у одного конкретного сотрудника строка визуально не выделяется. Давайте подробно разберем, почему это происходит и как решить проблему системно.
Рассмотрим стандартный подход, который обычно применяется в управляемых формах. Опираясь на проверенные методы доработки динамических списков, проанализируем пример кода, выполняемого на клиенте после перезаполнения данных:
// Предположим, мы уже нашли нужную строку в данных формы
ЭлементКоллекции = НайтиСтрокуВДеревеДоговоров(Ссылка, НомерГруппы, КореньДерева, 0);
Если ЭлементКоллекции <> Неопределено Тогда
// Получаем идентификатор строки для установки фокуса
ИдентификаторСтроки = ЭлементКоллекции.ПолучитьИдентификатор();
Элементы.Договора.ТекущаяСтрока = ИдентификаторСтроки;
КонецЕсли;
Проблема заключается в том, что в отладчике значение свойства ТекущаяСтрока действительно меняется, но интерфейс формы на это никак не реагирует. Выясним, какие скрытые механизмы могут блокировать это действие. Для этого можно использовать редактор форм в режиме предприятия.
Первым делом проанализируем ситуацию с точки зрения пользовательских настроек. Если ошибка воспроизводится только под одной учетной записью, это часто указывает на специфическое состояние Хранилища настроек или состава формы, для работы с которыми удобно использовать шаблон обработки с системой хранения настроек. Рассмотрим шаги по диагностике:
ХранилищеОбщихНастроек.Удалить().Разберем наиболее интересную и "коварную" причину, которая часто ускользает от внимания разработчика. Платформа 1С оптимизирует передачу данных между сервером и клиентом. Однако некоторые действия вызывают полную перерисовку (пересборку) формы. Рассмотрим ситуацию, когда одновременно с установкой строки мы меняем свойства других элементов, например, кнопок.
Если в коде присутствует условие, которое под конкретным пользователем (в зависимости от его прав или данных) меняет свойство КнопкаПоУмолчанию, Видимость или Доступность, это инициирует обновление всей формы. Платформа сначала устанавливает текущую строку, а затем "накатывает" изменения свойств элементов, что может сбросить фокус или вернуть таблицу в состояние "по умолчанию".
Как это лечится: Избегайте частого изменения свойств элементов, влияющих на структуру формы, в одном серверном вызове с обновлением данных. Если кнопку нужно сделать кнопкой по умолчанию, постарайтесь вынести эту логику отдельно или использовать управление видимостью заранее созданных групп.
Проанализируем работу событий формы. При программной установке свойства ТекущаяСтрока платформа принудительно генерирует событие ПриАктивацииСтроки. Если в этом событии написан код, который:
...то мы можем попасть в ситуацию "зацикливания" или принудительного обновления контекста, которое перекрывает нашу первоначальную установку строки.
Рекомендация: Всегда вставляйте проверку в событие ПриАктивацииСтроки. Если текущие данные не изменились или форма находится в процессе программного обновления, выполнение кода должно прерываться:
&НаКлиенте
Процедура ДоговораПриАктивацииСтроки(Элемент)
ТекущиеДанные = Элемент.ТекущиеДанные;
Если ТекущиеДанные = Неопределено Тогда
Возврат;
КонецЕсли;
// Проверка: действительно ли нужно обновлять связанные данные?
Если ТекущиеДанные.Ссылка = ПоследняяОбработаннаяСсылка Тогда
Возврат;
КонецЕсли;
// Логика обновления...
ПоследняяОбработаннаяСсылка = ТекущиеДанные.Ссылка;
КонецПроцедуры
Если стандартная установка ТекущаяСтрока всё равно игнорируется, применим надежный метод с использованием временной задержки. Это позволит форме завершить все внутренние циклы перерисовки и только потом позиционировать курсор.
Рассмотрим реализацию по шагам:
&НаКлиенте
Перем СохраненныйИдентификаторСтроки;
&НаКлиенте
Процедура ОбновитьДеревоИПозиционировать()
// ... логика обновления дерева ...
СохраненныйИдентификаторСтроки = НайденныйИдентификатор;
// Подключаем однократный обработчик с минимальной задержкой
ПодключитьОбработчикОжидания("УстановитьФокусНаСтроку", 0.1, Истина);
КонецПроцедуры
&НаКлиенте
Процедура УстановитьФокусНаСтроку()
Элементы.Договора.ТекущаяСтрока = СохраненныйИдентификаторСтроки;
// Принудительно возвращаем фокус на само дерево
ТекущийЭлемент = Элементы.Договора;
КонецПроцедуры
Если установка ТекущаяСтрока игнорируется у конкретного пользователя, алгоритм действий должен быть следующим: сначала исключаем влияние настроек формы (сброс к стандарту), затем проверяем, не меняются ли свойства кнопок или видимость панелей одновременно с обновлением данных. Если проблема сохраняется, используем ПодключитьОбработчикОжидания для гарантированной установки фокуса после завершения всех серверных транзакций и перерисовок интерфейса.