Release order block via SAP GUI Scripting

540 Views Asked by At

I'm able to unblock the outlets by utilizing a SAP GUI script and VBA macros. I need to keep the outlet code(Column a) and status 0(Column B) on an Excel sheet, and then when I click start script, sap will perform the unblocking activities.

Excel template looks as follows, enter image description here

This VBA code works.

Option Explicit
Public SapGuiAuto, WScript, msgcol
Public objGui  As GuiApplication
Public objConn As GuiConnection
Public objSess As GuiSession
Public objSBar As GuiStatusbar
Public objSheet As Worksheet
Dim W_System
Dim iCtr As Integer
Const tcode = "XD05"


Function Attach_Session(iRow, Optional mysystem As String) As Boolean
Dim il, it
Dim W_conn, W_Sess

' Unless a system is provided (XXXYYY where XXX is SID and YYY client)
' get the system from the sheet (in this case it is in cell A8)
If mysystem = "" Then
    W_System = ActiveSheet.Cells(iRow, 1)
Else
    W_System = mysystem
End If

' If we are already connected to a session, exit do not try again
If W_System = "" Then
   Attach_Session = False
   Exit Function
End If

' If the session object is not nil, use that session (assume connected to the correct session)
If Not objSess Is Nothing Then
    If objSess.Info.SystemName & objSess.Info.Client = W_System Then
        Attach_Session = True
        Exit Function
    End If
End If

' If not connected to anything, set up the objects
If objGui Is Nothing Then
   Set SapGuiAuto = GetObject("SAPGUI")
   Set objGui = SapGuiAuto.GetScriptingEngine
End If

' Cycle through the open SAP GUI sessions and check which is in the same system running the matching transaction
For il = 0 To objGui.Children.Count - 1
    Set W_conn = objGui.Children(il + 0)
    For it = 0 To W_conn.Children.Count - 1
        Set W_Sess = W_conn.Children(it + 0)
   If W_Sess.Info.SystemName & W_Sess.Info.Client = W_System Then
            Set objConn = objGui.Children(il + 0)
            Set objSess = objConn.Children(it + 0)
            Exit For
        End If
    Next
Next

' If nothing is found, display and error message
If objSess Is Nothing Then
   MsgBox "No active session to system " + W_System + " with transaction " + tcode + ", or scripting is not enabled.", vbCritical + vbOKOnly
   Attach_Session = False
   Exit Function
End If

' Turn on scripting
If IsObject(WScript) Then
   WScript.ConnectObject objSess, "on"
   WScript.ConnectObject objGui, "on"
End If

' Maximize the window of the connected session
Set objSBar = objSess.findById("wnd[0]/sbar")
objSess.findById("wnd[0]").Iconify

Attach_Session = True


End Function

Public Sub StartProcessing()

Dim W_Obj1, W_Obj2, W_Obj3, W_Obj4, iRow
Dim W_Func
Dim W_Src_Ord
Dim W_Ret As Boolean
Dim itemcount As Integer
Dim itemmax As Integer
Const startrow As Integer = 5 'First row with actual data

Set objSheet = ActiveWorkbook.ActiveSheet
' Connect to a system stored in cell A8
W_Ret = Attach_Session(2)
If Not W_Ret Then
    MsgBox "Not connected to client"
    GoTo MyEnd
End If

itemcount = 0
itemmax = 0

' Determine the number of items to be processed: where the status is zero
For iRow = startrow To objSheet.UsedRange.Rows.Count
    If objSheet.Cells(iRow, 2) = "0" Then
        itemmax = itemmax + 1
    End If
Next
' Update the counter in cell A9
objSheet.Cells(3, 1) = itemcount & "/" & itemmax

' Cycle through the rows with status 0 and call the ProcessRow function to process them
For iRow = startrow To objSheet.UsedRange.Rows.Count
    If objSheet.Cells(iRow, 2) = "0" Then
        Call ProcessRow(iRow)
        itemcount = itemcount + 1
        objSheet.Cells(3, 1) = itemcount & "/" & itemmax
    End If
Next
           

MyEnd:
' destory the objects, free up memory
    Set objSess = Nothing
    Set objGui = Nothing
    Set SapGuiAuto = Nothing
    
    MsgBox "Script completed.", vbInformation + vbOKOnly
       
End Sub

Function ProcessRow(iRow)
Dim W_BPNumber, W_Blockcode, W_Companycode, W_Salesorg
Dim lineitems As Long

' Set the line status to "processing..."
objSheet.Cells(iRow, 2) = 1

'BP Number
If objSheet.Cells(iRow, 1) <> "" Then
    W_BPNumber = objSheet.Cells(iRow, 1)
Else
    W_BPNumber = "xxxxxx"
End If

