Страницы: 1
RSS
Как с помощью VBA нажать кнопку подтверждения в системном окне Win32.API
 
Вчера столкнулся со следующим.
Есть макрос, берет из списка в Эксель номер, вызывает SAP и выполняет некоторые операции, записанные саповским скрипт рекордером.
И на одной из операций выкачивается файл PDF, но вылезает системное окно подтверждения с кнопками "Open", "Save", "Cancel". Нужно программно выбрать "Save", и перейти к следующей итерации. Варианта обойти или перенастроить SAP, как понимаете, нет.  
Поиском найден вариант https://www.cyberforum.ru/visual-basic/thread802877.html,, он единственный на весь тырнет, я его утажил практически без изменений, лишь адаптировав под х64 и поменяв лишь параметр Command2 на Save
Цитата
Код
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
    (ByVal hWndParent As Long, ByVal hWndChildAfter As Long, _
     ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function GetForegroundWindow Lib "user32" () As Long
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Const BM_CLICK = &HF5
' Кликаем по первой кнопке, она нажимает вторую кнопку программно.
Private Sub Command1_Click()
Ret = GetForegroundWindow()
hwndButt = FindWindowEx(Ret, ByVal 0&, vbNullString, "Command2") 'вместо Command2 написать реальный текст на кнопке!
PostMessage hwndButt, BM_CLICK, 0, 0
End Sub
Но  он не работает - в том смысле, что ошибок не выдает, но и нажимать ничего не нажимает.
Мне не очень понятен код, где и как он выбирает нужную кнопку.  Если  кто-нибудь мне разъяснит, что делать, в чем ошибка, буду очень благодарен коньяком.
Нужно автоматически собирать эти чертовы PDFы...,


Обновление от 24.05
Короче, нашел я, как это сделать - там целый комплекс
1. GetForegroundWindow() выдавал отнюдь не окно с текстом "File Download". hWnd какого окна выдавал - выяснять не стал.
2. Окно загрузки "File Download" искал функцией API GetWindow перебором всех окон, через функцияю GetWindowText
3. Но опять случилась засада - таких окон вываливалось аж 2. На одном из них была только одна кнопка "Cancel", а на другом находилась кнопка Save. Причем находилось то, на котором нужной кнопки не было. После долгих размышлений выбор из них осуществлять решил поиском внутри найденного окна через FindWindowEx пресловутой кнопки "Save", которая называлась.... "&Save" (мать-мать-мать Билла Гейтса)
4. Нажать кнопку Save через  PostMessage hwndButt, BM_CLICK, 0, 0 не удалось. Удалось только сделать кнопку активной. Послал туда после активации кнопки    keybd_event VK_ENTER, 0, 0, 0 Наконец-то у меня менюшка провалилась в другое меню с выбором пути сохранения.

5. Встал другой вопрос теперь - не могу найти на окне hWnd комбо-бокса, куда мне надо вставить путь. Окно нашел, кнопку "Save" нашел, а как обратиться к сомбобоксу, куда вставить имя файла? HELP!!!

Люди, ну не верю, что никто не работал с Win32.API.....

Обновление на 25.05
Так как никто не ответил, справился сам. Интернет знает все, надо только поглубже нырнуть в эту кроличью нору.
Значит, так.
Код
 a = FindWindowEx(0, ByVal &O0, vbNullString, "Save As")  ' ищу окно "Save As"    
Код
 s1 = FindWindowEx(a, ByVal &O0, vbNullString, "&Save")
subWindow = FindWindowEx(a, ByVal 0&, "DUIViewWndClassName", vbNullString)' в этом окне ищу hwnd окна класса "DUIViewWndClassName"
subWindow = FindWindowEx(subWindow, ByVal 0&, "DirectUIHWND", vbNullString)'затем в найденном окне элемент класса "DirectUIHWND"
subWindow = FindWindowEx(subWindow, ByVal 0&, "FloatNotifySink", vbNullString)'затем в найденном окне элемент класса "FloatNotifySink"
subWindow = FindWindowEx(subWindow, ByVal 0&, "ComboBox", vbNullString)'и только после этого в найденном окне элемент класса "ComboBox" 
'- эта кроличья нора невероятно глубока, и нигде нахрена не описана. Исполать тебе, чувак на stackoverflow, 3 года назад ответивший на запрос 5-летней давности  
'https://translated.turbopages.org/proxy_u/en-ru.ru.44b1acf2-628dc03e-2a272283-74722d776562/https/sta...

subWindow = FindWindowEx(subWindow, ByVal 0&, "Edit", vbNullString)'дальше все просто, находим объект combobox edit

FullPath = "C:\Users\etc\" & fName 'нужное имя
SendMessage subWindow, WM_SETTEXT, False, ByVal FullPath' посылаем туда путь
 a = FindWindowEx(0, ByVal &O0, vbNullString, "Save As")'снова находим окно и кнопку "Save" (иначе почему-то не нажимается кнопка, видимо, не активно оказывается окно)
 s1 = FindWindowEx(a, ByVal &O0, vbNullString, "&Save")
PostMessage s1, BM_CLICK, 0, 0'выбирает кнопку
PostMessage s1, BM_CLICK, 0, 0
  keybd_event VK_ENTER, 0, 0, 0'жмет Enter

Таким образом, 3 дня мучений, и мне удалось через Win32.API  из макроса прогруммно нажать внешние кнопки подтверждения скачивания файла, задать ему путь сохранения и имя.  Заявленную бутылку коньяка, к сожалению, сегодня не выиграл никто.

Изменено: kohet - 25.05.2022 10:18:22 (все вопросы решены самостоятельно, просто делюсь опытом, чтобы другие не задавали те же вопросы)
Страницы: 1
Наверх