Find any field in SAP transaction using recursion

I already presented you the way to loop through tabs in specific transaction. Now it’s time to show You how to find any field in SAP transaction, using recursion.

Without further ado

The starting point for this article will be the code from the MM02 tabs loop article:

Dim i As Integer, sapTab As Object, tabName As String
For i = 0 To session.findById("wnd[0]/usr/tabsTABSPR1").Children.Count - 1
    Set sapTab = session.findById("wnd[0]/usr/tabsTABSPR1").Children.Item(CInt(i))
    tabName = Trim(sapTab.Text)
    
    If tabName = "Sales: sales org. 1" Then
        sapTab.Select
        session.findById("wnd[0]/usr/tabsTABSPR1/tabpSP04/ssubTABFRA1:SAPLMGMM:2000/subSUB2:SAPLMGD1:2158/ctxtMVKE-VMSTA").Text = "Z5"
        session.findById("wnd[0]/usr/tabsTABSPR1/tabpSP04/ssubTABFRA1:SAPLMGMM:2000/subSUB2:SAPLMGD1:2158/ctxtMVKE-VMSTD").Text = "10.12.2021"

    ElseIf tabName = "MRP 1" Then
        sapTab.Select
        session.findById("wnd[0]/usr/tabsTABSPR1/tabpSP12/ssubTABFRA1:SAPLMGMM:2000/subSUB2:SAPLMGD1:2481/ctxtMARC-MMSTA").Text = "Z5"
        session.findById("wnd[0]/usr/tabsTABSPR1/tabpSP12/ssubTABFRA1:SAPLMGMM:2000/subSUB2:SAPLMGD1:2481/ctxtMARC-MMSTD").Text = "10.12.2021"
        session.findById("wnd[0]/usr/tabsTABSPR1/tabpSP12/ssubTABFRA1:SAPLMGMM:2000/subSUB3:SAPLMGD1:2482/ctxtMARC-DISMM").Text = "ZX"
    End If

Next

In this post we will replace the recorded code, after the selection of the specific tab, for the code which will, on itself, find the field we want to find.

SAP transaction tabs are built of objects/containers/tables, text fields which usually describes the nearby input fields and the input fields itself. So, let’s take for example the scrap of MRP 1 tab from MM02 transaction.

From the technical point of view the MRP 1 is a container – Parent – for smaller objects – Children – like those two visible on the above screen – General Data & MRP procedure. Although they are not having smaller containers, they have descriptive fields and input fields – its own Children. Let’s talk about them.

Labels & text fields

Now, as example, take the scrap from the Sales: sales org 1 tab of MM02.

DChain-spec. status is the VMSTA field in the MVKE table. If You want to change the status of the product on the sales organization level, You will change the value in this field – VMSTA.

In the MM02 transaction the name of this field is the merge of the table and field name – MVKE-VMSTA. Unfortunately going deeper into Sales: sales org 1 tab You can find two fields with such name.

Fortunately You can detect which one is the descriptive field – GuiLabel and which one is the actual input field – GuiCTextField.

To sum up the theory…

In general, the SAP tab transaction is build of objects – Parents & Children objects. Keep in mind that not all objects – Children – have its own Children. This will be kinda important in code.

Also, besides knowing the name of the field You want to fill in, remember about its Type. The GuiCTextField type is the one You put the value in SAP transaction.

So lets start the coding from the end!

Take the SAP object – sapObject, check if it has a name sapObject.Name (You may find some with no name), check its type – sapObject.Type.
If all positive, change the value of the field and give return message from the function.

Function checkObjectNameAndFieldType(sapObject As Object, nameText As String, fieldValue As String) As Boolean
    Dim sapObjectName As String
    
    On Error Resume Next
        sapObjectName = ""
        sapObjectName = sapObject.Name
    On Error GoTo 0
    
    If Len(sapObjectName) > 0 Then
        If sapObjectName = nameText Then
            If sapObject.Type = "GuiCTextField" Then
                sapObject.Text = fieldValue
                checkObjectNameAndFieldType = True
            End If
        End If
    End If

End Function

Recursive function to dig into SAP structure

Now the main part – recursive loop. First of all, remind yourself how to deal with digging into folders-files structure. This will ease the start and may arrange all the ideas and thoughts for this code.

You will need a function, which will require SAP object sapObject, name of the field nameText and the value You want to change fieldValue.

Function recursiveLoopThroughObjects(sapObject As Object, nameText As String, fieldValue As String) As Boolean

Just like in folders/parent objects, some of them can have subfolders/children and some don’t. That’s why in the first place You need to check if given object – sapObject – have them or not.

        On Error Resume Next
            childrenCount = 0
            childrenCount = sapObject.Children.Count
        On Error GoTo 0
        
        If childrenCount = 0 Then

        Else

        End If

