Внешняя компонента симуляции нажатий клавиатуры и мыши (в т.ч. сворачивание/разворачивание динамических списков)



Данная ВК позволяет использовать в ОС Windows начиная с 2000 функцию WinApi — SendInput().
А прилагающаяся обертка на 1С под нее позволяет делать это комфортно и просто.
Внешняя компонента была написана, прежде всего, для сворачивания/разворачивания группировок в динамических списках.

Краткая предистория:

В свое время очень мучал вопрос сворачивания/разворачивания динамических списков. Ситуацию обостряло тысяча подобных вопросов в гугле и не одного толкового ответа (по крайней мере я не видел).

Проблема тогда была решена здоровенным костылем: запуском скомпилированного скрипта AHK на сочетание Ctrl+Shift+Num-/Num+

Душа терзалась столь неизящным решением и вот наконец дошли руки сделать это чуть лучше и вдобавок слегка расширить функционал 1с.

 

Функционал:

Не буду долго тянуть, вк использует функцию Win Api — SendInput() для симуляции нажатий клавиш клавиатуры/мыши по виртуальным кодам.

Также в вк для удобства добавлена функция паузы и свойство определяющее продолжительность зажатия клавиши.

Для удобства в 1с создана обертка над вк, позволяющая использовать её весьма интуитивно, понятно и максимально просто.

Можно вызывать нажатие клавиши по её имени. Тестировал на Win Server 2012 R2 с Qwerty клавиатурой на 1с 8.3.10.2561. 

 

Примеры использования:

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

Клавиатура.Пауза()

Клавиатура.Свернуть()

Клавиатура.Развернуть()

Клавиатура.ВыполнитьНажатие()

 

 Спойлер

 

Листинг основного функционала общего модуля:

 

 Спойлер

 

Листинг вспомогательного функционала общего модуля:

 

 Спойлер

 

Послесловие:

Во вложении будет архив, в нем: тестовая конфигурация с примерами использования, утилитой для определения кодов клавиш, текстовый файл с ссылкой на вирустотал, xls документ с используемыми соответсвиями названиями и кодами клавиш, листинг общего модуля и собственно сама подключаемая библиотека. Надеюсь хоть комуто смог помочь, также прошу прощения за очепятки и абшибки. Повторюсь, компонента только для OS Windows начиная с 2000 , тоесть, по сути, должна работать только на любой современной Windows оси, в процессе использования она сама откидывает линь, мак, мобильное приложение и браузер, функции возвращают Ложь, вместо Истина. Возможно будет работать через Wine, такого Я не пробывал, не знаю.

ЕСЛИ У ВАС ВОЗНИКЛИ ВОПРОСЫ, С УДОВОЛЬСТВИЕМ ОТВЕЧУ В КОММЕНТАРИЯХ ИЛИ ЛС 

 

UPD 17.10.19

Как мне подсказал в комментариях Сергей Лесовой, для сворачивания/разворачивания дин. списка можно применить более изящное решение:

// Развернуть
Элементы.дСписок.Развернуть(ПредопределенноеЗначение("Справочник.СпрИмя.ПустаяСсылка"), Истина);
// Свернуть
Элементы.дСписок.Свернуть(ПредопределенноеЗначение("Справочник.СпрИмя.ПустаяСсылка"));

Правда такой подход не работает с иерархическим дин. списком, в то время как компонента отрабатывает нормально.

Компонента, Я полагаю, имеет право продолжать жить для других задач по автоматизации.

 

 

