Почему программная установка текущей строки в дереве или таблице игнорируется у отдельных пользователей

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

В практике разработки на платформе 1С:Предприятие 8.3 часто встречается задача: после обновления данных в дереве или таблице (например, используя флажок в динамическом списке) необходимо вернуть фокус на ту строку, где пользователь находился до обновления. Мы используем стандартный алгоритм: запоминаем ссылку, очищаем коллекцию, заполняем её заново, находим нужный элемент и устанавливаем свойство ТекущаяСтрока. Однако иногда этот механизм дает сбой — у большинства пользователей всё работает корректно, а у одного конкретного сотрудника строка визуально не выделяется. Давайте подробно разберем, почему это происходит и как решить проблему системно.

Типичный алгоритм позиционирования на строке

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


// Предположим, мы уже нашли нужную строку в данных формы
ЭлементКоллекции = НайтиСтрокуВДеревеДоговоров(Ссылка, НомерГруппы, КореньДерева, 0);

Если ЭлементКоллекции <> Неопределено Тогда
    // Получаем идентификатор строки для установки фокуса
    ИдентификаторСтроки = ЭлементКоллекции.ПолучитьИдентификатор();
    Элементы.Договора.ТекущаяСтрока = ИдентификаторСтроки;
КонецЕсли;

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

Причина №1: Влияние настроек формы и кэша

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

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

Причина №2: Изменение свойств элементов формы (Кнопка по умолчанию)

Разберем наиболее интересную и "коварную" причину, которая часто ускользает от внимания разработчика. Платформа 1С оптимизирует передачу данных между сервером и клиентом. Однако некоторые действия вызывают полную перерисовку (пересборку) формы. Рассмотрим ситуацию, когда одновременно с установкой строки мы меняем свойства других элементов, например, кнопок.

Если в коде присутствует условие, которое под конкретным пользователем (в зависимости от его прав или данных) меняет свойство КнопкаПоУмолчанию, Видимость или Доступность, это инициирует обновление всей формы. Платформа сначала устанавливает текущую строку, а затем "накатывает" изменения свойств элементов, что может сбросить фокус или вернуть таблицу в состояние "по умолчанию".

Как это лечится: Избегайте частого изменения свойств элементов, влияющих на структуру формы, в одном серверном вызове с обновлением данных. Если кнопку нужно сделать кнопкой по умолчанию, постарайтесь вынести эту логику отдельно или использовать управление видимостью заранее созданных групп.

Причина №3: Рекурсивные события в обработчиках ПриАктивацииСтроки

Проанализируем работу событий формы. При программной установке свойства ТекущаяСтрока платформа принудительно генерирует событие ПриАктивацииСтроки. Если в этом событии написан код, который:

...то мы можем попасть в ситуацию "зацикливания" или принудительного обновления контекста, которое перекрывает нашу первоначальную установку строки.

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


&НаКлиенте
Процедура ДоговораПриАктивацииСтроки(Элемент)
    ТекущиеДанные = Элемент.ТекущиеДанные;
    Если ТекущиеДанные = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Проверка: действительно ли нужно обновлять связанные данные?
    Если ТекущиеДанные.Ссылка = ПоследняяОбработаннаяСсылка Тогда
        Возврат;
    КонецЕсли;
    
    // Логика обновления...
    ПоследняяОбработаннаяСсылка = ТекущиеДанные.Ссылка;
КонецПроцедуры

Универсальное решение через обработчик ожидания

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

Рассмотрим реализацию по шагам:

  1. Создадим переменную модуля формы для хранения идентификатора строки.
  2. В основном коде, вместо прямой установки строки, запишем идентификатор в переменную и подключим обработчик ожидания.
  3. В самом обработчике установим строку и фокус на элемент.

&НаКлиенте
Перем СохраненныйИдентификаторСтроки;

&НаКлиенте
Процедура ОбновитьДеревоИПозиционировать()
    // ... логика обновления дерева ...
    СохраненныйИдентификаторСтроки = НайденныйИдентификатор;
    
    // Подключаем однократный обработчик с минимальной задержкой
    ПодключитьОбработчикОжидания("УстановитьФокусНаСтроку", 0.1, Истина);
КонецПроцедуры

&НаКлиенте
Процедура УстановитьФокусНаСтроку()
    Элементы.Договора.ТекущаяСтрока = СохраненныйИдентификаторСтроки;
    // Принудительно возвращаем фокус на само дерево
    ТекущийЭлемент = Элементы.Договора;
КонецПроцедуры

Подведем итоги

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

← На главную