In case there are no children, You just want to check if that last item of the branch is what You were looking for – call the checkObjectNameAndFieldType, because You can’t go any deeper.

        If childrenCount = 0 Then
            recursiveLoopThroughObjects = checkObjectNameAndFieldType(sapObject, nameText, fieldValue)

In other case, of any children, first of all check the sapObject if it meets the criteria. Just in case.

        Else
            recursiveLoopThroughObjects = checkObjectNameAndFieldType(sapObject, nameText, fieldValue)

If the returned value is False create a loop through all the children of the sapObject and there goes recursion – call the function itself to start the whole process from the begining in the -1 level from sapObject – children level.

            If recursiveLoopThroughObjects = False Then
                For i = 0 To sapObject.Children.Count - 1
                    Set sapObjectChild = sapObject.Children.Item(CInt(i))
                    recursiveLoopThroughObjects = recursiveLoopThroughObjects(sapObjectChild, nameText, fieldValue)

If this will return True value You can Exit Function, but if not, go futher with the loop to the next sapObject Children.

                    If recursiveLoopThroughObjects = True Then
                        Exit Function
                    End If
                Next

Gathering all together, the main function recursiveLoopThroughObjects looks like this below:

Function recursiveLoopThroughObjects(sapObject As Object, nameText As String, fieldValue As String) As Boolean

    Dim sapObjectChild As Object, i As Long, done As Boolean, childrenCount As Long, sapObjectName As String
    
    If recursiveLoopThroughObjects = False Then
        On Error Resume Next
            childrenCount = 0
            childrenCount = sapObject.Children.Count
        On Error GoTo 0
        
        If childrenCount = 0 Then
            recursiveLoopThroughObjects = checkObjectNameAndFieldType(sapObject, nameText, fieldValue)
        Else
            recursiveLoopThroughObjects = checkObjectNameAndFieldType(sapObject, nameText, fieldValue)
            
            If recursiveLoopThroughObjects = False Then
                For i = 0 To sapObject.Children.Count - 1
                    Set sapObjectChild = sapObject.Children.Item(CInt(i))
                    recursiveLoopThroughObjects = recursiveLoopThroughObjects(sapObjectChild, nameText, fieldValue)
                    
                    If recursiveLoopThroughObjects = True Then
                        Exit Function
                    End If
                Next
            End If
        End If
    End If

End Function

And this is it!

Dim i As Integer, sapTab As Object, tabName As String, filledFields As Boolean
For i = 0 To session.findById("wnd[0]/usr/tabsTABSPR1").Children.Count - 1
    Set sapTab = session.findById("wnd[0]/usr/tabsTABSPR1").Children.Item(CInt(i))
    tabName = Trim(sapTab.Text)
    
    If tabName = "Sales: sales org. 1" Then
        sapTab.Select
        Set sapTab = session.findById("wnd[0]/usr/tabsTABSPR1").Children.Item(CInt(i))
        
        filledFields = recursiveLoopThroughObjects(sapTab, "MVKE-VMSTA", "Z7")
        filledFields = recursiveLoopThroughObjects(sapTab, "MVKE-VMSTD", "31.01.2022")

    ElseIf tabName = "MRP 1" Then
        sapTab.Select
        Set sapTab = session.findById("wnd[0]/usr/tabsTABSPR1").Children.Item(CInt(i))
    
        filledFields = recursiveLoopThroughObjects(sapTab, "MARC-MMSTA", "Z5")
        filledFields = recursiveLoopThroughObjects(sapTab, "MARC-MMSTD", "10.01.2022")
        filledFields = recursiveLoopThroughObjects(sapTab, "MARC-DISMM", "ZD")
    End If
Next

Understanding the main idea of the SAP transaction structure solves everything! Just add to this a little bit of knowledge that You already learned before, like that connected with searching for the folder & files, and You are able to find any field in SAP transaction!

Author: Tomasz Płociński

I'm very advanced in VBA, Excel, also easily linking VBA with other Office applications (e.g. PowerPoint) and external applications (e.g. SAP). I take part also in RPA processes (WebQuery, DataCache, IBM Access Client Solutions) where I can also use my SQL basic skillset. I'm trying now to widen my knowledge into TypeScript/JavaScript direction.

3 thoughts on “Find any field in SAP transaction using recursion”

  1. This is really great, Tomasz! Any chance you would be able to do a quick video tutorial of this? Sorry to continue to post on your stuff, I just find this stuff fascinating and you’re great at explaining it simply!

      1. I’m waiting your video about that as soon.
        Can you show me how to get any object in SAP, because we can use VBA script, but could not know exactly object (except record)

Leave a Reply

Your email address will not be published.