'Company Code
If objSheet.Cells(iRow, 2) <> "03" Then
    W_Companycode = objSheet.Cells(iRow, 2)
Else
    W_Companycode = "xxxxxx"
End If
'Sales Org
If objSheet.Cells(iRow, 4) <> "" Then
    W_Salesorg = objSheet.Cells(iRow, 4)
Else
    W_Salesorg = "xxxxxx"
End If

'Block Code
If objSheet.Cells(iRow, 5) <> "" Then
    W_Blockcode = objSheet.Cells(iRow, 5)
Else
    W_Blockcode = ""
End If



' Set error handling to the below code where we can capture if a line had failed in the GUI script
On Error GoTo myerr

' SAP GUI Script starts here

objSess.findById("wnd[0]").Iconify
'objSess.findById("wnd[0]").Maximize
objSess.findById("wnd[0]/tbar[0]/okcd").Text = "/nXD05"
objSess.findById("wnd[0]").sendVKey 0
objSess.findById("wnd[0]/usr/ctxtRF02D-KUNNR").Text = W_BPNumber
objSess.findById("wnd[0]/usr/ctxtRF02D-BUKRS").Text = "1172"
objSess.findById("wnd[0]/usr/ctxtRF02D-VKORG").Text = "1172"
objSess.findById("wnd[0]/usr/ctxtRF02D-VTWEG").Text = "10"
objSess.findById("wnd[0]/usr/ctxtRF02D-SPART").Text = "00"
objSess.findById("wnd[0]/usr/ctxtRF02D-SPART").SetFocus
objSess.findById("wnd[0]/usr/ctxtRF02D-SPART").caretPosition = 2
objSess.findById("wnd[0]").sendVKey 0
objSess.findById("wnd[0]/usr/ctxtKNA1-AUFSD").Text = ""
objSess.findById("wnd[0]/usr/ctxtKNVV-AUFSD").Text = ""
objSess.findById("wnd[0]/usr/ctxtKNVV-AUFSD").SetFocus
objSess.findById("wnd[0]/usr/ctxtKNVV-AUFSD").caretPosition = 0
objSess.findById("wnd[0]/tbar[0]/btn[11]").press
objSess.findById("wnd[0]").sendVKey 12


' Gets the message from the status bar and save it in column B
objSheet.Cells(iRow, 5) = objSBar.Text

' Update the Status to "Completed" and exit
objSheet.Cells(iRow, 2) = 2
Exit Function

myerr:
' Update the status to "Error"
objSheet.Cells(iRow, 2) = 3

End Function

My requirements

If the following field in sap has the value 03, the outlet should be unblocked; otherwise, an error message should show in the excel file for that particular outlet.

objSess.findById("wnd[0]/usr/ctxtKNA1-AUFSD").Text = ""
objSess.findById("wnd[0]/usr/ctxtKNVV-AUFSD").Text = ""

enter image description here

How to achieve this with VBA?

1

There are 1 best solutions below

0
OzzyMiner On

not sure I fully understand what you are asking here but maybe something like this:

Const cBlockText As String = "03"

objSess.findById("wnd[0]").Iconify
objSess.findById("wnd[0]/tbar[0]/okcd").Text = "/nXD05"
objSess.findById("wnd[0]").sendVKey 0

objSess.findById("wnd[0]/usr/ctxtRF02D-KUNNR").Text = W_BPNumber
objSess.findById("wnd[0]/usr/ctxtRF02D-BUKRS").Text = "1172"
objSess.findById("wnd[0]/usr/ctxtRF02D-VKORG").Text = "1172"
objSess.findById("wnd[0]/usr/ctxtRF02D-VTWEG").Text = "10"
objSess.findById("wnd[0]/usr/ctxtRF02D-SPART").Text = "00"
objSess.findById("wnd[0]").sendVKey 0

' New code here:
' Not sure of and/or rules?
If objSess.findById("wnd[0]/usr/ctxtKNA1-AUFSD").Text = cBlockText _
   Or objSess.findById("wnd[0]/usr/ctxtKNVV-AUFSD").Text = cBlockText Then

    objSheet.Cells(iRow, 5) = "Unable to block: Dispute with customer"
    objSess.findById("wnd[0]/tbar[0]/okcd").Text = "/n"
    objSess.findById("wnd[0]").sendVKey 0
Else
    objSess.findById("wnd[0]/usr/ctxtKNA1-AUFSD").Text = ""
    objSess.findById("wnd[0]/usr/ctxtKNVV-AUFSD").Text = ""
    objSess.findById("wnd[0]/tbar[0]/btn[11]").press
    objSess.findById("wnd[0]").sendVKey 12

    objSheet.Cells(iRow, 5) = objSBar.Text

    ' Update the Status to "Completed" and exit
    objSheet.Cells(iRow, 2) = 2
End If