cancel
Showing results for 
Search instead for 
Did you mean: 

SAP GUI crashes when running a Python Script while having multiple sessions open.

Jorge_Bustos_mx
Discoverer
0 Kudos

Hi, team:

Though I'm using Python as a platform, I'm basically using a VB Scripting to perform a series of steps in SAP. The script usually runs without issues, if we only have one session window open. The crashes happen at random iterations but usually happen when querying data from SAP, performing changes or saving changes. This causes the entire SAP GUI to close all session and conexions. Please advise.

import win32com.client
import sys
import subprocess
import time
import datetime
import pandas as pd
import numpy as np
def process_past(past_df):
    try:
        print('Connecting to SAP GUI...')
        sapg = win32com.client.GetObject('SAPGUI')
        if not type(sapg) == win32com.client.CDispatch:
            return
        appx = sapg.GetScriptingEngine
        if not type(appx) == win32com.client.CDispatch:
            sapg = None
            return
        conx = appx.Children(0)
        if not type(conx) == win32com.client.CDispatch:
            sapg = None
            appx = None
            return
        ssnx = conx.Children(0)
        if not type(ssnx) == win32com.client.CDispatch:
            sapg = None
            appx = None
            conx = None
            return
        print('Connection is successful\nStarting to process Past Dues...')
        unqso = past_df['so'].unique()
        unqso.sort()
        stime = 0.0
        for sox in unqso:
            block = past_df.query('so == @sox & action.isnull()')
            block = block.sort_values(by = ['crrDlv','vldDlv', 'soLn'], ascending = [True, True, True])
            unqc = block['crrDlv'].unique()
            try:
                for cdlv in unqc:
                    cblock = block.query('crrDlv == @cdlv')
                    unqd = cblock['vldDlv'].unique()
                    unqd.sort()
                    for vdlv in unqd:
                        print(f'Opening transaction VA02 in SAP\nSearching for SO {sox}...')
                        ssnx.findById("wnd[0]/tbar[0]/okcd").text = '/nva02'
                        ssnx.findById('wnd[0]').sendVKey(0)
                        ssnx.findById('wnd[0]/usr/ctxtVBAK-VBELN').text = sox
                        ssnx.findById('wnd[0]/usr/btnBT_SUCH').press()
                        sleep_run = 0
                        while ssnx.findById('wnd[0]/sbar').text != '' and sleep_run <= 4:
                            print(f'Waiting for {stime} seconds and try to open SO {sox} again')
                            time.sleep(stime)
                            ssnx.findById('wnd[0]/usr/ctxtVBAK-VBELN').text = sox
                            ssnx.findById('wnd[0]/usr/btnBT_SUCH').press()
                            sleep_run += 1
                            stime = 10
                        while ssnx.ActiveWindow.Name == 'wnd[1]':
                            ssnx.findById('wnd[1]/tbar[0]/btn[0]').press()
                        wgrp = cblock.query('vldDlv == @vdlv')
                        wgrp = wgrp.sort_values(by = 'soLn')
                        vdlx = datetime.datetime.strptime(vdlv, '%m/%d/%Y')
                        print(ssnx.ActiveWindow.text)
                        # display all the SO lines
                        ssnx.findById('wnd[0]/tbar[0]/okcd').text = 'uall'
                        ssnx.findById('wnd[0]').sendVKey(0)
                        for x, rows in wgrp.iterrows():
                            noack = wgrp.loc[x, 'no_ack']
                            mout = wgrp.loc[x, 'move_out']
                            mfgx = wgrp.loc[x, 'mfgl'].lower()
                            lnx = wgrp.loc[x, 'soLn']
                            invc = wgrp.loc[x, 'invChk']
                            cdlv = wgrp.loc[x, 'crrDlv'].date()
                            rdlv = wgrp.loc[x, 'rqtDlv'].date()
                            dlpf = wgrp.loc[x, 'dlrProfile']
                            fstd = None
                            hold = None
                            rjct = None
                            rwg = int(lnx/10) - 1 
                            0 if rwg < 0 else rwg
                            ssnx.findById(soLn_grid).verticalScrollbar.position = rwg
                            lns = int(ssnx.findById(f'{soLn_grid}/txtVBAP-POSNR[0,0]').text)
                            if rwg > 0 and lns == 10:
                                rwg = round(rwg/2,0)
                                ssnx.findById(soLn_grid).verticalScrollbar.position = rwg
                                lns = int(ssnx.findById(f'{soLn_grid}/txtVBAP-POSNR[0,0]').text)
                                print(f'Script overshot on first try. Starting off SO Line {lns} found on row {rwg}')
                            while lns != lnx:
                                if lns == lnx:
                                    pass # the lines match there is no need to move the row
                                elif lns < lnx:
                                    rwg += 1
                                    ssnx.findById(soLn_grid).verticalScrollbar.position = rwg
                                    lns = int(ssnx.findById(f'{soLn_grid}/txtVBAP-POSNR[0,0]').text)
                                elif lns > lnx:
                                    rwg -= 1
                                    ssnx.findById(soLn_grid).verticalScrollbar.position = rwg
                                    lns = int(ssnx.findById(f'{soLn_grid}/txtVBAP-POSNR[0,0]').text)
                            ssnx.findById(soLn_grid).verticalScrollbar.position = rwg
                            ssnx.findById(soLn_grid).getAbsoluteRow(rwg).selected = True
                            past_df.loc[x,'saprow'] = rwg
                            print(f'SO: {sox} line: {lnx} was found on row: {rwg} with grid line value: {lns}')
                            ssnx.findById('wnd[0]/usr/tabsTAXI_TABSTRIP_OVERVIEW/tabpT\\01').select()
                            fstd = ssnx.findById(f'{soLn_grid}/ctxtRV45A-ETDAT[8,0]').text
                            past_df.loc[x, 'fdate'] = datetime.datetime.strptime(fstd, '%m/%d/%Y')
                            hold = ssnx.findById(f'{soLn_grid}/chkRV45A-STAT03[16,0]').selected
                            past_df.loc[x, 'hold'] = hold # boolean value (True or False)
                            past_df.loc[x, 'rjctr'] = ssnx.findById(f'{soLn_grid}/cmbVBAP-ABGRU[9,0]').text
                            if past_df.loc[x, 'hold'] == True or past_df.loc[x, 'rjctr'] != '' or vdlx.date() == cdlv:
                                past_df.loc[x, 'action'] = 'close as cib'
                                cblock.loc[x, 'action'] = 'close as cib'
                            elif mfgx == 'x':
                                past_df.loc[x, 'action'] = 'update delivery and send to mfg'
                                cblock.loc[x, 'action'] = 'update delivery and send to mfg'
                            elif mfgx != 'x' and vdlx.date() > cdlv and rdlv < cdlv:
                                past_df.loc[x, 'action'] = 'close as cib'
                                cblock.loc[x, 'action'] = 'close as cib'
                            elif invc == True and vdlx.date() == cdlv:
                                past_df.loc[x, 'action'] = 'update delivery and send to mfg'
                                cblock.loc[x, 'action'] = 'update delivery and send to mfg'
                            elif past_df.loc[x, 'fdate'].date() == vdlx.date():
                                past_df.loc[x, 'action'] = 'past due process 01'
                                cblock.loc[x, 'action'] = 'past due process 01'
                            elif past_df.loc[x, 'fdate'].date() != vdlx.date():
                                past_df.loc[x, 'action'] = 'past due process 02'
                                cblock.loc[x, 'action'] = 'past due process 02'
                            ssnx.findById('wnd[0]/usr/tabsTAXI_TABSTRIP_OVERVIEW/tabpT\\01').select()
                        dgrp = cblock.query('action == "close as cib"')
                        if len(dgrp) > 0:
                            print(f'so {sox} valid: {vdlx} == current: {cdlv}.\nRemoving NoAck and saving changes. Complete as CIB.')
                            ssnx.findById('wnd[0]/mbar/menu[1]/menu[1]/menu[11]/menu[5]').select()
                            ssnx.findById('wnd[1]/tbar[0]/btn[7]').press()
                            ssnx.findById('wnd[0]/tbar[0]/btn[11]').press()
                            start_time = time.perf_counter()
                            while ssnx.ActiveWindow.Name == 'wnd[1]':
                                if ssnx.ActiveWindow.Text == 'Information':
                                    ssnx.findById("wnd[1]/tbar[0]/btn[0]").press()
                                elif ssnx.ActiveWindow.Text == 'Warning - Defect Code':
                                    ssnx.findById('wnd[1]/tbar[0]/btn[0]').press()
                                elif ssnx.ActiveWindow.Text == 'Save Incomplete Document':
                                    ssnx.findById("wnd[1]/usr/btnSPOP-VAROPTION1").press()
                                elif ssnx.ActiveWindow.Text == 'Change Initiator':
                                    ssnx.findById("wnd[1]/usr/btnPB_SC").press()
                                elif ssnx.ActiveWindow.Text == 'STOP! Dates Changed -  Click SAVE or  CANCEL':
                                    ssnx.findById("wnd[1]/usr/btnPB_SAVE").press()
                                elif ssnx.ActiveWindow.Text == 'STOP! Unconfirmed Lines - Click SAVE or CANCEL':
                                    ssnx.findById("wnd[1]/usr/btnPB_SAVE").press()
                                elif ssnx.ActiveWindow.Text == 'Requirements/Stocks Individual Customer Order':
                                    ssnx.findById("wnd[1]/tbar[0]/btn[0]").press()
                                else:
                                    q = input('did you save the script for this save pop-up (else)? ')
                            end_time = time.perf_counter()
                            stime = round(end_time - start_time, 0)
                            print(ssnx.findById('wnd[0]/sbar').text)
                            for x, rows in dgrp.iterrows():
                                past_df.loc[x, 'action'] = 'so line ready to be completed'
                                cblock.loc[x, 'action'] = 'so line ready to be completed'
                                wgrp.loc[x, 'action'] = 'so line ready to be completed'
                        dgrp = cblock.query('mfgl == "X" & action == "update delivery and send to mfg"')
                        if len(dgrp) > 0:
                            print(f'so {sox} has lines marked for MFG. Closing without saving changes and sending to MFG.')
                            ssnx.findById('wnd[0]/tbar[0]/btn[3]').press()
                            ssnx.findById("wnd[1]/usr/btnSPOP-OPTION2").press()
                        dgrp = cblock.query('mfgl != "X" & action == "past due process 01"')
                        if len(dgrp) > 0:
                            ssnx.findById('wnd[0]/usr/tabsTAXI_TABSTRIP_OVERVIEW/tabpT\\01').select()
                            print(f'first date: {fstd} and valid delivery date {vdlv} are the same')
                            ssnx.findById('wnd[0]/mbar/menu[1]/menu[1]/menu[0]').select()
                            ssnx.findById('wnd[1]/usr/chkGF_SEL_MVGR3').selected = True
                            ssnx.findById('wnd[1]/usr/chkGF_SEL_GRKOR').selected = True
                            ssnx.findById('wnd[1]/usr/ctxtGF_MVGR3').text = 'D'
                            ssnx.findById('wnd[1]/tbar[0]/btn[7]').press()
                            while ssnx.ActiveWindow.Name == 'wnd[2]':
                                ssnx.findById('wnd[2]/tbar[0]/btn[0]').press()
                            if ssnx.ActiveWindow.Name == 'wnd[0]' and ssnx.ActiveWindow.Text=='SC Standard Order: Availability Control':
                                ssnx.findById("wnd[0]/tbar[1]/btn[18]").press()
                            while ssnx.ActiveWindow.Name == 'wnd[2]':
                                ssnx.findById('wnd[2]/tbar[0]/btn[0]').press()
                            if ssnx.ActiveWindow.Name == 'wnd[0]' and ssnx.ActiveWindow.Text=='SC Standard Order: Availability Control':
                                ssnx.findById("wnd[0]/tbar[1]/btn[18]").press()
                            while ssnx.ActiveWindow.Name == 'wnd[2]':
                                ssnx.findById('wnd[2]/tbar[0]/btn[0]').press()
                            ssnx.findById('wnd[0]/usr/tabsTAXI_TABSTRIP_OVERVIEW/tabpT\\02').select()
                            while ssnx.ActiveWindow.Name == 'wnd[1]':
                                ssnx.findById("wnd[1]/tbar[0]/btn[0]").press()
                            ssnx.findById('wnd[0]/usr/tabsTAXI_TABSTRIP_OVERVIEW/tabpT\\05').select()
                            while ssnx.ActiveWindow.Name == 'wnd[1]':
                                ssnx.findById("wnd[1]/tbar[0]/btn[0]").press()
                            ssnx.findById('wnd[0]/usr/tabsTAXI_TABSTRIP_OVERVIEW/tabpT\\06').select()
                            while ssnx.ActiveWindow.Name == 'wnd[1]':
                                ssnx.findById("wnd[1]/tbar[0]/btn[0]").press()
                            ssnx.findById('wnd[0]/usr/tabsTAXI_TABSTRIP_OVERVIEW/tabpT\\05').select()
                            while ssnx.ActiveWindow.Name == 'wnd[1]':
                                ssnx.findById("wnd[1]/tbar[0]/btn[0]").press()
                            ssnx.findById('wnd[0]/usr/tabsTAXI_TABSTRIP_OVERVIEW/tabpT\\06').select()
                            while ssnx.ActiveWindow.Name == 'wnd[1]':
                                ssnx.findById("wnd[1]/tbar[0]/btn[0]").press()
                            save_changes = 0
                            for x,rows in dgrp.iterrows():
                                sdlx = ssnx.findById(f'{ship_grid}/ctxtRV45A-GRETD[3,0]').text
                                sdlv = datetime.datetime.strptime(sdlx,'%m/%d/%Y')
                                if sdlv == vdlx:
                                    past_df.loc[x, 'fst_try'] = 'yes'
                                    wgrp.loc[x, 'fst_try'] = 'yes'
                                    dgrp.loc[x, 'fst_try'] = 'yes'
                                else:
                                    past_df.loc[x, 'fst_try'] = 'no'
                                    wgrp.loc[x, 'fst_try'] = 'no'
                                    dgrp.loc[x, 'fst_try'] = 'no'
                            save_changes = len(dgrp.query('fst_try == "yes"'))
                            if save_changes == len(dgrp):
                                print(f'so {sox} delivery date(s) have been updated from {cdlv} to {vdlx}')
                                ssnx.findById(ship_grid).verticalScrollbar.position = 0
                                for x, rows in dgrp.iterrows():
                                    rwg = past_df.loc[x, 'saprow']
                                    ssnx.findById(ship_grid).verticalScrollbar.position = rwg
                                    ssnx.findById(ship_grid).getAbsoluteRow(rwg).selected = True
                                ssnx.findById('wnd[0]/mbar/menu[1]/menu[1]/menu[11]/menu[5]').select()
                                ssnx.findById('wnd[1]/tbar[0]/btn[7]').press()
                                start_time = time.perf_counter()
                                ssnx.findById('wnd[0]/tbar[0]/btn[11]').press()
                                while ssnx.ActiveWindow.Name == 'wnd[1]':
                                    if ssnx.ActiveWindow.Text == 'Information':
                                        ssnx.findById("wnd[1]/tbar[0]/btn[0]").press()
                                    elif ssnx.ActiveWindow.Text == 'Warning - Defect Code':
                                        ssnx.findById('wnd[1]/tbar[0]/btn[0]').press()
                                    elif ssnx.ActiveWindow.Text == 'Save Incomplete Document':
                                        ssnx.findById("wnd[1]/usr/btnSPOP-VAROPTION1").press()
                                    elif ssnx.ActiveWindow.Text == 'Change Initiator':
                                        ssnx.findById("wnd[1]/usr/btnPB_SC").press()
                                    elif ssnx.ActiveWindow.Text == 'STOP! Dates Changed -  Click SAVE or  CANCEL':
                                        ssnx.findById("wnd[1]/usr/btnPB_SAVE").press()
                                    elif ssnx.ActiveWindow.Text == 'STOP! Unconfirmed Lines - Click SAVE or CANCEL':
                                        ssnx.findById("wnd[1]/usr/btnPB_SAVE").press()
                                    elif ssnx.ActiveWindow.Text == 'Requirements/Stocks Individual Customer Order':
                                        ssnx.findById("wnd[1]/tbar[0]/btn[0]").press()
                                    else:
                                        q = input('did you save the script for this save pop-up (else)? ')
                                end_time = time.perf_counter()
                                stime = round(end_time - start_time, 0)
                                print(ssnx.findById('wnd[0]/sbar').text)
                                for x, rows in dgrp.iterrows():
                                    past_df.loc[x, 'action'] = 'so line ready to be completed'
                                    cblock.loc[x, 'action'] = 'so line ready to be completed'
                                    wgrp.loc[x, 'action'] = 'so line ready to be completed'
                            elif save_changes > 0 and save_changes < len(dgrp):
                                print(f'so {sox} will require a second pass in order to update\nClosing {sox} without saving changes')
                                ssnx.findById('wnd[0]/tbar[0]/btn[3]').press()
                                ssnx.findById("wnd[1]/usr/btnSPOP-OPTION2").press()
                                for x, rows in dgrp.iterrows():
                                    past_df.loc[x, 'action'] = 'run 2nd time'
                                    cblock.loc[x, 'action'] = 'run 2nd time'
                                    wgrp.loc[x, 'action'] = 'run 2nd time'
                            else:
                                print(f'so {sox} will be updated and sent to mfg for review')
                                ssnx.findById('wnd[0]/tbar[0]/btn[3]').press()
                                ssnx.findById("wnd[1]/usr/btnSPOP-OPTION2").press()
                                for x, rows in dgrp.iterrows():
                                    past_df.loc[x, 'action'] = 'update delivery and send to mfg'
                                    cblock.loc[x, 'action'] = 'update delivery and send to mfg'
                                    wgrp.loc[x, 'action'] = 'update delivery and send to mfg'
                        # had to cut part of the code from this point due to num of characters permitted
                print('Moving on to the next so. first pass')
            except:
                print(f'Error occurred on SO {sox}. Moving on to the next SO')
    except:
        print(f'Script broke on SO {sox} Line {lnx} please review')
        print('Displaying system error:\n', sys.exc_info())
    finally:
        # terminate connection
        ssnx = None
        conx = None
        appx = None
        sapg = None
        print('Processing past due SO lines is done\nTerminating connection to SAP')
anne-petteroe
Community Manager
Community Manager

Hi Jorge,

Thank you for visiting SAP Community to get answers to your questions. Since you're asking a question here for the first time, I recommend that you familiarize yourself with https://community.sap.com/resources/questions-and-answers, as it provides tips for preparing questions that draw responses from our members.

Feel free to take our Q&A tutorial at https://developers.sap.com/tutorials/community-qa.html as well, as that will also help you when preparing questions for the community.

By adding a picture to your profile you encourage your readers to respond.

Kind regards,
Anne

Accepted Solutions (0)

Answers (0)