Jump to content

Code Optimization? - (Moved)


Recommended Posts

Hello all,

my goal is to observe a open application and read the visual text, filter for a specific value and based on that value to refresh a sidebar using an http call.

This code is working but it is my first AutoIt Coding Experience and this is why I am asking you for any potential code optimization, as I have to observe many more Windows and in order to make this clean I ask for your assistance.

So the goals are:

Run invisible in the Background
Observe open Window of Application (only do something if the Windows is open)
Read Visual Text and get specific value (Vendor Number)
If this Number changes, update the sidebar using http call

Here is the code:

#include "Array.au3"
#include "WinHttp.au3"
#include "WinAPI.au3"
#include "WindowsConstants.au3"
#include "StringConstants.au3"


Global $lieferant, $firstRun, $lieferantChanged
$firstRun = True

Func observe()
   While not WinExists("Test2 Rechnungskontrolle (Verbuchung)")
       Sleep(250)
   WEnd
   While WinExists("Test2 Rechnungskontrolle (Verbuchung)")
     Sleep(250)
     if($firstRun) Then
        getLieferant()
        $firstRun = False
      EndIf
     isChanged()
     getLieferant()
   Wend

EndFunc

Func getLieferant()

   if(WinExists("Test2 Rechnungskontrolle (Verbuchung)")) Then
      local $strString = WinGetText("Test2 Rechnungskontrolle (Verbuchung)")
      local $arrResult = StringRegExp($strString, '(?s)&Adresse.*?\d+.*?(\d+)', $STR_REGEXPARRAYGLOBALMATCH)
      If IsArray($arrResult) Then $lieferant = $arrResult[0]
      Return $lieferant
   Else
      observe()
   EndIf

EndFunc

Func isChanged()

   if(WinExists("Test2 Rechnungskontrolle (Verbuchung)")) Then
      local $strString = WinGetText("Test2 Rechnungskontrolle (Verbuchung)")
      local $arrResult = StringRegExp($strString, '(?s)&Adresse.*?\d+.*?(\d+)', $STR_REGEXPARRAYGLOBALMATCH)
      If IsArray($arrResult) Then $lieferantChanged = $arrResult[0]
      If $lieferantChanged == $lieferant Then
         getLieferant()
      Else
         ;MsgBox(0,"Changed",$lieferantChanged)
         ConsoleWrite($lieferantChanged)
         refreshSidebar($lieferantChanged)
         getLieferant()
      EndIf
   Else
      observe()
   EndIf
EndFunc

Func refreshSidebar($vendorID)
   Opt("MustDeclareVars", 1)

   ; Initialize and get session handle
   Global $hOpen = _WinHttpOpen()
   ; Get connection handle
   Global $hConnect = _WinHttpConnect($hOpen, "http://MKSRVAPP04:25024")

   Local $hRequest = _WinHttpSimpleRequest($hConnect, "GET", "api/client/sidebar/sendCommand?user=MULTIKRAFT\" & @UserName & "&call=OBJ:Vendor@@SELECT@@IDX:Vendor%20ID=" & $vendorID)

   ; Close handles
   _WinHttpCloseHandle($hConnect)
   _WinHttpCloseHandle($hOpen)
EndFunc



observe()

 

Thank you very much!

Best Regards
Kenan

Link to post
Share on other sites
  • Moderators

Moved to the appropriate forum, as the Developer General Discussion forum very clearly states:

Quote

General development and scripting discussions. If it's super geeky and you don't know where to put it - it's probably here.


Do not create AutoIt-related topics here, use the AutoIt General Help and Support or AutoIt Technical Discussion forums.

Moderation Team

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to post
Share on other sites

Personally I use indirect recursion with much caution.  Also there is too much redundancy in your code.  Here what I would advise :

Opt("MustDeclareVars", 1)

Global $lieferant = 0 ; make it to a value that cannot be found

observe()

Func observe()
  While True
    While Not WinExists("Test2 Rechnungskontrolle (Verbuchung)")
      Sleep(250)
    WEnd
    While WinExists("Test2 Rechnungskontrolle (Verbuchung)")
      Sleep(250)
      getLieferant()
    WEnd
  WEnd
EndFunc   ;==>observe

Func getLieferant()

  If Not WinExists("Test2 Rechnungskontrolle (Verbuchung)")) Then Return
  Local $strString = WinGetText("Test2 Rechnungskontrolle (Verbuchung)")
  Local $arrResult = StringRegExp($strString, '(?s)&Adresse.*?\d+.*?(\d+)', $STR_REGEXPARRAYGLOBALMATCH)
  If Not IsArray($arrResult) Then Return
  If $lieferant == $arrResult[0] Then Return
  $lieferant = $arrResult[0]
  ;MsgBox(0,"Changed",$lieferant)
  ConsoleWrite($lieferant)
  refreshSidebar($lieferant)

