0

I need to use Application.Wait Now + [some time value] between commands. But sometimes it doesn't work, when SAP working too slow. How to do it? I need some Loop with Application.Wait when each dialog windows showing up.

This is my VBA code:

Sub logowanie()
    
    UserForm1.Show
    
    vSAP = Shell("C:\Program Files (x86)\SAP\FrontEnd\SAPgui\saplogon.exe", vbNormalFocus)
    Call Shell("C:\Program Files (x86)\SAP\FrontEnd\SAPgui\saplogon.exe", vbNormalFocus)
    Set WSHShell = CreateObject("WScript.Shell")
    
    Do Until WSHShell.AppActivate("SAP Logon")
    Application.Wait Now + TimeValue("0:00:01")
    Loop
    Set SapGui = GetObject("SAPGUI")
    Set Appl = SapGui.GetScriptingEngine
    
    Application.Wait Now + TimeValue("0:00:01")
    Set connection = Appl.Openconnection("xxxxxxxxxx", True)
    
    Application.Wait Now + TimeValue("0:00:02")
    WSHShell.SendKeys UserForm1.TextBox1.Value
    WSHShell.SendKeys "{TAB}"
    WSHShell.SendKeys UserForm1.TextBox2.Value
    WSHShell.SendKeys "{ENTER}"
    Application.Wait Now + TimeValue("0:00:01")
    WSHShell.SendKeys "y_ecd_96000032"
    WSHShell.SendKeys "{ENTER}"
    Application.Wait Now + TimeValue("0:00:01")
    WSHShell.SendKeys "{DOWN}"
    WSHShell.SendKeys "{DOWN}"
    WSHShell.SendKeys "{DOWN}"
    WSHShell.SendKeys "{TAB}"
    WSHShell.SendKeys "22:00:00"
    WSHShell.SendKeys "{TAB}"
    WSHShell.SendKeys "*"
    WSHShell.SendKeys "{ENTER}"
    Application.Wait Now + TimeValue("0:00:02")
    WSHShell.SendKeys "DC15"
    Application.Wait Now + TimeValue("0:00:02")
    WSHShell.SendKeys "{ENTER}"
    Application.Wait Now + TimeValue("0:00:02")
    WSHShell.SendKeys "{DOWN}"
    WSHShell.SendKeys "{TAB}"
    WSHShell.SendKeys "{TAB}"
    WSHShell.SendKeys "{ENTER}"
    Application.Wait Now + TimeValue("0:00:02")
    WSHShell.SendKeys "^{TAB}"
    WSHShell.SendKeys "{TAB}"
    WSHShell.SendKeys "{TAB}"
    WSHShell.SendKeys "{TAB}"
    WSHShell.SendKeys "{TAB}"
    WSHShell.SendKeys "{TAB}"
    WSHShell.SendKeys "{TAB}"
    WSHShell.SendKeys "{TAB}"
    WSHShell.SendKeys "{TAB}"
    WSHShell.SendKeys "{ENTER}"
    Application.Wait Now + TimeValue("0:00:02")
    WSHShell.SendKeys "U:\[...]\a.txt"
    WSHShell.SendKeys "{ENTER}"
    Application.Wait Now + TimeValue("0:00:03")
    WSHShell.SendKeys "{F8}"
    Application.Wait Now + TimeValue("0:00:03")
    WSHShell.SendKeys "{F8}"
    Application.Wait Now + TimeValue("0:00:03")
    WSHShell.SendKeys "+{F4}"
    Application.Wait Now + TimeValue("0:00:02")
    WSHShell.SendKeys "U:\[...]\SRET.xlsx"
    WSHShell.SendKeys "{ENTER}"
    'Application.Wait Now + TimeValue("0:00:03")
    WSHShell.SendKeys "{LEFT}"
    WSHShell.SendKeys "{ENTER}"
    Application.Wait Now + TimeValue("0:00:04")
    AppActivate (vSAP)
    Application.Wait Now + TimeValue("0:00:02")
    WSHShell.SendKeys "%{F4}"
    Application.Wait Now + TimeValue("0:00:02")
    WSHShell.SendKeys "{TAB}"
    WSHShell.SendKeys "{ENTER}"
    
End Sub
Sandra Rossi
  • 11,934
  • 5
  • 22
  • 48
Karol
  • 91
  • 11
  • Note that SAP GUI proposes a SAP GUI Scripting library to automate screens, the execution is synchronous, it waits for the screen to show up before executing the next action. – Sandra Rossi Jun 21 '23 at 15:49

2 Answers2

0

I think the easiest way is to use WinAPI to test the name of the current window. Try this:

Public Declare Function GetForegroundWindow Lib "user32" () As Long
Public Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal HWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long

Sub Test()
    WaitForWindow "Notepad"
    Debug.Print "Notepad is opened"
End Sub

Sub WaitForWindow(Title As String)
    Dim TopWindow As String
    Do
        DoEvents
        TopWindow = WindowTitle
        Application.Wait Now + TimeValue("0:00:01")
    Loop Until InStr(1, TopWindow, WindowTitle, vbTextCompare) > 0
End Sub

Function WindowTitle()
    Dim WinText As String
    Dim HWnd As Long
    Dim L As Long
    HWnd = GetForegroundWindow()
    WinText = String(255, vbNullChar)
    L = GetWindowText(HWnd, WinText, 255)

    WindowTitle = Left(WinText, InStr(1, WinText, vbNullChar) - 1)
End Function

When you run the Test method, it will wait for something with Notepad in the title. Put your dialog title in the call instead.

Sam
  • 5,424
  • 1
  • 18
  • 33
  • Hey, everything looks to be ok (thanks!), but I have a problem with: `AppActivate (vSAP) Application.Wait Now + TimeValue("0:00:02") WSHShell.SendKeys "%{F4}" Application.Wait Now + TimeValue("0:00:02") WSHShell.SendKeys "{TAB}" WSHShell.SendKeys "{ENTER}"` it's not closing SAP. I need to activate child window, not "SAP Logon 740". – Karol Mar 05 '19 at 12:43
  • Even though I understand your problem, it's extremely hard for me to help you from where I am. This is specific to your setup and since I don't have SAP, I don't know what problem to solve. Having that said, there are options using other WinAPI calls that can help you. – Sam Mar 05 '19 at 16:48
0

Here is solution:

Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As Any, ByVal lpWindowName As Any) As Long

Public Sub IEFrameToTop()
 Dim THandle As Long

 THandle = FindWindow(vbNullString, "**** name of child window here ****")

 If THandle = 0 Then
  MsgBox "Could not find window.", vbOKOnly
 Else
  SetForegroundWindow (THandle)

  SendKeys "%{F4}"
  Application.Wait (Now + TimeValue("0:00:02"))
  SendKeys "{TAB}"
  SendKeys "{ENTER}"

 End If
End Sub

Thanks for your help.

Karol
  • 91
  • 11