Morkai Posted May 26, 2020 Share Posted May 26, 2020 (edited) Background: I'm currently using AutoIt v3.3.12.0 to control SAP GUI. There're lots of calls to $session.FindById(), eg.: $session.FindById("wnd[0]/usr/ctxtVBAK-VBELN").Text = $order I had an idea to replace $session.FindById with a custom function TryFindById() that will exit the program with an error if FindById() doesn't return an object and then replace the previous code with: TryFindById("wnd[0]/usr/ctxtVBAK-VBELN").Text = $order but AU3Check would throw an error: Statement cannot be just an expression. So I thought maybe it will go away if I upgrade to the latest version. After upgrading, my script failed to recognize a newly created SAP GUI session. I'm looping over all sessions and checking whether their windows are enabled ($WIN_STATE_ENABLED): $win = $session.FindById("wnd[0]") $state = WinGetState($win.Handle) ConsoleWrite($state) In version v3.3.12.0, WinGetState() returns 15 (00001111): window exists, is visible, enabled and active. In versions v3.3.14.0 to v3.3.15.3, WinGetState() returns 0. btw why is this correct: $session.FindById("wnd[0]/usr/ctxtVBAK-VBELN").Text = $order and this is not: Func TryFindById($id) Return $session.FindById($id) EndFunc TryFindById("wnd[0]/usr/ctxtVBAK-VBELN").Text = $order Edited May 26, 2020 by Morkai Code fix Link to comment Share on other sites More sharing options...
seadoggie01 Posted May 26, 2020 Share Posted May 26, 2020 2 minutes ago, Morkai said: $win = $session.FindById("wnd[0") $state = WinGetState($win.Handle) ConsoleWrite($state) Looks like your issue might be here. You have "wnd[0" without a closing bracket I would also suggest either having your TryFindById function either return the text property of the session, or setting a variable ($session?) to the result of your function before getting the .Text property. It looks a bit cleaner and allows you to handle errors better in the future. All my code provided is Public Domain... but it may not work. Use it, change it, break it, whatever you want. Spoiler My Humble Contributions:Personal Function Documentation - A personal HelpFile for your functionsAcro.au3 UDF - Automating Acrobat ProToDo Finder - Find #ToDo: lines in your scriptsUI-SimpleWrappers UDF - Use UI Automation more Simply-erKeePass UDF - Automate KeePass, a password managerInputBoxes - Simple Input boxes for various variable types Link to comment Share on other sites More sharing options...
Morkai Posted May 26, 2020 Author Share Posted May 26, 2020 It was a typo in the example. TryFindById() in looks like this: Func TryFindById($id) $control = $session.FindById($id) If Not IsObj($control) Then LogDebug("CONTROL_NOT_FOUND=" & $id) LogError("INVALID_SCREEN", $ERR_INVALID_SCREEN) EndIf Return $control EndFunc Func LogDebug($message = "") ConsoleWrite($message & @CRLF) EndFunc Func LogError($message, $exitCode = -1) ConsoleWriteError($message & @CRLF) If $exitCode <> -1 Then CloseSession() Exit($exitCode) EndIf EndFunc and would be used used like this: TryFindById("...id...") TryFindById("...id...").Text = $value TryFindById("...id...").Press() instead of: Func AssertControl($control, $id) If Not IsObj($control) Then LogDebug("CONTROL_NOT_FOUND=" & $id) LogError("INVALID_SCREEN") EndIf EndFunc $ctrlId = "wnd[0]/usr/ctxtVBAK-VBELN" $ctrl = $session.FindById($ctrlId) AssertControl($ctrl, $ctrlId) $ctrlId = "wnd[0]/usr/ctxtVBAK-VBELN" $ctrl = $session.FindById($ctrlId) AssertControl($ctrl, $ctrlId) $ctrl.Text = $value $ctrlId = "wnd[0]/usr/ctxtVBAK-VBELN" $ctrl = $session.FindById($ctrlId) AssertControl($ctrl, $ctrlId) $ctrl.Press() Anyway, In v3.3.12 $win is an object, $win.Handle is a handle, WinGetState() returns 15 and @error is 0. In v3.3.14-15 $win is an object, $win.Handle is a handle, WinGetState() returns 0 and @error is 0. Link to comment Share on other sites More sharing options...
seadoggie01 Posted May 26, 2020 Share Posted May 26, 2020 Can you post a small reproducer of this issue? I'm unable to try any of your code so far. As for your "btw" at the end of your first post, you can use the result of a function as an object... as long as the result of a function is an object. I highly suggest debugging your code a bit more and checking out the Au3Check parameters to help ensure you're following best programming practices. I get too many errors without it All my code provided is Public Domain... but it may not work. Use it, change it, break it, whatever you want. Spoiler My Humble Contributions:Personal Function Documentation - A personal HelpFile for your functionsAcro.au3 UDF - Automating Acrobat ProToDo Finder - Find #ToDo: lines in your scriptsUI-SimpleWrappers UDF - Use UI Automation more Simply-erKeePass UDF - Automate KeePass, a password managerInputBoxes - Simple Input boxes for various variable types Link to comment Share on other sites More sharing options...
Morkai Posted May 26, 2020 Author Share Posted May 26, 2020 You won't be able to run it without access to an instance of SAP GUI so I made a video: #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Change2CUI=y ;#AutoIt3Wrapper_Version=Beta #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** Global $session = Null Func TryFindById($id) Return $session.FindById($id) EndFunc $wrapper = ObjCreate("SapROTWr.SAPROTWrapper") $sapgui = $wrapper.GetROTEntry("SAPGUI") $application = $sapgui.GetScriptingEngine() $connection = $application.Children(0) $session = $connection.Children(0) $window = $session.FindById("wnd[0]") $handle = $window.Handle ConsoleWrite("@AutoItVersion=" & @AutoItVersion & @CRLF) ConsoleWrite("WinGetState($handle)=" & WinGetState($handle) & @CRLF) $session.FindById("wnd[0]").Restore() ;TryFindById("wnd[0]").Restore() Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now