Как отменить автоматическую активизацию строки в таблице на форме при ее заполнении

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

При разработке сложных интерфейсов на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с проблемой «зацикливания» или избыточного срабатывания событий. Типичная ситуация: на форме расположены несколько связанных таблиц (например, Таб1, Таб2 и Таб3). Предполагается, что при выборе строки в первой таблице должны обновляться вторая и третья. Однако программное заполнение второй таблицы автоматически вызывает её событие ПриАктивизацииСтроки, которое, в свою очередь, запускает собственный алгоритм обновления третьей таблицы. Это может привести к конфликтам логики, замедлению работы интерфейса или некорректному отображению данных.

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

Метод 1. Использование программного флага (блокировки)

Проанализируем самый простой и надежный способ — использование переменной-флага в модуле формы. Этот метод позволяет временно «отключить» логику обработчика события ПриАктивизацииСтроки для второй таблицы в тот момент, когда данные в нее записываются из первой.

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

  1. Объявим переменную в разделе описания переменных модуля формы.
  2. В процедуре обработки активации строки первой таблицы будем устанавливать этот флаг в Истина перед заполнением второй таблицы.
  3. В обработчике второй таблицы добавим проверку этого флага.

Рассмотрим пример кода:


&НаКлиенте
Перем БлокировкаОбновленияТаб2;

&НаКлиенте
Процедура Таб1ПриАктивизацииСтроки(Элемент)
    
    // Устанавливаем флаг, чтобы Таб2 знала: обновление идет программно
    БлокировкаОбновленияТаб2 = Истина;
    
    // Алгоритм заполнения Таб2 данными
    ЗаполнитьТаблицу2НаСервере(Элементы.Таб1.ТекущаяСтрока);
    
    // После заполнения Таб2, алгоритм Таб1 сам заполняет Таб3
    ЗаполнитьТаблицу3НаСервере(Элементы.Таб1.ТекущаяСтрока);
    
    // Снимать флаг здесь не всегда безопасно, так как событие 
    // ПриАктивизацииСтроки Таб2 может сработать чуть позже.
    // Лучше сбрасывать его внутри самого события Таб2.
КонецПроцедуры

&НаКлиенте
Процедура Таб2ПриАктивизацииСтроки(Элемент)
    
    Если БлокировкаОбновленияТаб2 = Истина Тогда
        // Сбрасываем флаг и выходим, игнорируя программную активацию
        БлокировкаОбновленияТаб2 = Ложь;
        Возврат;
    КонецЕсли;
    
    // Стандартная логика при ручном клике пользователя по Таб2
    ЗаполнитьТаблицу3ПоДаннымТаб2(Элементы.Таб2.ТекущаяСтрока);
    
КонецПроцедуры

Метод 2. Проверка текущего элемента формы

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

Проанализируем ситуацию в коде обработчика Таб2ПриАктивизацииСтроки:


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

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

Метод 3. Сравнение идентификатора текущей строки

Часто событие ПриАктивизацииСтроки срабатывает избыточно: при обновлении формы, изменении видимости элементов или просто при обновлении данных без фактического перехода на другую строку. Чтобы избежать лишних расчетов, мы можем запоминать идентификатор последней обработанной строки.

Посмотрим на пример реализации:


&НаКлиенте
Перем ПоследнийИдентификаторТаб2;

&НаКлиенте
Процедура Таб2ПриАктивизацииСтроки(Элемент)
    
    ТекущаяСтрока = Элементы.Таб2.ТекущаяСтрока;
    
    // Если строка не изменилась, ничего не делаем
    Если ТекущаяСтрока = ПоследнийИдентификаторТаб2 Тогда
        Возврат;
    КонецЕсли;
    
    ПоследнийИдентификаторТаб2 = ТекущаяСтрока;
    
    // Выполняем полезную работу
    ОбновитьЗависимыеТаблицы();
    
КонецПроцедуры

Метод 4. Использование обработчика ожидания

Если логика заполнения таблиц «тяжелая» и вызывает визуальные фризы или конфликты отрисовки, рекомендуется использовать метод ПодключитьОбработчикОжидания. Это позволяет вынести выполнение кода в отдельный поток обработки событий интерфейса, когда все автоматические процессы активации уже завершены.

Разберем этот подход:


&НаКлиенте
Процедура Таб2ПриАктивизацииСтроки(Элемент)
    
    // Вместо мгновенного выполнения вызываем процедуру с задержкой 0.1 сек
    // Параметр "ИмяПроцедуры" должен быть строкой, 
    // а сама процедура должна быть экспортной в модуле формы или просто доступной
    ОтключитьОбработчикОжидания("ВыполнитьОбновлениеТаб3");
    ПодключитьОбработчикОжидания("ВыполнитьОбновлениеТаб3", 0.1, Истина);
    
КонецПроцедуры

&НаКлиенте
Процедура ВыполнитьОбновлениеТаб3() Экспорт
    // Здесь выполняем заполнение Таб3
    // К этому моменту все "всплески" событий от заполнения Таб2 уже утихнут
КонецПроцедуры

Метод 5. Временное обнуление текущей строки

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

Рассмотрим последовательность действий:

  1. Устанавливаем Элементы.Таб2.ТекущаяСтрока = Неопределено.
  2. Заполняем данные таблицы.
  3. Если нужно, программно устанавливаем фокус на конкретную строку.

Этот способ помогает избежать «событийного шторма» в некоторых версиях платформы, работающих в режиме Такси.

Рекомендации по архитектуре

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

Использование комбинации Метода 1 (Флаг) и Метода 3 (Проверка идентификатора) является «золотым стандартом» разработки на управляемых формах 1С, обеспечивая максимальную производительность и отсутствие логических ошибок при заполнении связанных данных. При необходимости можно использовать готовую реализацию связывания главной и подчиненной таблиц на управляемых формах.

← На главную