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