OGERWOLF
OGERWOLF

Reputation: 127

How to make VBA script automate a "Save As" window

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.

Upvotes: 4

Views: 4360

Answers (1)

OGERWOLF
OGERWOLF

Reputation: 127

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.

Upvotes: 3

Related Questions