Search code examples
excelvbavbscriptsap-gui

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.


Solution

  • 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.