23 Comments

  1. eugeniezheludkov

    Я за альтернативу и разнообразие.

    Вот еще решение от 1С) (сценарное тестирование 2)


    WshShellW = Новый COMОбъект(«WScript.Shell»);

    WshShellW.AppActivate(ПолучитьЗаголовокСистемы());

    // Команда может состоять из одной буквы

    ПозицияОткрывающейСкобки = Найти(ПередаваемыеДанные.СочетаниеКлавиш, «{«);

    ПозицияЗакрывающейСкобки = Найти(ПередаваемыеДанные.СочетаниеКлавиш, «}»);

    Если ПозицияОткрывающейСкобки <> 0 Тогда

    Если ПозицияЗакрывающейСкобки — ПозицияОткрывающейСкобки — 1 = 1 Тогда

    Буква = Сред(ПередаваемыеДанные.СочетаниеКлавиш, ПозицияОткрывающейСкобки + 1, 1);

    Буква = ИСТП_ПреобразоватьБуквуВСоответствииСРаскладкой(Буква);

    Команда = Сред(ПередаваемыеДанные.СочетаниеКлавиш, 1,ПозицияОткрывающейСкобки) + Буква + Сред(ПередаваемыеДанные.СочетаниеКлавиш, ПозицияЗакрывающейСкобки);

    Иначе

    Команда =ПередаваемыеДанные.СочетаниеКлавиш;

    КонецЕсли;

    Иначе

    // скобок может и не быть

    Команда = ПередаваемыеДанные.СочетаниеКлавиш;

    ЕстьКТРЛ = Ложь;

    ЕстьАЛЬТ = Ложь;

    ЕстьШИФТ = Ложь;

    Если Найти(Команда, «#k8SjZc9Dxk») > 0 Тогда

    Команда = СтрЗаменить(Команда, «#k8SjZc9Dxk», «»);

    ЕстьКТРЛ = Истина;

    КонецЕсли;

    Если Найти(Команда, «%») > 0 Тогда

    Команда = СтрЗаменить(Команда, «%», «»);

    ЕстьАЛЬТ = Истина;

    КонецЕсли;

    Если Найти(Команда, «+») > 0 Тогда

    Команда = СтрЗаменить(Команда, «+», «»);

    ЕстьШИФТ = Истина;

    КонецЕсли;

    Если СтрДлина(Команда) = 1 Тогда

    Команда = ИСТП_ПреобразоватьБуквуВСоответствииСРаскладкой(Команда);

    Если ЕстьШИФТ Тогда

    Команда = «+» + Команда;

    КонецЕсли;

    Если ЕстьАЛЬТ Тогда

    Команда = «%» + Команда;

    КонецЕсли;

    Если ЕстьКТРЛ Тогда

    Команда = «#k8SjZc9Dxk» + Команда;

    КонецЕсли;

    Иначе

    Команда = ПередаваемыеДанные.СочетаниеКлавиш;

    КонецЕсли;

    КонецЕсли;

    WshShellW.SendKeys(Команда);

    Показать

    Reply
  2. 🅵🅾️🆇

    (1) Как Num-/Num+ передать?)

    Reply
  3. bulpi

    (1)

    WshShellW.SendKeys(Команда);

    работает не на всех системах, увы.

    Reply
  4. 🅵🅾️🆇

    (3) https://ru.wikipedia.org/wiki/Windows_Script_Host

    Естественно. Его Я тоже пробывал, но писечка в том, что оно не подошло, тк не скумекал как им симулировать нажатия Num- и Num+, а значит и не смог свернуть динамический список.

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

    Вообще у меня к 1с есть несколько основных притензий:

    1) У динамических списков нет родной кнопки и метода для свернуть/развернуть группировки, хотя это можно делать сочетанием клавиш.

    2) На управляемых формах можно строить неплохой адаптивный интерфейс, но нельзя нормально в процентном отношении задавать размер элементов.

    3) Модуль объекта не существует на клиенте (уж хотяб для обработок можно былоб сделать).

    4) У объектов нельзя создавать собственный конструктор и деструктор.

    Приходиться делать так а = Обработка.Создать(); а.Конструктор(параметры);

    5) Очень хотелось бы увидеть инкремент и декримент хотяб.

    А то Счетчик = Счетчик + 1; — не комильфо писать :3

    Это очень странно, тк С++ вполне позволяет использовать перегрузки.

    6) Из общего модуля клиента нельзя нормально вызывать модуль сервера.

    Прошу прощения, за то, что излил свою попаболь)))

    Reply
  5. Synoecium

    Что-то не понял насчет сворачивания/разворачивания, чем вариант вызвать такой код не подошел:

    Элементы.Список.Развернуть(Элементы.Список.ТекущаяСтрока,Истина);

    Элементы.Список.Свернуть(Элементы.Список.ТекущаяСтрока);

    Reply
  6. 🅵🅾️🆇

    (5)

    Я может чего и упускаю, но это работает только для обычных таблиц, но никак не для динамических списков.

    Если ошибаюсь или чегот добавили — был бы благодарен за предоставленный пример. Я не представляю, как можно получить «Идентификатор строки таблицы.» у динамического списка. У него же нельзя перебирать содержимое, а значит не выйдет перебрать все и все свернуть. Самый максимум, что позволяет — по клику сворачивать текущую группировку.

    Опять же, поправьте если не прав и ошибаюсь.

    Reply
  7. nytlenc

    Ставлю плюс за идею!

    Reply
  8. Synoecium

    (6) ну вот те строки кода, которые написал в (5), это доработка для конфигурации ITIL, там список задач сделан через динамический список с запросом, и этот код позволяет сворачивать/разворачивать подчиненные задачи. Возможно не сработает если в динамическом списке не указана основная таблица, особо не ковырялся в этом направлении.

    Reply
  9. 🅵🅾️🆇

    (8) Тоесть, чтоб свернуть такой список

    — Задачи

    — Помыть посуду

    — Подстричь газон

    — Заправить постель

    — Постирать носки

    Вам надо: (a) тыкнуть на «Задачи», а затем (б) нажать кнопку которая вызовет ваш код (ну или разместить код в «ПриАктивизацииСтроки/Поля/Ячейки») и это свернет только данную группировку. Это не есть очень удобно, к томуже у вас может быть не 1 родительская группировка, а несколько.

    Попробуйте погуглить по «свернуть динамический список 1с», увидите насколько остро стоит проблема у многих людей.

    Reply
  10. Synoecium

    (9) Ну если нужно свернуть все задачи, то достаточно передать пустую ссылку в метод Свернуть(), даже активизировать ничего не нужно. В принципе можно даже сворачивать на любое количество уровней вверх, при условии что у вас в динамическом списке основной назначена таблица с иерархией. Набросал пример для 1С:Документооборот ну или любой конфигурации, где есть справочник ПапкиФайлов, в нем продемонстрировано то, о чем писал.

    Reply
  11. 🅵🅾️🆇

    (10)

    Сейчас детально посмотрю, в коде не обязательно ломиться на сервер:

    Элементы.ДинСписок.Развернуть(ПолучитьПустуСсылкуНаСервере(),Истина);

    Должно быть достаточно:

    Элементы.ДинСписок.Развернуть(ПредопределенноеЗначение(«Справочник.ПапкиФайлов.ПустаяСсылка»),Истина);

    Reply
  12. Synoecium

    (12) ну я не парился с качеством, просто показал принцип 🙂

    а так да, лучше лишний раз на сервер не нырять

    Reply
  13. eugeniezheludkov

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

    (4) эх тоже хотелось бы всех этих ООП штучек в 1С, но тогда будет риск превращения 1С в Microsoft Dynamics AX. по слухам бизнес, что успел подсесть на аксапта избавляется от нее и переводят учет на 1С по причинам: 1. В Аксапте разработка фич ведется дольше чем в 1С. 2. Дорогостоящие и труднонаходимые специалисты по сравнению с адынесниками

    Reply
  14. lunjio

    Компонента по какой технологии написано, ответьте пожалуйста.

    Reply
  15. 🅵🅾️🆇

    (15) Это внешняя компонента, написана на плюсах, за основу брал пример от 1с.

    Использует Win Api.

    Примеры использования в публикации, вроде, были.

    Если вам очень хочется попробывать, но нет/жаль стартмани — пишите в ЛС, отдам за спасибо, Я не жадина)

    Тоже касается и сорцев, если у Вас есть человек, который сечет во внешних компонентах и С++, там нет ничего сверхестественного.

    Моя телега, на всякий: @FoxWithBox

    Reply
  16. lunjio

    Спасибо за ответ, изначально не увидел в текстах кода с инициализацией, потом нашел и вопрос отпал, она по технологии Native ) В компонентах сам секу, на C# могу писать, на C++ для меня трудно, времени нету изучить его, шаблон даже есть где-то внешней на C#, только вот по технологии com помоему, а мне Native нужна. ) Спасибо за отзывчивость.

    Reply
  17. unknown181538

    Что-то не работают оба варианта… у меня динамический список документов… вставляю разворот в процедуру ПриОткрытии() а открывается все равно свернуто…

    Reply
  18. 🅵🅾️🆇

    (18) Попробуй через обработчик ожидания.

    «При открытии» подключи.

    Но перед глазами сейчас 1с’ки нет.

    Reply
  19. unknown181538

    (19) Да, получилось в итоге с помощью ВК и обработчика ожидания.

    Reply
  20. 🅵🅾️🆇

    (20) Рад, что мои набитые шишки кому то помогают :3

    Reply
  21. andryandry

    Я разворачиваю все группы Динамического списка так

    Для каждого стр из Элементы.ДинСписок.ВыделенныеСтроки цикл

    Элементы.ДинСписок.Развернуть(стр, истина);

    Конеццикла;

    Reply
  22. 🅵🅾️🆇

    (22)

    Спасибо, собственно проблема была в том, чтоб развернуть и свернуть корень, а не выделенные строки.

    Это решается таким способом:

    // Развернуть
    Элементы.дСписок.Развернуть(ПредопределенноеЗначение(«Справочник.СпрИмя.ПустаяСсылка»), Истина);
    
    // Свернуть
    Элементы.дСписок.Свернуть(ПредопределенноеЗначение(«Справочник.СпрИмя.ПустаяСсылка»));

    Собственно я тогда был мал, глуп и неопытен :3

    Reply
  23. andryandry

    (23) ну ВК написать — не так мал ))

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *