Как программно активизировать строку в табличной части документа 1С 7.7 без ложного закрытия формы?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

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

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

Часто программисты пытаются обойти это через "псевдо-закрытие" формы в процедуре ПриЗакрытии(). Но этот костыль имеет критический недостаток — платформа видит флаг модифицированности и выдает пользователю системный вопрос: "Сохранить документ? Да, нет, отмена". Если записывать документ принудительно для сброса флага, это может нарушить логику работы пользователя.

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

Способ 1: Трюк с открытием фиктивной обработки (Модальный перехват)

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

Сделаем это по шагам:

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

// Передаем контекст текущего документа в обработку
ОткрытьФормуМодально("Обработка.АктиваторСтроки", Контекст);
  1. Теперь перейдем в модуль формы самой созданной обработки АктиваторСтроки. В предопределенной процедуре ПриОткрытии() пропишем следующий код:

Процедура ПриОткрытии()
    // Активизируем строку через переданный контекст документа
    // (предполагается, что нужный номер строки мы вычислили заранее или передали)
    Форма.Параметр.АктивизироватьСтроку(НужныйНомерСтроки);
    
    // Мгновенно отменяем открытие формы обработки
    СтатусВозврата(0);
    Возврат;
КонецПроцедуры

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

Способ 2: Отложенная активация через дополнительный таймер

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

Посмотрим на решение с использованием цепочки таймеров:

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

// Конец процедуры загрузки данных
ОбработкаОжидания("УстановкаФокуса", 1);
  1. Создаем процедуру УстановкаФокуса(), которая выполнит действие уже после того, как форма обновилась:

Процедура УстановкаФокуса()
    // Отключаем таймер, передав пустую строку
    ОбработкаОжидания("", 0);
    
    // Теперь безопасно активизируем строку
    АктивизироватьСтроку(НужныйНомерСтроки);
КонецПроцедуры

Этот метод гарантирует, что команда активации сработает в уже перерисованном интерфейсе.

Способ 3: Эмуляция нажатия клавиш (через WScript.Shell)

Если программные методы 1С подводят, мы можем воздействовать на форму на уровне операционной системы Windows. Суть метода — программно "нажать" клавишу стрелки "Вниз" нужное количество раз.

Разберем пример реализации через системный COM-объект:


// Вычисляем, сколько раз нужно нажать "Вниз"
Смещение = НужныйНомерСтроки - 1; // Так как мы находимся на первой строке

Если Смещение > 0 Тогда
    WshShell = СоздатьОбъект("WScript.Shell");
    
    Для Индекс = 1 По Смещение Цикл
        WshShell.SendKeys("{DOWN}");
    КонецЦикла;
КонецЕсли;

Осторожно: Данный метод работает безотказно и не затрагивает флаг модифицированности, однако у него есть недостаток. Если в момент эмуляции пользователь переключится на другое окно (например, откроет браузер), нажатия клавиш {DOWN} уйдут в это стороннее активное окно.

Способ 4: Надежная эмуляция клавиатуры через FormEx

Чтобы избежать проблемы с перехватом фокуса другими приложениями из предыдущего способа, рассмотрим использование популярной внешней компоненты FormEx.

Сама компонента не имеет отдельного магического метода для жесткой активации строки, игнорирующего платформу, но у нее есть отличный объект Сервис с методом ЭмулироватьКлавиатуру().


Сервис = СоздатьОбъект("Сервис");
// Эмуляция нажатия стрелки вниз
// В отличие от WScript.Shell, FormEx посылает команды напрямую в окно 1С
Сервис.ЭмулироватьКлавиатуру(40); // 40 - код клавиши VK_DOWN

Эмуляция через FormEx отрабатывает строго в контексте приложения 1С. Даже если окно программы свернуто или перекрыто другими окнами, сдвиг курсора произойдет корректно именно в нашей табличной части.

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

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

← На главную