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

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

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

Проанализируем ситуации по шагам и рассмотрим рабочие методы решения.

Установка фокуса на кнопку при открытии формы

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

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

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


Процедура ПриОткрытии()
    Активизировать("кнЗакрыть", 0);
КонецПроцедуры

В большинстве простых случаев этого будет достаточно: мы передаем имя элемента диалога (в данном случае кнЗакрыть) в качестве первого параметра. Второй параметр 0 (флаг перехода) указывает системе просто передать фокус на элемент.

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

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


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

Процедура ПриОткрытии(АвтоВызов = 1)
    Если АвтоВызов = 1 Тогда 
        // Запускаем таймер на 1 секунду
        Форма.ОбработкаОжидания("АктивироватьКнопкуЗакрыть", 1);
    КонецЕсли;
КонецПроцедуры

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

Отображение табличного документа компоненты Йоксель (Yoksel) на форме

Вторая проблема, которую мы разберем, связана с использованием внешней компоненты Йоксель. Это мощный инструмент для 1С 7.7 (SpreadSheet.dll), который позволяет работать с таблицами намного быстрее штатного объекта Таблица, полноценно поддерживает формат Excel (.xls) и дает возможность встраивать таблицы прямо внутрь диалоговых форм как ActiveX-объекты.

Часто разработчики сталкиваются со следующей проблемой: на форму добавляется элемент управления (ЭУ) Йокселя, пишется код формирования таблицы, но при нажатии на кнопку сформированный документ не отображается на форме, либо таблица появляется и тут же исчезает (зависает).

Проанализируем типичный ошибочный код формирования:


Процедура Сформировать()
    // ... создание и заполнение объекта тВремДокумент ...
    
    ВремДокумент = СоздатьОбъект("ТабличныйДокумент");
    // ОШИБКА ЗДЕСЬ: Локальная переменная ТабЭлемент
    ТабЭлемент = ВремДокумент.СоздатьЭлементУправления(Форма, "пЛокации");
    
    ВремДокумент.ЗагрузитьИзТаблицы(тВремДокумент);
    ВремДокумент.ФиксироватьКолонкиСлева = 1;
    ВремДокумент.ФиксироватьСтрокиСверху = 1;
    ВремДокумент.ОбновитьВсеОтображения();
КонецПроцедуры

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

Чтобы решить эту задачу, выполним следующие шаги:

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

Посмотрим на правильный и полностью рабочий вариант кода:


// В самом начале модуля формы объявляем переменную!
Перем ТабЭлемент;

Процедура Сформировать()
    Макет = глКаталогПечФорм + "MXL\СписокЛокаций.mxl";
    тВремДокумент = СоздатьОбъект("Таблица");
    тВремДокумент.ИсходнаяТаблица(Макет);
    
    // Создаем основной объект компоненты Йоксель
    ВремДокумент = СоздатьОбъект("ТабличныйДокумент");
    
    // Инициализируем визуальный элемент на форме.
    // Так как переменная глобальная, она не уничтожится после выхода из процедуры!
    ТабЭлемент = ВремДокумент.СоздатьЭлементУправления(Форма, "пЛокации");
    
    // ... здесь идет цикл заполнения исходной таблицы тВремДокумент ...
    
    // Загружаем данные в объект Йокселя
    ВремДокумент.ЗагрузитьИзТаблицы(тВремДокумент);
    
    // КРИТИЧЕСКИ ВАЖНЫЙ ШАГ: связываем данные и визуальный элемент!
    ТабЭлемент.Документ = ВремДокумент;
    
    // Настраиваем внешний вид
    ВремДокумент.ФиксироватьКолонкиСлева = 1;
    ВремДокумент.ФиксироватьСтрокиСверху = 1;
    
    // Перерисовываем таблицу на форме
    ВремДокумент.ОбновитьВсеОтображения();
КонецПроцедуры

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

← На главную