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

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

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

Метод 1: Использование «активного» текстового элемента на форме

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

Рассмотрим алгоритм реализации по шагам:

  1. Создадим на форме справочника новый элемент диалога типа Текст.
  2. Разместим его в невидимой области или сделаем очень маленьким (хотя для отладки лучше оставить его видимым).
  3. В свойствах этого элемента на закладке Дополнительно в поле Формула впишем имя функции, например: МониторингАктивногоЭлемента().

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


Перем ПредАктивныйЭлемент;

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

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

Метод 2: Расширение возможностей через компоненту FormEx

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

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


Процедура ПриВходеВЭлемент(ИмяЭлемента)
    // Это предопределенное событие FormEx
    Если ИмяЭлемента = "НужныйРеквизит" Тогда
        Сообщить("Пользователь вошел в поле: " + ИмяЭлемента);
        // Здесь можно программно изменить значение или подготовить поле
    КонецЕсли;
КонецПроцедуры

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

Метод 3: Использование штатной процедуры ПриНачалеВыбораЗначения

Посмотрим на ситуацию, когда наш реквизит не является простой строкой или числом. Если тип реквизита — Справочник, Перечисление или СписокЗначений, мы можем использовать встроенную процедуру ПриНачалеВыбораЗначения.

Рассмотрим пример, когда нам нужно отловить активацию поля выбора категории:


Процедура ПриНачалеВыбораЗначения(ИдентЭлемДиалога, ФлагСтандОбр)
    Если ИдентЭлемДиалога = "КатегорияОбъекта" Тогда
        // Мы можем отменить стандартный выбор и предложить свою логику
        // Или просто зафиксировать факт нажатия на кнопку выбора/входа
        Сообщить("Начат выбор в поле: " + ИдентЭлемДиалога);
    КонецЕсли;
КонецПроцедуры

Для простых текстовых полей этот метод можно применить, если в свойствах элемента диалога установить галочку «Кнопка выбора». Тогда нажатие на эту кнопку (или нажатие клавиши F4 в поле) вызовет данную процедуру.

Метод 4: Сабклассинг и перехват Windows-сообщений (1C++)

Для самых сложных задач, когда нужно отследить фокус на уровне операционной системы, программисты используют компоненту 1C++. Она позволяет реализовать перехват сообщений Windows (subclassing). Каждое поле ввода в 1С 7.7 — это стандартное окно класса Edit. Когда оно получает фокус, операционная система посылает ему сообщение WM_SETFOCUS.

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

Проблема «выделения всего текста» при входе

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

Как решить эту проблему? Рассмотрим варианты:

  1. Использование FormEx: С помощью метода Сервис.SendKeys("{END}") можно программно «нажать» клавишу End сразу после того, как фокус попал в поле. Это снимет выделение и поставит каретку в конец строки.
  2. Использование внешних ActiveX: Замена стандартного текстового поля на объект Microsoft Forms 2.0 TextBox. У таких объектов есть свойства SelStart и SelLength, которыми можно управлять из кода 1С, четко позиционируя курсор.
  3. Визуальные трюки: Сделать поле недоступным для прямого редактирования, а рядом разместить кнопку. При нажатии на кнопку вызывать ВвестиСтроку(), где в качестве начального значения уже будет подставлен нужный префикс.

Выясним, какой метод выбрать. Если вы ограничены только типовыми возможностями — используйте Метод 1 с проверкой АктивныйЭлемент(). Если же у вас есть возможность использовать внешние библиотеки — FormEx является абсолютным фаворитом, так как делает код чистым, понятным и избавляет от «костылей» с постоянным пересчетом формул на форме.

← На главную