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



Данная ВК позволяет использовать в ОС 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 не будет опубликован. Обязательные поля помечены *