Tip: How to Find an SAP Label by its Text

In a few cases the result of an SAP report are a collection labels on the screen. You see in the object hierarchy the lbl for label and their column and row. lbl[53,0] means a label which starts at column 53 in row 0. In this example open fields,.

image

UiPath use the ID of the element to identify it.

image

But the ID could change, if more or less entries are visible. That’s where a search for a descriptive attribute would be helpful. Here an approach how to realize this with SAP GUI Scripting.

This approach uses the detection of the connection and session number from here. I added a tiny function to detect an Id of an UI element via its text (Function FindIdByText). This function loops over the area and compares each text of an element with the searched. If the text was found, the Id is returned.

'-Begin-----------------------------------------------------------------

'-Directives------------------------------------------------------------
Option Explicit

'-Function FindIdByText-------------------------------------------------
Function FindIdByText(oArea, strText)

  Dim cntObj, i, Child, Id

  On Error Resume Next
  cntObj = oArea.Children.Count()
  If cntObj > 0 Then
    For i = 0 To cntObj - 1
      Set Child = oArea.Children.Item(CLng(i))
      If InStr(UCase(Child.Text), UCase(strText)) Then
        Id = Child.Id
        Exit For
      End If
    Next
  End If
  On Error Goto 0
  FindIdByText = Id

End Function

'-Function FindSAPWindowsByHandle---------------------------------------
Function FindSAPWindowByHandle(hSAPWnd)

  Dim SapGuiAuto, app, CollCon, oCon, CollSes, oSes, hWnd, i, j

  Set SapGuiAuto = GetObject("SAPGUI")
  If Not IsObject(SapGuiAuto) Then
    Exit Function
  End If

  Set app = SapGuiAuto.GetScriptingEngine
  If Not IsObject(app) Then
    Exit Function
  End If

  '-Get all connections-------------------------------------------------
  Set CollCon = app.Connections()
  If Not IsObject(CollCon) Then
    Exit Function
  End If

  '-Loop over connections-----------------------------------------------
  For i = 0 To CollCon.Count() - 1

    Set oCon = app.Children(CLng(i))
    If Not IsObject(oCon) Then
      Exit Function
    End If

    '-Get all sessions of a connection----------------------------------
    Set CollSes = oCon.Sessions()
    If Not IsObject(CollSes) Then
      Exit Function
    End If

    '-Loop over sessions------------------------------------------------
    For j = 0 To CollSes.Count() - 1

      Set oSes = oCon.Children(CLng(j))
      If Not IsObject(oSes) Then
        Exit Function
      End If 

      If oSes.Busy() = vbFalse Then

        hWnd = oSes.findById("wnd[0]").Handle
        
        If hSAPWnd = hWnd Then
          FindSAPWindowByHandle = oSes.ID
        End If

      End If

    Next

  Next

End Function

'-Sub Main--------------------------------------------------------------
Sub Main()

  Dim HandleSAPWindow
  Dim sessionId, connectionNumber, sessionNumber
  Dim pos, Len

  HandleSAPWindow = CLng(WScript.Arguments.Item(0))

  sessionId = CStr(FindSAPWindowByHandle(HandleSAPWindow))

  pos = InStr(sessionId, "con[") + 4
  Len = InStr(pos, sessionId, "]") - pos
  connectionNumber = CLng(Mid(sessionId, pos, Len))

  pos = InStr(sessionId, "ses[") + 4
  Len = InStr(pos, sessionId, "]") - pos
  sessionNumber = CLng(Mid(sessionId, pos, Len))

'-SAP GUI Script - Begin------------------------------------------------

Dim SapGuiAuto, app, connection, session, Id, aId

Set SapGuiAuto = GetObject("SAPGUI")
If Not IsObject(SapGuiAuto) Then
  Exit Sub
End If

Set app = SapGuiAuto.GetScriptingEngine
If Not IsObject(app) Then
  Exit Sub
End If

app.HistoryEnabled = False

Set connection = app.Children(CInt(ConnectionNumber))
If Not IsObject(connection) Then
  Exit Sub
End If

If connection.DisabledByServer = True Then
  Exit Sub
End If

Set session = connection.Children(CInt(SessionNumber))
If Not IsObject(session) Then
  Exit Sub
End If

If session.Info.IsLowSpeedConnection = True Then
  Exit Sub
End If

