I am writing a VBA code that will save a PDF file by automating screen of SAP software. I've reached the place where SAP asks me where I would like to save my PDF file (it opens a Windows explorer "save as" window). At this point, VBA code stops and I need to manually input the name of the file I want to save. Then, VBA continues to run...
I need help to find a way to automate this step.
A possible solution that I am thinking of (but I don't know how to actually do it) is to tell VBA to run a VB script that ends at "save as" window. Then I would send a application.sendkeys(" ")
to input the "save as" path.
Please advise if this is feasible. If it is, next step is I will have to dynamically modify specific lines of the VB script file (I need to loop through a list and change some values every time).
Thank you.
So, it has been quite a challenge....Here is my solution to Handle a "Save as" window. It can be way simpler if you would only want to click on "Save" Button. My solution is more complicated because I specify where the file needs to be saved. To do that you need to find the right combobox, which takes a lot of iteration.
WinAPI necessary declarations:
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
(ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" _
(ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Declare Function SendMessage Lib "user32" Alias _
"SendMessageW" (ByVal hWnd As Long, ByVal wMsg As Long, _
ByVal wParam As Long, lParam As Any) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public Declare Function SendNotifyMessage Lib "user32" Alias "SendMessageA" ( _
ByVal hWnd As Long, _
ByVal Msg As Integer, _
ByVal ByValByValwParam As Integer, _
ByVal lParam As String) As Integer
Actual VBA Code:
Sub SaveAsWindow()
Dim Winhwnd As Long
Dim prev As Long
Dim abc As Long
Dim strText As String
Dim rty As Variant
Dim Parent As Long
Dim child As Long
Winhwnd = FindWindow(vbNullString, "Save As")
For i = 1 To 20
strText = String$(100, Chr$(0))
abc = GetClassName(Winhwnd, strText, 100)
If Left$(strText, 12) = "DirectUIHWND" Then GoTo here1
Winhwnd = FindWindowEx(Winhwnd, 0&, vbNullString, vbNullString)
Next i
here1:
Parent = Winhwnd
child = FindWindowEx(Parent, 0&, vbNullString, vbNullString)
GoTo skip 'avoid this part for the 1st run
here2:
'fix child3 and child2
If child2 = 0 Then
rty = "0&"
Else
rty = 0
End If
If child3 = 555 Then
rty = "0&"
child3 = ""
End If
skip:
For i = 1 To 20
child = FindWindowEx(Parent, child, vbNullString, vbNullString)
For x = 1 To 20
If child3 = "" Then rty = 0
child2 = FindWindowEx(child, rty, vbNullString, vbNullString)
abc = GetClassName(child2, strText, 100)
If Left$(strText, 8) = "ComboBox" Then
child3 = FindWindowEx(child2, 0&, vbNullString, vbNullString)
If child3 = 0 Then
child3 = 555
GoTo here2
Else
GoTo here3
End If
End If
Next x
Next i
here3:
'this is te filepath. will be pasted into combobox. to adapt to your needs.
SendNotifyMessage child3, &HC, 0&, "C:\Users\username\abc.pdf"
'Get again the Save button
Winhwnd = FindWindow(vbNullString, "Save As")
buttn = FindWindowEx(Winhwnd, 0, "Button", "&Save")
'click on the save button
SendMessage buttn, &HF5&, 0, 0
End Sub
2nd VBA Code : For SAP, as it turns out to be simpler due to ComboboxEx32 being used instead of Combobox.
Sub test()
Dim Winhwnd As Long
Dim strText As String
Winhwnd = FindWindow(vbNullString, "Save As")
combo = FindWindowEx(Winhwnd, 0, vbNullString, vbNullString)
For i = 1 To 20
combo = FindWindowEx(Winhwnd, combo, vbNullString, vbNullString)
strText = String$(100, Chr$(0))
abc = GetClassName(combo, strText, 100)
If Left$(strText, 12) = "ComboBoxEx32" Then GoTo here
Next i
here:
SendNotifyMessage combo, &HC, 0&, "C:\Users\username\abc.pdf"
buttn = FindWindowEx(Winhwnd, 0, "Button", "&Open")
SendMessage buttn, &HF5&, 0, 0
End Sub
Bottom line, this is not the most perfect code, but I couldn't find anything else on the web. I hope this will benefit anyone with the same problem.