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