Id = FindIdByText(session.findById("wnd[0]/usr"), _
  WScript.Arguments.Item(1))
aId = Split(Id, "/")
Id = aId(UBound(aId))

app.HistoryEnabled = True

'-SAP GUI Script - End--------------------------------------------------

  WScript.Echo(Id)

End Sub

'-Main------------------------------------------------------------------
Main

'-End-------------------------------------------------------------------

Here my test sequence.

It delivers with the SearchText variable “open” the correct result.

image

Now it is possible to use this Id as variable in the selector.

This example shows us very good how to combine the possibilities of SAP GUI Scripting with the possibilities of UiPath automation. On this way we can detect text on an SAP GUI for Windows screen fast. This approach can be a good complement or alternative to the procedures that already available in the portfolio of the UiPath activities.

2 Likes

HI @StefanSchnell

Thanks for the idea and approach!

Just want to let you and everyone know, that we have implemented this idea in UiPath itself :white_check_mark:

I am working right now on documenting this feature into official documentation for UiPath Studio 21.4 :construction_worker_man:

Starting from UiAutomation Activity Pack 21.2 and higher we are offering the possibilities to use additional attributes such as Text and/or Tooltip and Type of element direct in selector.

See the same example here:

With this out-of-the-box approach the automation is faster than invoke activity.

Best regards, Lev

PS: Case-Sensitive Selectors

For i = 0 To cntObj - 1
  Set Child = oArea.Children.Item(CLng(i))
  If InStr(UCase(Child.Text), UCase(strText)) Then
    Id = Child.Id
    Exit For
  End If
Next

in the sample script above you are using case-insensitive matching, which is also available in our selectors, see here Case-Sensitive Selectors

2 Likes

@LevKushnir

Excellent Lev :star_struck:
Great to know that.

This really helps in stabilizing SAP based Automation. We often face the issue of changing the ID elements after each SAP version upgrade.
Text based search always makes the Bot efficient.

Thank You @LevKushnir for an update…

2 Likes

Good morning everyone!

How to adapt this function to find the line referring to the “measurement code” TN58 with the status in MEDA. The “measure code” TN58 can appear several times, but I want to find the line referring to TN58 with Status in MEDA.

Follow the image below:

image

Hi @Jefferson_Fernando

The solution is here. Exact the same scenario as in your case

Read it carefully

Best regards, Lev

1 Like

Hi @LevKushnir, good afternoon!!

Thanks for the feedback.

In my case I’m working with GuiTableControl (80), in the example you sent you couldn’t adapt.

Below is the SAP Screen configuration, as pointed out by the Tracker.

image

I’m doing this programming in VB.

TN_variable = session.findById(“wnd[0]/usr/tabsTAB_GROUP_10/tabp10\TAB02/ssubSUB_GROUP_10:SAPLIQS0:7235/subCUSTOM_SCREEN:SAPLIQS0:7212/subSUBSCREEN_5:SAPLIQS0:7336/tblSAPLIQS0MASSNAH”).text

In Variable_TN = get the text that is in column 0 and line 2.

Variável_Status session.findById = ( “WND [0] / usr / tabsTAB_GROUP_10 / tabp10 \ TAB02 / ssubSUB_GROUP_10: SAPLIQS0: 7235 / subCUSTOM_SCREEN: SAPLIQS0: 7212 / subSUBSCREEN_5: SAPLIQS0: 7336 / tblSAPLIQS0MASSNAH_2VIEW”) 3 / txtRIX00-SAPLIQS0MASSNAH_2VIEWER").text

In Variable_Status, get the Status referring to Variable_TN.

Today so I can a line referring to the “measure code” TN58 where a “Status” is in MEDA several lines.

What will my idea be if it is possible with your help.

Inside GuiTableControl (80) in SAPGUI, I want to make a query where a Variable refunds me the line referring to the “measure code” TN58 where a “Status” is in MEDA.

HI @Jefferson_Fernando

The beauty of UiPath is, that as a User, you do not care about technical stuff and you do not need to thing about control type GuiTable, Grid Table, etc.

For UiPath both tables looks exactly the same and allows the exact same operations. Therefore my solution above for GRID Table will work the same for GuiTableControl.

See example of GuiTable with exact the same information available, such as Column Name, Text, all kind of numbers (Row number, Column number.)

So, you are ready to go with UiPath only and do not need to think about VB scripting

Best regards, Lev

1 Like

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.