Как обработать событие выхода из поля ввода в 1С 7.7: стандартные методы и лайфхаки

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

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

Рассмотрим подробно задачу: как отловить момент, когда пользователь закончил ввод данных в поле (нажал Enter, Tab или кликнул мышкой в другое место), чтобы проверить введенное значение. Разберем как штатные способы, так и продвинутые методы с использованием внешних компонент.

Постановка задачи

В современных версиях 1С (8.2, 8.3) у поля ввода есть событие ПриИзменении, которое срабатывает после окончания редактирования, и событие ПриОкончанииВводаТекста. В версии 7.7 все устроено иначе. Нам необходимо реализовать валидацию данных сразу после того, как курсор покидает поле, не дожидаясь нажатия кнопки «ОК» или записи документа.

Способ 1. Использование вкладки «Формула» (Штатный метод)

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

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

Если пользователь зашел в поле, ничего не менял и вышел — формула не сработает. Если изменил и нажал Enter или Tab — формула сработает.

Алгоритм действий:

  1. Открываем форму в Конфигураторе.
  2. Выделяем нужное поле ввода.
  3. В палитре свойств находим поле Формула.
  4. Пишем туда имя процедуры или функции, которую нужно вызвать, например: ПроверитьАртикул().

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

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


Процедура ПроверитьАртикул()
    // Получаем текущее значение реквизита, связанного с полем
    ТекАртикул = Артикул; 
    
    // Простейшая проверка: артикул не должен быть короче 3 символов
    Если СтрДлина(СокрЛП(ТекАртикул)) < 3 Тогда
        Предупреждение("Артикул слишком короткий! Введите минимум 3 символа.");
        
        // Эта команда отменяет событие выхода из поля.
        // Фокус вернется обратно в поле ввода.
        СтатусВозврата(0); 
    КонецЕсли;
    
    // Также здесь можно выполнить поиск в базе данных
    СпрТовары = СоздатьОбъект("Справочник.Номенклатура");
    Если СпрТовары.НайтиПоРеквизиту("Артикул", ТекАртикул, 1) = 1 Тогда
        Предупреждение("Товар с таким артикулом уже существует: " + СпрТовары.Наименование);
        // Не обязательно запрещать выход, можно просто предупредить
    КонецЕсли;
КонецПроцедуры

Преимущества метода:

Недостатки:

  • Не срабатывает, если значение не менялось (например, мы хотим что-то проверить просто при проходе через поле табом).
  • Способ 2. Эмуляция события «ПриАктивизации» через Обработку Ожидания

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

    Суть метода заключается в том, что мы запоминаем имя текущего активного элемента и постоянно сравниваем его с новым значением. Как только они начинают различаться — значит, фокус перешел на другой элемент.

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

    1. В модуле формы объявим переменную для хранения имени предыдущего активного элемента.
    2. В процедуре ПриОткрытии запустим ОбработкаОжидания.
    3. Напишем процедуру мониторинга.

    Рассмотрим код решения:

    
    Перем ПредЭлемент; // Глобальная переменная модуля формы
    
    Процедура ПриСменеАктивногоЭлемента(ИмяСтарого, ИмяНового)
        // Здесь пишем логику обработки события
        
        // Например, если мы ушли из поля "Контрагент"
        Если ИмяСтарого = "Контрагент" Тогда
            // Выполняем действия при потере фокуса полем Контрагент
            Сообщить("Вы покинули поле выбора контрагента");
        КонецЕсли;
        
        // Например, если мы пришли в поле "Сумма"
        Если ИмяНового = "Сумма" Тогда
             Сообщить("Вы активировали поле Сумма");
        КонецЕсли;
    КонецПроцедуры
    
    Процедура МенеджерФокуса()
        // Получаем имя текущего элемента формы, на котором стоит курсор
        ТекЭлемент = Форма.АктивныйЭлемент();
        
        // Если элемент изменился по сравнению с прошлым замером
        Если ТекЭлемент <> ПредЭлемент Тогда
            ПриСменеАктивногоЭлемента(ПредЭлемент, ТекЭлемент);
            ПредЭлемент = ТекЭлемент; // Запоминаем новое состояние
        КонецЕсли;
    КонецПроцедуры
    
    Процедура ПриОткрытии()
        ПредЭлемент = Форма.АктивныйЭлемент();
        // Запускаем проверку каждые 0.1 - 0.2 секунды
        ОбработкаОжидания("МенеджерФокуса", 1); 
    КонецПроцедуры
    

    Важные нюансы:

    Способ 3. Продвинутый уровень: Внешние компоненты (FormEx / 1C++)

    Для профессиональной разработки на 1С 7.7 стандартом де-факто стало использование библиотеки FormEx. Она позволяет перехватывать системные события Windows и сообщения форме.

    С помощью FormEx можно реализовать полноценные события, аналогичные современным OnExit (ПриВыходе) или OnFocus (ПриПолученииФокуса).

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

    Рассмотрим концептуальный пример с использованием FormEx (требует наличия FormEx.dll в папке базы или bin):

    
    Перем Сервис;
    
    Процедура ПриОткрытии()
        Если ЗагрузитьВнешнююКомпоненту("FormEx.dll") = 0 Тогда
            Сообщить("Не удалось загрузить FormEx!", "!");
            Возврат;
        КонецЕсли;
        
        Сервис = СоздатьОбъект("Сервис");
        // Включаем расширенную обработку событий формы
        Сервис.Включить("Events"); 
    КонецПроцедуры
    
    // Предопределенная процедура FormEx, перехватывающая нажатия клавиш
    Процедура ПриНажатииКнопкиКлавиатуры(КодКлавиши, Альт, Шифт, Контрл, Символ, ФлагОстановить)
        
        // Коды клавиш: 13 - Enter, 9 - Tab
        Если (КодКлавиши = 13) ИЛИ (КодКлавиши = 9) Тогда
            ТекЭлемент = Форма.АктивныйЭлемент();
            
            Если ТекЭлемент = "МоеПолеВвода" Тогда
                // Здесь выполняем проверку ПЕРЕД выходом
                Если Не ПроверитьЗначение() Тогда
                    Предупреждение("Значение некорректно!");
                    ФлагОстановить = 1; // Запрещаем выход (отменяем нажатие клавиши)
                КонецЕсли;
            КонецЕсли;
        КонецЕсли;
        
    КонецПроцедуры
    

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

    Способ 4. «Живой поиск» и ActiveX

    В теме также обсуждалась задача проверки введенного значения непосредственно в процессе ввода (при нажатии каждой буквы), например, для реализации «живого поиска» в справочнике или подбора номенклатуры.

    Стандартные поля 1С 7.7 не умеют генерировать событие при вводе каждого символа. Решение заключается в подмене стандартного поля ввода на ActiveX компонент (обычно из библиотеки Microsoft Forms 2.0 — FM20.DLL, которая входит в состав MS Office).

    Рассмотрим логику реализации:

    1. На форму помещается элемент ActiveX (вместо обычного поля).
    2. Выбирается класс Microsoft Forms 2.0 TextBox.
    3. В модуле формы прописывается обработчик событий этого ActiveX объекта.

    У объекта TextBox из этой библиотеки есть событие Change (Изменение), которое срабатывает при каждом нажатии клавиши, и событие Exit (Выход).

    
    // Примерный обработчик события Change для ActiveX поля
    Процедура ActiveXПоле_Change()
        ТекстПоиска = ActiveXПоле.Text; // Получаем текущий текст
        
        // Выполняем поиск по подстроке прямо во время ввода
        Если СтрДлина(ТекстПоиска) > 2 Тогда
            ОбновитьСписокНайденного(ТекстПоиска);
        КонецЕсли;
    КонецПроцедуры
    

    Риски использования ActiveX:

    Заключение

    Подведем итог. Для большинства задач проверки введенных данных в 1С 7.7 достаточно использовать стандартный механизм: вкладка «Формула» в свойствах элемента + функция в модуле формы с использованием СтатусВозврата(0). Это работает стабильно и не требует внешних библиотек.

    Если же задача стоит шире — например, отслеживать перемещение фокуса без изменения данных или реагировать на ввод каждого символа — необходимо использовать внешние компоненты (FormEx, 1C++) или ActiveX элементы, принимая во внимание усложнение поддержки такой конфигурации.

    ← На главную