В практике разработки на платформе 1С:Предприятие 8.3 часто возникает специфическая задача: необходимо программно инициировать нажатие кнопки на управляемой форме. Сложность заключается в том, что в управляемом приложении обработчики событий элементов формы обычно являются закрытыми (неэкспортными) процедурами в модуле формы. Рассмотрим подробно, как решить эту задачу различными способами, от официальных механизмов тестирования до «хитрых» приемов эмуляции. Для быстрого исследования структуры интерфейса и поиска имен элементов в режиме пользователя можно использовать инструмент для редактирования свойств открытых форм.
Прежде чем мы разберем техническую реализацию, проанализируем ситуацию. Типичные сценарии, когда это требуется:
Рассмотрим основные подходы к решению этой проблемы.
Это наиболее правильный и современный подход, предусмотренный самой фирмой «1С». Платформа позволяет запускать сеансы в режиме тестирования. Разберем по шагам, как это работает. При необходимости проводить регулярное тестирование и обслуживание группы баз применяется программа для автоматического архивирования и тестирования Обновлятор 1С.
Для начала нам нужно запустить два сеанса 1С: Менеджер тестирования и Клиент тестирования. В коде менеджера тестирования мы можем получить доступ к любому элементу формы клиента и вызвать метод Нажать().
Посмотрим на пример кода, который выполняется в контексте менеджера тестирования:
// Инициализируем соединение с клиентом тестирования
Клиент = ТестируемоеПриложение.УстановитьСоединение();
// Находим нужное окно по заголовку
НужноеОкно = Клиент.НайтиОбъект(Тип("ТестируемоеОкно"), "ЗаголовокМоейФормы");
// Внутри окна находим кнопку по имени, заданному в конфигураторе
Кнопка = НужноеОкно.НайтиОбъект(Тип("ТестируемаяКнопкаФормы"), "ИмяКнопкиДействия");
// Выполняем программное нажатие
Кнопка.Нажать();
Проанализируем преимущества этого метода: платформа сама находит связанный с кнопкой обработчик (команду) и выполняет его в контексте формы клиента. Нам не нужно знать имя процедуры или менять её свойства. Однако этот метод требует специального режима запуска программы.
Рассмотрим ситуацию, когда мы работаем в обычном сеансе и не можем менять код формы (например, форма в закрытом модуле). В этом случае можно воспользоваться системными средствами Windows для эмуляции ввода с клавиатуры. Для этого предварительно в конфигураторе (или через расширение) кнопке назначается Сочетание клавиш.
Разберем пример реализации через COM-объект WScript.Shell:
// Создаем объект для работы с системными командами Windows
Shell = Новый COMОбъект("WScript.Shell");
// Активируем окно 1С (если нужно)
Shell.AppActivate("1С:Предприятие");
// Эмулируем нажатие сочетания клавиш, например, Ctrl+S
// "^" соответствует клавише Ctrl
Shell.SendKeys("^s");
Важный момент: этот способ считается «некрасивым» и нестабильным, так как требует, чтобы окно 1С было в фокусе в момент выполнения кода. Мы рекомендуем использовать его только в крайних случаях, например, при разработке инструментов для внутреннего использования.
Если наша цель — вызвать код кнопки, не снимая основную конфигурацию с поддержки, то лучшим решением будет использование расширений. Рассмотрим, как проанализировать структуру формы и перехватить управление.
&Вместо или &После, чтобы изменить поведение или просто вызвать оригинальный код.Экспортной, что позволит вызывать её из любого другого места программы.Пример кода в расширении для формы:
&НаКлиенте
&Вместо("ОбработкаНажатияКнопки")
Процедура Расш1_ОбработкаНажатияКнопки(Команда)
// Мы можем вызвать оригинальный код
ПродолжитьВызов(Команда);
// Или добавить свою логику
Сообщить("Кнопка была нажата программно или пользователем!");
КонецПроцедуры
Выясним причину, по которой прямое обращение к ЭтаФорма.Команды.ИмяКоманды не дает результата. В 1С объект КомандаФормы не имеет метода «Выполнить». Но мы можем пойти другим путем. Если кнопка связана с Общей командой или Командой объекта, мы можем вызвать её программно.
Для вызова общей команды используем метод:
ПараметрыВыполнения = Новый Структура("Источник", ЭтаФорма);
КомандыСистемы.ВыполнитьКоманду("ОбщаяКоманда.ИмяКоманды", ПараметрыВыполнения);
Интересный прием, который обсуждался коллегами: если на форме есть поле ввода, связанное с каким-либо реквизитом, можно программно изменить этот реквизит и вызвать событие ПриИзменении. Если в этом событии прописана логика, аналогичная нажатию кнопки, задача будет решена.
Рассмотрим реализацию через метод, предложенный автором tormozit:
ЭтаФорма.Элементы.ИмяПоля.ТекстРедактирования = "НовоеЗначение";Подводя итог нашему анализу, можно выделить следующие правила выбора метода:
Клиент тестирования или готовые фреймворки типа Vanessa Automation.WScript.Shell.Помните, что архитектурно правильным решением всегда является вынос логики из обработчика нажатия кнопки в отдельную экспортную процедуру или функцию. Это делает ваш код чистым, тестируемым и доступным для программного вызова без использования вышеописанных «ухищрений».