EndFunc   ;==>getLieferant

Func refreshSidebar($vendorID)
  ; Initialize and get session handle
  Local $hOpen = _WinHttpOpen()
  ; Get connection handle
  Local $hConnect = _WinHttpConnect($hOpen, "http://MKSRVAPP04:25024")

  Local $hRequest = _WinHttpSimpleRequest($hConnect, "GET", "api/client/sidebar/sendCommand?user=MULTIKRAFT\" & @UserName & "&call=OBJ:Vendor@@SELECT@@IDX:Vendor%20ID=" & $vendorID)

  ; Close handles
  _WinHttpCloseHandle($hConnect)
  _WinHttpCloseHandle($hOpen)
EndFunc   ;==>refreshSidebar

Untested of course...

Link to post
Share on other sites
56 minutes ago, Nine said:

Personally I use indirect recursion with much caution.  Also there is too much redundancy in your code.  Here what I would advise :

Opt("MustDeclareVars", 1)

Global $lieferant = 0 ; make it to a value that cannot be found

observe()

Func observe()
  While True
    While Not WinExists("Test2 Rechnungskontrolle (Verbuchung)")
      Sleep(250)
    WEnd
    While WinExists("Test2 Rechnungskontrolle (Verbuchung)")
      Sleep(250)
      getLieferant()
    WEnd
  WEnd
EndFunc   ;==>observe

Func getLieferant()

  If Not WinExists("Test2 Rechnungskontrolle (Verbuchung)")) Then Return
  Local $strString = WinGetText("Test2 Rechnungskontrolle (Verbuchung)")
  Local $arrResult = StringRegExp($strString, '(?s)&Adresse.*?\d+.*?(\d+)', $STR_REGEXPARRAYGLOBALMATCH)
  If Not IsArray($arrResult) Then Return
  If $lieferant == $arrResult[0] Then Return
  $lieferant = $arrResult[0]
  ;MsgBox(0,"Changed",$lieferant)
  ConsoleWrite($lieferant)
  refreshSidebar($lieferant)

EndFunc   ;==>getLieferant

Func refreshSidebar($vendorID)
  ; Initialize and get session handle
  Local $hOpen = _WinHttpOpen()
  ; Get connection handle
  Local $hConnect = _WinHttpConnect($hOpen, "http://MKSRVAPP04:25024")

  Local $hRequest = _WinHttpSimpleRequest($hConnect, "GET", "api/client/sidebar/sendCommand?user=MULTIKRAFT\" & @UserName & "&call=OBJ:Vendor@@SELECT@@IDX:Vendor%20ID=" & $vendorID)

  ; Close handles
  _WinHttpCloseHandle($hConnect)
  _WinHttpCloseHandle($hOpen)
EndFunc   ;==>refreshSidebar

Untested of course...

wow, this is great, thank you very much.

Link to post
Share on other sites

Next thing is you said you want to monitor multiple windows?

searching by window name is going to slow your code quite a bit

maybe something like this

Global $aWindows[0][3] ;Hwnd, WinText, last vendorID

AddWindow($aWindows, "Test2 Rechnungskontrolle (Verbuchung)")
observe($aWindows)

Func AddWindow(Byref $aWin, $sWindowText, $VendorId = 0)
    Local $iElement = UBound($aWin, 1)
    ReDim $aWin[$iElement + 1][3]
    $aWin[$iElement][0] = WinGetHandle ($sWindowText)
    $aWin[$iElement][1] = $sWindowText
    $aWin[$iElement][2] = $VendorId
EndFunc

Func observe(Byref $aWin)
  Local $hWnd, $lieferant
  While True
    For $i = 0 to UBound($aWin) - 1  
        $hWnd = $aWin[$i][0]
        If $hWnd Then
            If WinExists($hWnd) And WinGetTitle($hWnd) == $aWin[$i][1] Then
                $lieferant = getLieferant($hWnd) ; Pass valid hwnd onto getLieferant have it return the vendorID & store it
                If $lieferant = "" Then
                    ;VendorID not found..
                    ;Delete window from list? 
                    ;Check again later?
                    ;Throw Warning?
                ElseIf $lieferant <> $aWin[$i][2] Then
                    ConsoleWrite("NEW " & $lieferant & @crlf)
                    refreshSidebar($lieferant)
                    $aWin[$i][2] = $lieferant
                EndIf
            Else
                $aWin[$i][0] = 0 ; Win No longer exists donot check again
            EndIf
        EndIf
    Next
    Sleep(250)  
  WEnd
EndFunc

Func getLieferant($hWnd)
  Local $strString = WinGetText($hWnd)
  Local $arrResult = StringRegExp($strString, '(?s)&Adresse.*?\d+.*?(\d+)', $STR_REGEXPARRAYGLOBALMATCH)
  If Not IsArray($arrResult) Then Return ""
  Return $arrResult[0]
EndFunc

 

Edited by Bilgus
Link to post
Share on other sites

@keeeniiic

There is no need to quote a post for your answer (except when you want to refer to a specific part of a previous post - then mark this part and click on the appearing "Quote selection") . We know what we have written ;)
Simply enter your reply in the input field at the end of the thread and click "Submit Reply" :)

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2021-06-05 - Version 1.5.4.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2021-06-14 - Version 1.6.5.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
Task Scheduler (2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Tutorials:
ADO - Wiki, WebDriver - Wiki

 

Link to post
Share on other sites

I would - in addition - suggest a hotkey to exit the script. Else such code would make your script wait forever when there isn't and never will be a window named "Test2 Rechnungskontrolle (Verbuchung)".

While Not WinExists("Test2 Rechnungskontrolle (Verbuchung)")
    Sleep(250)
WEnd

 

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2021-06-05 - Version 1.5.4.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2021-06-14 - Version 1.6.5.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
PowerPoint (2017-06-06 - Version 0.0.5.0) - Download - General Help & Support
Excel - Example Scripts - Wiki
Word - Wiki
Task Scheduler (2019-12-03 - Version 1.5.1.0) - Download - General Help & Support - Wiki

Tutorials:
ADO - Wiki, WebDriver - Wiki

 

Link to post
Share on other sites
31 minutes ago, water said:

I would - in addition - suggest a hotkey to exit the script. Else such code would make your script wait forever when there isn't and never will be a window named "Test2 Rechnungskontrolle (Verbuchung)"

 

or just keep count of how many windows succeeded..

Func observe(Byref $aWin)
  Local $iValid = 1, $hWnd, $lieferant
  While $iValid > 0
    $iValid = 0
    For $i = 0 to UBound($aWin) - 1  
        $hWnd = $aWin[$i][0]
        If $hWnd Then
            If WinExists($hWnd) And WinGetTitle($hWnd) == $aWin[$i][1] Then
                ...
                $iValid += 1
            Else
                $aWin[$i][0] = 0 ; Win No longer exists donot check again
            EndIf
        EndIf
    Next
    Sleep(250)  
  WEnd
EndFunc

 

Link to post
Share on other sites

@Bilgus thank you for the suggestion

@water thank you for the hint, won't happen again.

Thank you for the last answers, would this code cover, if the user reopens the window, because this happens quite often, they work in the "Test 2 ... " window then close it open another one and later come back to the "Test 2.. " window.

Let me know thanks

Link to post
Share on other sites

I don't know enough about your application if the hWnd stays the same then sure but generally when closing and reopening windows the hwnd changes so you might have to search for it by name each time its not found...

 

The code I posted will still work but it'll need to be tweaked

 

 

Link to post
Share on other sites
Opt("MustDeclareVars", 1)

Global $lieferant = 0 ; make it to a value that cannot be found
Global $aWindows[0][3] ;Hwnd, WinText, last vendorID
Global $bQuit = False

HotKeySet("+!q", "Quit_Loop") ; Shift-Alt-q
HotKeySet("+!a", "AddCurrentWindow") ; Shift-Alt-a

AddWindow($aWindows, "Test2 Rechnungskontrolle (Verbuchung)")
observe($aWindows)

Func AddWindow(Byref $aWin, $sWindowText, $VendorId = 0)
    Local $iElement = UBound($aWin, 1)
    ReDim $aWin[$iElement + 1][3]
    $aWin[$iElement][0] = WinGetHandle ($sWindowText)
    $aWin[$iElement][1] = $sWindowText
    $aWin[$iElement][2] = $VendorId
EndFunc

Func observe(Byref $aWin)
  Local $hWnd, $lieferant
  While Not $bQuit
    For $i = 0 to UBound($aWin) - 1  
        $hWnd = $aWin[$i][0]
        If $hWnd Then
            If WinExists($hWnd) And WinGetTitle($hWnd) == $aWin[$i][1] Then
                $lieferant = getLieferant($hWnd) ; Pass valid hwnd onto getLieferant have it return the vendorID & store it
                If $lieferant < 0 Then
                    ;VendorID not found..
                    ;Delete wiondow from list? 
                    ;Check again later?
                    ;Throw Warning?
                ElseIf $lieferant <> $aWin[$i][2] Then
                    ConsoleWrite("NEW " & $lieferant & @crlf)
                    refreshSidebar($lieferant)
                    $aWin[$i][2] = $lieferant
                EndIf
            Else
                $aWin[$i][0] = WinGetHandle ($aWin[$i][1])
            EndIf
        Else
            ;Try to find the window again   
            $aWin[$i][0] = WinGetHandle ($aWin[$i][1])
        EndIf
    Next
    Sleep(250)  
  WEnd
EndFunc

Func getLieferant($hWnd)
  Local $strString = WinGetText($hWnd)
  Local $arrResult = StringRegExp($strString, '(?s)&Adresse.*?\d+.*?(\d+)', $STR_REGEXPARRAYGLOBALMATCH)
  If Not IsArray($arrResult) Then Return -1
  Return $arrResult[0]
EndFunc

Func refreshSidebar($vendorID)
  ; Initialize and get session handle
  Local $hOpen = _WinHttpOpen()
  ; Get connection handle
  Local $hConnect = _WinHttpConnect($hOpen, "http://MKSRVAPP04:25024")

  Local $hRequest = _WinHttpSimpleRequest($hConnect, "GET", "api/client/sidebar/sendCommand?user=MULTIKRAFT\" & @UserName & "&call=OBJ:Vendor@@SELECT@@IDX:Vendor%20ID=" & $vendorID)

  ; Close handles
  _WinHttpCloseHandle($hConnect)
  _WinHttpCloseHandle($hOpen)
EndFunc   ;==>refreshSidebar

Func Quit_Loop()
    $bQuit = True
EndFunc

Func AddCurrentWindow()
    Local $hWnd = WinGetHandle("[ACTIVE]", "")
    AddWindow($aWindows, WinGetText($hWnd))
    ConsoleWrite("Added: " & WinGetTitle($hWnd) & @crlf)
EndFunc

And Hotkeyset is indeed your best bet since there could be no active windows for a bit

Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...