Quantcast
Channel: SCN : All Content - Scripting Languages
Viewing all 522 articles
Browse latest View live

Display ALV GRID with PHP

$
0
0

Hi

 

it is posible to display a report who use ALV Grid with SAPRFC/PHP on the browser?

 

Thanx for help.

 

Arne


txt Vs ctxt ui element id in VB Script

$
0
0

Hi ,

 

There is one custom program which is used to record through standard GUI Scripting recorder capture the UI Element as below:

 

session.findById("wnd[0]/usr/txtT1").text =  "test"

 

But when the same program transported to different system , then the screen field is capture as :

 

session.findById("wnd[0]/usr/ctxtT1").text =  "test1"

 

So why there is difference in the field element capturing for the same program and same UI field. What is the difference of txt and ctxt id in the VB script?

 

Regards,

Kapil

VBA to SAP Logon - logged in fine, nothing happens after

$
0
0

Hello everyone,

 

I have been trying to start a new SAP session from scratch by calling its API from the Excel VBA. Thanks to this forums I've managed to start a new SAP window, enter my credentials and successfully log in to the system. However, I can only think it is successful because when the credentials are correct, the window disappears and nothing happens after that. If I enter the incorrect credentials, it won't let me through which I understand as a sign that the session is properly connected to the database.

 

Is there any way to force the SAP GUI keep open after I log in? Is it normal that it disappears?

 

The code I use to prompt the logon window:

 

If SapGuiApp Is Nothing Then
    Set SapGuiApp = CreateObject("Sapgui.ScriptingCtrl.1")
End If

If Conn Is Nothing Then
    Set Conn = SapGuiApp.OpenConnectionByConnectionString("mycompanyserver.com", True, False)
End If

If SAPSesi Is Nothing Then
   Set SAPSesi = Conn.Children(0)
End If

 

After that I want to be able to run the macro the following way:

 

With SAPSesi

    .findById("wnd[0]/tbar[0]/btn[12]").press

    .findById("wnd[0]/tbar[0]/okcd").Text = "TRANSACTION"

    .findById("wnd[0]/tbar[0]/btn[0]").press

 

etc.

 

Thank you!

 

Krzysiek

CCo (COM Connector) for SAP NetWeaver RFC Library for Scripting Languages

$
0
0

Hello community,

 

SAP offers different connectors to develop ABAP compatible components and applications. JCo for Java environments, NCo for dotNET languages and the NetWeaver RFC SDK for C++. But what's up if you work neither with Java or dotNET environments nor with C++?

 

Here is another alternative, CCo - the COM Connector for SAP. CCo is a COM library and offers wrappers around all functions of the SAP NetWeaver RFC library. So it is possible to use all functionalities of the SAP NetWeaver RFC library inside any language which support COM technic.

 

With CCo it is easily possible to use the SAP NetWeaver RFC functions inside VBScript, Visual Basic for Applications (VBA) or AutoIt script.

 

Here a VBScript example to connect an SAP system:

 

'-Begin-----------------------------------------------------------------  '-Directives----------------------------------------------------------    Option Explicit  '-Variables-----------------------------------------------------------    Dim SAP, hRFC, rc  '-Main----------------------------------------------------------------    Set SAP = CreateObject("COMNWRFC")    If IsObject(SAP) Then      SAP.About      hRFC = SAP.RfcOpenConnection("ASHOST=ABAP, SYSNR=00, " & _        "CLIENT=001, USER=BCUSER")      If hRFC Then        MsgBox "Check connection with TAC SMGW in the SAP system"        rc = SAP.RfcCloseConnection(hRFC)      End If      Set SAP = Nothing    End If

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

 

Here a VBA example to ping an SAP system:

 

'-Begin-----------------------------------------------------------------  Option Explicit  '-Constants-----------------------------------------------------------    Const RFC_OK = 0  '-Sub Ping------------------------------------------------------------    Sub Ping()      '-Variables-------------------------------------------------------        Dim SAP As CCo.COMNWRFC        Dim hRFC As Long        Dim rc As Integer        Dim hFunc, hFuncDesc As Long      Set SAP = CreateObject("COMNWRFC")      If IsObject(SAP) Then        hRFC = SAP.RFCOPENCONNECTION("ASHOST=ABAP, SYSNR=00, " & _          "CLIENT=001, USER=BCUSER")        If hRFC Then          '-Variant1----------------------------------------------------            hFuncDesc = SAP.RFCGETFUNCTIONDESC(hRFC, "RFC_PING")            If hFuncDesc Then              hFunc = SAP.RFCCREATEFUNCTION(hFuncDesc)              If hFunc Then                If SAP.RFCINVOKE(hRFC, hFunc) = RFC_OK Then                  Debug.Print "Ping successful"                Else                  Debug.Print "Ping not successful"                End If                SAP.RFCDESTROYFUNCTION hFunc              End If            End If          '-Variant2----------------------------------------------------            If SAP.RFCPING(hRFC) = RFC_OK Then              Debug.Print "Ping successful"            Else              Debug.Print "Ping not successful"            End If          rc = SAP.RFCCLOSECONNECTION(hRFC)        End If        Set SAP = Nothing      End If    End Sub

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

 

To the duality of accesses via SAP GUI Scripting and RFC with scripting languages

ScriptStructure1.jpg

 

CCo opens a powerful second channel to communicate with an SAP backend. You can code in your favorite COM-enabled scripting language and use two ways: on the one hand the SAP GUI Scripting to communicate via SAP GUI for Windows with an SAP system, and on the other hand the COM Connector (CCo) to communicate via SAP NetWeaver RFC library with an SAP application server.

CCo is an ideal complementation to SAP GUI Scripting in this application area. You can e.g. use the wide range of thousands of remote-enabled function modules from an SAP system. Use the transaction code BAPI to open the BAPI explorer and find a lot in the alphabetical hierarchy tree.

Enrich your SAP GUI Scripting operation processes. Get information easy and fast via CCo RFC interface in your scripting environment. Combine the best of both worlds.

 

 

Hint: CCo has at the moment experimental character. Don't use it in production environments.

 

Hint: CCo needs SAP RFC SDK, you find it here.

 

Download

You find CCo here: http://cco.stschnell.de

 

 

2014/09/21:

  • Updated Version 1.2 is available.
  • No functional changes, new compilation with advanced header files.
  • Check with actual RFC library patch level 25.
  • Corrected register routine.

 

 

Comments are welcome.

 

Cheers

Stefan

Trouble with PyRFC Table Parameter

$
0
0

When I run this program:

 

from pyrfc import Connection

import sys

 

def main():

    conn = Connection(user='AUSER', passwd='VerySecure', ashost='10.1.2.3', sysnr='00', client='110')

    result = conn.call('RFC_READ_TEXT', TEXT_LINES=[dict( MANDT=u'110',TDOBJECT=u'VBBK', \

                                                                              TDNAME=u'0000110028',TDID=u'0001',TDSPRAS=u'E', \

                                                                              COUNTER=u'000',TDFORMAT=u'*',TDLINE=u'')])

    lines = result['TEXT_LINES']

       

if __name__ == '__main__':

    main()

 

I expect to see 5 lines of text in the TDLINE field (just like in SE37), I only see the one line I am passing with blank TDLINE

 

What am I doing wrong ?

 

Thanks, Ron

Automating Drag and Drop

$
0
0

Hello,

 

Im currently automating a workflow with the help of Script recording.

I have to automate a drag and drop funtionality in this flow. When enabling the Script recording , drag and drop functionality is not working.

Is there any way to overcome this problem? (or) Is any APIs available to use and achieve this functionality by a code program ?

Thanks,

Surya

Python for Basis (Part 2): Scheduling SUIM Jobs using Python

$
0
0

In this post I will document how to schedule batch jobs using python and how to handle the output. You may want to check out my first blog post as an introduction on how to access SAP through Python: Python for Basis (Part 1) .

 

Description of the Scenario

In the following section we want to perform a security assessment by scheduling report RSUSR002 to find out the following:

 

  • Which users have SAP_ALL?
  • Which users are able to execute any function module thanks to S_DEVELOP?

 

That means, we need to accomplish the following tasks:

 

  • Logon to the SAP client we want to evaluate
  • Create a variant for report RSUSR002
  • Schedule report RSUSR002 in the background with immediate start
  • Wait for completion of the job
  • Download the generated spool
  • Extract the users from the downloaded spool
  • Generate an Excel file with the extracted information

 

Extending the PyRFC Connection Class

The easiest way to accomplish our task is to create a subclass of the PyRFC Connection class and add our own functions to it.

 

import pyrfc

class sap_abapclient(pyrfc.Connection):

    def __init__(self, *args, **kwargs ):

        pyrfc.Connection.__init__(self, *args, **kwargs )

        self.condetails=self.get_connection_attributes()

 

Instead of using the standard pyrfc.Connection class to connect to an SAP system we will use our own class. The following sections will document the different functions required to complete the task.

 

Check whether RSUSR002 variant already exists

Before we schedule a RSUSR002 job we need to create or modify a corresponding variant. Since we need to use different function modules for maintenance and creation, we need to check first, whether a variant exists. The following function will take care of this:

 

    def check_if_variant_exists(self, program, variant):

        result = self.call('RFC_READ_TABLE',

                         QUERY_TABLE='VARID', \

                         DELIMITER='|', \

                         FIELDS=[{'FIELDNAME':'VARIANT'}], \

                         OPTIONS = [{'TEXT':"REPORT EQ '" + program.upper()+"'"}])

 

        tabledump=result['DATA']

        variant_exists=False

        for record in tabledump:

            if record['WA']==variant.upper():

                variant_exists=True

        return(variant_exists)

 

The function performs the following:

 

  • Execute function module RFC_READ_TABLE to download the existing variant names of report RSUSR002
  • Initialize the boolean variable variant_exists
  • loop over all records and find out if the variant name we picked already exists.
  • If the variant exists, variant_exists will be set to True
  • At the end the function returns the content of the variant_exists.

 

Create/Maintain RSUSR002 variant

To create a variant we use RS_CREATE_VARIANT_RFC, to modify an existing variant we use RS_CHANGE_CREATED_VARIANT_RFC. The corresponding python function starts with an underscore ('_') which by convention determines that a function should not be called directly. It would be a private method but python doesn't prevent calling these functions directly.

 

If you look at the definition of the function modules then you see several different import parameters. We need the following:

 

  • VARI_DESC: Defines the variant name and will contain the change date and timestamp
  • VARI_CONTENTS: contains the actual variant values
  • VARI_TEXT: Contains the description in the variant attributes

 

VARI_CONTENTS is defined as a table with the following fields that are part of the variant values table when looking at the variant through transaction SE38:

  • SELNAME: Selection Screen
  • KIND: Type
  • OPTION: Option
  • LOW: frm
  • HIGH: to
  • SIGN: I/E

 

The easiest way to get an idea of the variants is to define it in the report itself and then look at the actual values using the variant editor in transaction SE38. Like with all tables, the variant has to be defined as a list of dictionaries. This is the python function to create a create or maintain a variant for RSUSR002:

 

    def _create_suim_variant(self, variant):

        """

        Creates a temporary variant to schedule the report

        :param variant: list of dictionaries that comprise the variant content.

 

        """

        import datetime

        report = u'RSUSR002'

        variantname = u'TEMPVARI'

        vari_text = list()

        vari_list = list()

        vari_contents = list()

        vscreens = list()

 

        temp = dict(MANDT = self.condetails['client'],

                     LANGU=u'EN',

                     REPORT=report,

                     VARIANT=variantname,

                     VTEXT=u'temporary')

 

        vari_text.append(temp)

 

        vari_desc = dict(REPORT = report,

                         VARIANT=  variantname,

                         AEDAT = datetime.date(2013,12,12),

                         AETIME = datetime.time(00,00))

 

        vari_contents.extend(variant)

 

        if self.check_if_variant_exists(report, variantname)==True:

            test = self.call('RS_CHANGE_CREATED_VARIANT_RFC', CURR_REPORT= report,

                                                              CURR_VARIANT= variantname,

                                                              VARI_DESC = vari_desc,

                                                              VARI_CONTENTS = vari_contents,

                                                              VARI_TEXT = vari_text)

        else:

            test = self.call('RS_CREATE_VARIANT_RFC', CURR_REPORT= report,

                                                      CURR_VARIANT= variantname,

                                                      VARI_DESC = vari_desc,

                                                      VARI_CONTENTS = vari_contents,

                                                      VARI_TEXT = vari_text)

 

Schedule report RSUSR002 as Batch Job

To schedule the report in background we will to use the XBP interface (Background Processing, Job Scheduling (BC-XBP). we are going to run the following function modules:

 

  • BAPI_XMI_LOGON: Before we schedule a job we need to register with the instance
  • BAPI_XBP_JOB_OPEN: Initiate the creation of a new job definition
  • BAPI_XBP_JOB_ADD_ABAP_STEP: Define the job step to execute
  • BAPI_XBP_JOB_CLOSE: complete the job creation
  • BAPI_XBP_JOB_START_IMMEDIATELY: Change the job definition for immediate start.
  • BAPI_XMI_LOGOFF: log off from the instance

 

Here is the code:

 

    def schedule_job_immediately(self, jobname, program, variant='none', wait='yes'):

        import datetime

 

        if variant<>'none':

            if self.check_if_variant_exists(program, variant)==False:

                print('Variant Does not Exist')

                exit(3)

 

        result = self.call ('BAPI_XMI_LOGON', EXTCOMPANY='LARS',

                                              EXTPRODUCT='assessment',

                                              INTERFACE='XBP',

                                              VERSION='2.0')

 

        result = self.call('BAPI_XBP_JOB_OPEN', JOBNAME=jobname,

                                                EXTERNAL_USER_NAME='AUDIT')


        jobcount=result['JOBCOUNT']

 

        if variant<>'none':

            result = self.call('BAPI_XBP_JOB_ADD_ABAP_STEP', JOBNAME=jobname,

                                                             JOBCOUNT=jobcount,

                                                             EXTERNAL_USER_NAME='AUDIT',

                                                             ABAP_PROGRAM_NAME=program,

                                                             ABAP_VARIANT_NAME=variant)

        else:

            result = self.call('BAPI_XBP_JOB_ADD_ABAP_STEP', JOBNAME=jobname,

                                                             JOBCOUNT=jobcount,

                                                             EXTERNAL_USER_NAME='AUDIT',

                                                             ABAP_PROGRAM_NAME=program)

 

        result = self.call('BAPI_XBP_JOB_CLOSE', JOBNAME=jobname,

                                                 JOBCOUNT=jobcount,

                                                 EXTERNAL_USER_NAME='AUDIT')

 

        result = self.call('BAPI_XBP_JOB_START_IMMEDIATELY', JOBNAME=jobname,

                                                             JOBCOUNT=jobcount,

                                                             EXTERNAL_USER_NAME='AUDIT')

 

        if wait=='yes':

            jobstatus=self._wait_until_job_completed(jobname,jobcount)

 

        result=dict(JOBCOUNT  = jobcount,

                    JOBSTATUS = jobstatus)

        return(result)

 

 

Wait until Job Completes

The job was started immediately, but before we can download the spool, we need to make sure that the job is really complete. We will use function module SUBST_CHECK_BATCHJOB for this:

 

    def _wait_until_job_completed(self, jobname, jobcount):

        """

        Checks whether a job is still running and waits until it completes.

        :param jobname:

        :param jobcount:

        """

        jobstatus = 'X'

        while jobstatus not in ['F','A']:

            status=self.call('SUBST_CHECK_BATCHJOB',JOBNAME=jobname, JOBCOUNT=jobcount)

            jobstatus=status['JOBSTATUS']

            print ('job running')

            time.sleep(3)

        return(jobstatus)

 

Determine the Spool-ID

The batch job will generate a spool request that is identified by the spool ID. To determine the spool ID we need to check table TBTCP:

 

 

    def determine_spool_id(self, jobname, jobcount):

        """

        find the spool ID based on the job name and job count.

        :param jobname: name of the SM37 job

        :param jobcount: Job Count

        :return:

        """


        where_clause = "JOBNAME EQ '" +jobname+"' AND JOBCOUNT EQ '" + jobcount + "' AND STEPCOUNT EQ '1'"

 

        result = self.call('RFC_READ_TABLE', \

                           QUERY_TABLE='TBTCP', \

                           DELIMITER='|', \

                           FIELDS=[{'FIELDNAME':'LISTIDENT'}], \

                           OPTIONS = [{'TEXT':where_clause}])

 

        tabledump=result['DATA']

        spoolid = tabledump[0]['WA']

        return spoolid

 

Download Spool

After finding out the spool ID we can download the spool into a variable for further analysis:

 

    def download_spool(self, spoolid):

        """

        Download Spool File

        :param spoolid: spool ID of the job

        """

        result = self.call ('BAPI_XMI_LOGON', EXTCOMPANY='linkies',

                                              EXTPRODUCT='assessment',

                                              INTERFACE='XBP',

                                              VERSION='2.0')

        result = self.call('BAPI_XBP_JOB_READ_SINGLE_SPOOL',SPOOL_REQUEST=spoolid,

                                                            EXTERNAL_USER_NAME='AUDIT'

                                                            )

        return(result['SPOOL_LIST_PLAIN'])

 

Extract Users From Spool

The spool file will be a large text stored in a variable. We need to parse the spool file to extract the user information:

 

    def _extract_users_from_spool(self, spoolfile):

        """

        Extracts the users from the spool file generated by SUIM

        :param spoolfile:

        :return: returns a list of dictionaries with the user records.

        """

        import re

        users = list()

        issues = list()

        userrecord = dict()

        for line in spoolfile:

            flatline = line['LINE']

            if flatline<>'':

                if flatline[0]=='|' and flatline[0:7] == '|  User':  

                    linearray=self.locations_of_substring(flatline,'|')

                if flatline[0]=='|' and flatline[0:9] <>'|  User  ' \

                                    and flatline[0:9] <>'|--------' \

                                    and flatline[0:9] <>'|  User n':

                    userrecord=dict(username     = flatline[1:linearray[1]].strip(),

                                    completename = flatline[linearray[1]+1:linearray[2]].strip(),

                                    usergroup    = flatline[linearray[2]+1:linearray[3]].strip(),

                                    accountnumber= flatline[linearray[3]+1:linearray[4]].strip(),

                                    locked       = flatline[linearray[4]+1:linearray[5]].strip(),

                                    reason       = flatline[linearray[5]+1:linearray[6]].strip(),

                                    validfrom    = flatline[linearray[6]+1:linearray[7]].strip(),

                                    validto      = flatline[linearray[7]+1:linearray[8]].strip(),

                                    usertype     = flatline[linearray[8]+1:linearray[9]].strip(),

                                    refuser      = flatline[linearray[9]+1:linearray[10]].strip())

                    if len(linearray)==12:

                        # there is a new policy column with 7.31. That needs to be included

                        userrecord['policy'] = flatline[linearray[10]+1:linearray[11]].strip()

                    if userrecord['reason'] <>'':

                        userrecord['locked']='X'

                    users.append(userrecord)

        return(users)

 

The function uses another function to determine the number of '|' in the first line that contains the headers. We need to add that function to our class, too:

 

    def locations_of_substring(self, string, substring):

        """Return a list of locations of a substring.

        :param substring:

        """

        substring_length = len(substring)

        def recurse(locations_found, start):

            location = string.find(substring, start)

            if location != -1:

                return recurse(locations_found + [location], location+substring_length)

            else:

                return locations_found

        return recurse([], 0)

 

Generate the Excel file with the users

To generate the excel file I will use a different python module that needs to be installed called xlsxwriter (XlsxWriter 0.5.7 : Python Package Index).

 

    def generate_xlsx_file(self, data, filename):

        """

        Generate a XLSX file using returned data

        :param data: data

        aram filename: xlsx filename

        """

 

        import xlsxwriter

        workbook = xlsxwriter.Workbook(filename)

        worksheet = workbook.add_worksheet()

        worksheet.freeze_panes(1,0)

 

        xls_row=0

        xls_column=0

 

        bold = workbook.add_format({'bold': True})

 

        for record in data:

            if len(record.keys())==10:

                if xls_row==0:

                    for i in range(0,9):

                        worksheet.write(xls_row,i,self.columns_10[i],bold)

                        worksheet.set_column(0,0,20)

                        worksheet.set_column(1,1,50)

                    xls_row=1

                else:

                    for i in range(0,9):

                        if i == 0: worksheet.write(xls_row,i,  data['username'])

                        elif i == 1: worksheet.write(xls_row,i,data['completename'])

                        elif i == 2: worksheet.write(xls_row,i,data['usergroup'])

                        elif i == 3: worksheet.write(xls_row,i,data['accountnumber'])

                        elif i == 4: worksheet.write(xls_row,i,data['locked'])

                        elif i == 5: worksheet.write(xls_row,i,data['reason'])

                        elif i == 6: worksheet.write(xls_row,i,data['validfrom'])

                        elif i == 7: worksheet.write(xls_row,i,data['validto'])

                        elif i == 8: worksheet.write(xls_row,i,data['usertype'])

                        elif i == 9: worksheet.write(xls_row,i,data['refuser'])

                    xls_row=xls_row+1

 

            elif len(record.keys())==11:

                if xls_row==0:

                    for i in range(0,10):

                        worksheet.write(0,i,self.columns_11[i],bold)

                        worksheet.set_column(0,0,20)

                        worksheet.set_column(1,1,50)

                    xls_row=1

                else:

                    for i in range(0,10):

                        if   i == 0: worksheet.write(xls_row, i,record['username'])

                        elif i == 1: worksheet.write(xls_row, i,record['completename'])

                        elif i == 2: worksheet.write(xls_row, i,record['usergroup'])

                        elif i == 3: worksheet.write(xls_row, i,record['accountnumber'])

                        elif i == 4: worksheet.write(xls_row, i,record['locked'])

                        elif i == 5: worksheet.write(xls_row, i,record['reason'])

                        elif i == 6: worksheet.write(xls_row, i,record['validfrom'])

                        elif i == 7: worksheet.write(xls_row, i,record['validto'])

                        elif i == 8: worksheet.write(xls_row, i,record['usertype'])

                        elif i == 9: worksheet.write(xls_row, i,record['refuser'])

                        elif i == 10: worksheet.write(xls_row,i,record['policy'])

                    xls_row=xls_row+1

        workbook.close()

 

Combining all functions

The last function will perform all of the previous functions to make the scheduling easier.

 

    def run_suim_job(self,variant, filename):

        """

        run a SUIM report using a single variant

        :param variant: dictionary that contains the variant

        :return:

        """

        self._create_suim_variant(variant)

        result=self.schedule_job_immediately('RSUSR002','RSUSR002','TEMPVARI')

        spoolid=self.determine_spool_id('RSUSR002',result['JOBCOUNT'])

        spoolfile = self.download_spool(int(spoolid))

        users = self._extract_users_from_spool(spoolfile)

        self.generate_xlsx_file(self, users, filename)

 

Putting it all together

 

The entire class would look like this:

 

 

import pyrfc, xlsxwriter

class sap_abapclient(pyrfc.Connection):

    def __init__(self, *args, **kwargs ):

        pyrfc.Connection.__init__(self, *args, **kwargs )

        self.condetails=self.get_connection_attributes()



    def run_suim_job(self,variant, filename):

         ...


    def def generate_xlsx_file(self, data, filename):

         ...


    def locations_of_substring(self, string, substring):

         ...

 

    def _extract_users_from_spool(self, spoolfile):

         ...


    def download_spool(self, spoolid):

         ...


    def schedule_job_immediately(self, jobname, program, variant='none', wait='yes'):

          ...

 

    def check_if_variant_exists(self, program, variant):

          ...


    def _create_suim_variant(self, variant):

         ...


    def _wait_until_job_completed(self, jobname, jobcount):

         ...


    def determine_spool_id(self, jobname, jobcount):

         ...


    def download_spool(self, spoolid):

         ...


Executing the Script

To test the script we need to add some lines to the end of the file to make it actually do something. Otherwise the file would only be a text file that contains a definition of a python class but nothing else. The following construct will execute the script.

 

  • the IF condition will execute the corresponding code underneath
  • several variables will be initialized
  • a connection to the SAP system is initiated using our own subclass that inherited everything from the pyrfc.Connection class.
  • our own functions to schedule RSUSR002 will be executed.

 

If everything works well, we will have two Excel files in our current work directory. The example does not contain any error handling though.

 

if __name__ == '__main__':

     sap_all_variant=[]

        # the next lines contain the data for the variant as stored in parameters.

        tempdict=dict(SELNAME = "PROF1", KIND = "S", OPTION = "EQ", LOW = "SAP_ALL", HIGH = "", SIGN = "I")

        self.variantdict.append(tempdict)


    s_develop_variant=[]

        tempdict=dict(SELNAME = "OBJ1",   KIND = "P",  OPTION = "", LOW = "S_DEVELOP",  HIGH = "", SIGN = "")

        self.variantdict.append(tempdict)

        tempdict=dict(SELNAME = "VAL111", KIND = "P",  OPTION = "", LOW = 'PROG',    HIGH = "", SIGN = "")

        self.variantdict.append(tempdict)

        tempdict=dict(SELNAME = "VAL141", KIND = "P",  OPTION = "", LOW = '03',      HIGH = "", SIGN = "")

        self.variantdict.append(tempdict)


    logon_details = dict( user = <username>,

                          passwd = <secret>,

                         ashost = <hostname>,

                          client = <client>,

                          sysnr = <systemnumber>,

                         sid = <sid> )


    connection=sap_abapclient(**params)

    connection.run_suim_job(sap_all_variant,'sap_all_users.xlsx')

    connection.run_suim_job(s_develop_variant,'s_develop_users.xlsx')


 

This script can be easily extended. You don't need to write things into a excel spreadsheet. You can store things in a database, refresh the data regularly and send an email with changes for example... or generate a nice HTML page using a template engine like jinja2 (Welcome | Jinja2 (The Python Template Engine)), Or you can use the example and write a script that schedules all kinds of basis jobs consistently across an SAP landscape....

PHP: RFC Logon problems

$
0
0

Hey guys,

 

I've done many implementations regarding SAP via RFC in PHP.

 

One stranger problem that I have is that we've created a new CLIENT and I want to connect to it.

 

  1. I've created a brand new user with all the required parameters and authorizations, direct copy from the main client server
  2. I've changed the client number from 200 to 300
  3. PHP extension is installed and it's working with the client 200
  4. My credentials are 100% correct
  5. Everything seems to be okay until the next message

 

Warning: RFC Error Info :
Group : 103
Key : RFC_ERROR_LOGON_FAILURE
Message : Name or password is incorrect (repeat logon)

 

My configuration look like this

 

require_once("sap/saprfc.php");
$login = array (            "ASHOST"    =>  "myIp",            "SYSNR"     =>  "00",            "CLIENT"    =>  "300",            "USER"      =>  "myUser",            "PASSWD"    =>  "myPass",            "LANG"      =>  "EN",            "CODEPAGE"  =>  "1100"
);

 

Any suggestions regarding this weird problem ?

Thank you


Open and LOGON on SAP with Excel Macro

$
0
0

Hi,

 

i am trying to start SAP from excel VBA and input my information, like Log in, user name, password, etc.

 

To sum up, SAP is not open. I want to open it by clicking on the macro it will also input my user name and password into SAP.

 

Here is my coding.


When I click on the macro, its give me the following. (see image).


Any help?


Sub macro2() Dim sapConn As Object Set objshell = CreateObject("WScript.Shell") Set objapp = objshell.Exec("C:\Program Files\SAP\FrontEnd\SAPgui\saplogon.exe") Set sapConn = CreateObject("SAP.Functions") 'Create ActiveX object   sapConn.connection.ApplicationServer = "C:\Program Files\SAP\FrontEnd\SAPgui\saplogon.exe"   sapConn.connection.client = "100" ' only read access   sapConn.connection.user = Environ("USER")   sapConn.connection.Password = "PASSWORD"   sapConn.connection.System = ".VCM Global Production"   sapConn.connection.Language = "EN"   If sapConn.connection.logon(0, False) <> True Then 'Try Logon   MsgBox "Cannot Log on to SAP"   getSAPProjectHours = False   Else      sapConn.connection.Logoff   End If   Set sapConn = Nothing End Sub

Macro said I am log in SAP, but actually not the case...

$
0
0

Hi,

 

I have this macro that work and tell me that i sucessfuly log on in SAP.

 

Dim sapConn As Object 'Declare connection object 'added Set objshell = CreateObject("WScript.Shell") Set objapp = objshell.Exec(Environ("PROGRAMFILES") & "\SAP\FrontEnd\SAPgui\saplogon.exe") Set sapConn = CreateObject("SAP.Functions") 'Create ActiveX object 'Specify user sapConn.Connection.User = "Flie" 'Then password sapConn.Connection.Password = "Mz123" 'Client sapConn.Connection.Client = "100" 'added sapConn.Connection.System = "PVE" 'Target server address sapConn.Connection.ApplicationServer = "10.169.555.233" 'Language code sapConn.Connection.Language = "EN" If sapConn.Connection.Logon(0, True) <> True Then MsgBox "Cannot Log on to SAP" 'Issue message if cannot logon Else MsgBox "Logged on to SAP!" End If

When it open SAP...I still need to click logon and input my password and user name..

 

any clue? It seem there is no conenction between the two

Upload several documents SAP

$
0
0

Hello experts,

I am devolping a code to automate the solped creation process (particulary in proyects) (me51n) however i have reached an impass, because acoording to the enterprice rulebook we must upload: Licitacion basis, planes, formats, and other word files.

Is there a way that I can specify only the folder name and that every file contained is uploaded?


SAP logON connection not found error.

$
0
0

I get SAP Logon connection not found error 1000 when i run this into excel. any help?

 

Set SAPGUIApp = CreateObject("Sapgui.ScriptingCtrl.1")     Set SapGuiConn = SAPGUIApp.OpenConnection(".vcm global production", True)     Set Session = SapGuiConn.Children(0)     Session.TestToolMode = 1         'added part to deal with sap status (open/close)     Set log_opt = Session.FindById("wnd[1]/usr/radMULTI_LOGON_OPT2", False)             If Not log_opt Is Nothing Then         log_opt.Select         Session.FindById("wnd[1]/tbar[0]/btn[0]").Press         End If

EXCEL VBA Vs SAP: Copy text from textbox to LongText in SAP- Hash sign #

$
0
0

After a year hello again.

Im here to ask You for help. Today I hope it is quite simple, but Im stuck...:

 

I have automation on sending data from excel - textbox- to orders LongTexts in -SAP. Im using CO02.

 

Now the problem is when it copy the text into window in SAP it is ok - the same - I save the order change. When I open it again and go to the given longtext, there are many # signs on ends of lines.

I figured out that when it copy data from Textbox to SAP box window - text is the same but there are tabs or spaces on the ends of lines.... when I click on the end of some line, cursor jumps "Tab/Space" after text end. When I delete these spaces, hash signs disappear. The paragraph  function in excel does not shows any spaces.

Hope the problem is described understandable. Can send  screens it would be immediately clear.

 

Can someone propose a formatting to EXCEL BOX text or SAP LONGTEXT window?

 

Thanks in advance.

 

Mirek. 

Order Group import file

$
0
0

Dears,

 

I try to import order group using import option.Could you provide how should look like flat file or something like this ?

How can I do this?

I use KOH1, KOH2, KOH3 transaction.

 

Script Man

 

 

Thanks,

Luc

Message box if sap session is not open

$
0
0

Hi SAP Experts,

 

I am new to SAP Vbscript. I have created a vbscript in SAP. My scripts extract the data from FBL1N and save it into a folder as .xls formate. Before run this VBscript I have to open SAP session.

 

So I would like to edit one message box in to my VBscript. This message box should warn If any user run this Vbscript before opening SAP session.

 

The messaage should be like (Please open SAP Session).

 

Here is my script:-

 

If Not IsObject(application) Then

   Set SapGuiAuto  = GetObject("SAPGUI")

   Set application = SapGuiAuto.GetScriptingEngine

End If

If Not IsObject(connection) Then

   Set connection = application.Children(0)

End If

If Not IsObject(session) Then

   Set session    = connection.Children(0)

End If

If IsObject(WScript) Then

   WScript.ConnectObject session,     "on"

   WScript.ConnectObject application, "on"

End If

session.findById("wnd[0]").maximize

session.findById("wnd[0]/tbar[0]/okcd").text = "fbl3n"

session.findById("wnd[0]").sendVKey 0

session.findById("wnd[0]/usr/ctxtSD_SAKNR-HIGH").setFocus

session.findById("wnd[0]/usr/ctxtSD_SAKNR-HIGH").caretPosition = 0

session.findById("wnd[0]/usr/btn%_SD_SAKNR_%_APP_%-VALU_PUSH").press

session.findById("wnd[1]/usr/tabsTAB_STRIP/tabpSIVA/ssubSCREEN_HEADER:SAPLALDB:3010/tblSAPLALDBSINGLE/ctxtRSCSEL-SLOW_I[1,0]").text = "40305120"

session.findById("wnd[1]/usr/tabsTAB_STRIP/tabpSIVA/ssubSCREEN_HEADER:SAPLALDB:3010/tblSAPLALDBSINGLE/ctxtRSCSEL-SLOW_I[1,1]").text = "40305130"

session.findById("wnd[1]/usr/tabsTAB_STRIP/tabpSIVA/ssubSCREEN_HEADER:SAPLALDB:3010/tblSAPLALDBSINGLE/ctxtRSCSEL-SLOW_I[1,1]").setFocus

session.findById("wnd[1]/usr/tabsTAB_STRIP/tabpSIVA/ssubSCREEN_HEADER:SAPLALDB:3010/tblSAPLALDBSINGLE/ctxtRSCSEL-SLOW_I[1,1]").caretPosition = 8

session.findById("wnd[1]").sendVKey 8

session.findById("wnd[0]/usr/ctxtSD_BUKRS-LOW").text = "2350"

session.findById("wnd[0]/usr/ctxtPA_STIDA").text = '02102014"

session.findById("wnd[0]/usr/ctxtPA_STIDA").setFocus

session.findById("wnd[0]/usr/ctxtPA_STIDA").caretPosition = 10

session.findById("wnd[0]").sendVKey 8

session.findById("wnd[0]/mbar/menu[0]/menu[3]/menu[2]").select

session.findById("wnd[1]/usr/sub:SAPLSPO5:0101/radSPOPLI-SELFLAG[1,0]").select

session.findById("wnd[1]/usr/sub:SAPLSPO5:0101/radSPOPLI-SELFLAG[1,0]").setFocus

session.findById("wnd[1]/tbar[0]/btn[0]").press

session.findById("wnd[1]/usr/ctxtRLGRAP-FILENAME").text = str & "\Consignment dump GP1.XLS"

session.findById("wnd[1]/usr/ctxtRLGRAP-FILENAME").caretPosition = 48

session.findById("wnd[1]").sendVKey 0

 

 

Could you please help on this.

 

Sorry for my poor englsih

 

Thanks & regards,

Pradeep


Script to tell if document has an attachment in SAP

$
0
0

I would like to write a script to check if our MIRO and FB60 documents have an attachment.  I would prefer a system report, but our IT group has not been able to provide this.  I have reverted to writing a script that pulls up each invoice, opens up the attachment list window and then checks to see if there is an attachment.  My script is not great because if there is no attachment, I don't know how to cleanly determine this.  Right now I try to select the first attachment.

 

session.FindById("wnd[1]/usr/cntlCONTAINER_0100/shellcont/shell").selectedRows = "0"

 

If there is no attachment, I get an error message.  In Excel I set up the error handler to jump to a part of the macro that records "no attachment", if there isn't an error message I record "has attachment".

 

Is there a cleaner way to do this?

 

 

Also, I'm checking thousands of these documents and if there is a warning message at the bottom of a window when I pull up the document with FBV3 (document deleted etc) then my macro falls over.  Any ideas on how to handle messages in a general way?

 

Thanks,

Tyler

How to return the window/screen name in GUI scripting

$
0
0

I'm starting out with SAP GUI scripting.  I'm driving the scripts from Excel, which works well.  I haven't found a reference book that explains the objects, methods and properties available in SAP GUI scripting so I do a lot by trial and error, guessing at what I think the property might be.  One of the issues that I have run into is that when I look up a document using FBV3, the resulting screen can be different.  I don't understand what is driving the difference (vendor type, document type, company code ???).  I need to grab a field off of the window, but the field will be referenced different depending on the type of window that come up.

 

Is there a way with GUI script to read the name of the window so that I know which field reference to use to get the field that I want?

 

Thanks,

Tyler

Start recording directly from Excel

$
0
0

Hello!

 

I was thinking of developing a script for developing scripts.. The idea is as follows;

 

A button in a Excel spreadsheet that when you click it, it opens a logged in-session of SAP that already has started recording.

 

And to the problem... I tried finding the Alt+F12 menu via the wizard but as it turns out, that is about the only button that does not have an ID. I also tried to record while doing stuff in that menu but the script does not capture that.

 

Anyone here got a clue if this is possible in some other way without using some kind on third-party software?

 

BR and thanks, Mattias.

SAP GUI Scripting trying to paste screenshot of SAP to excel sheet(HardcopyToMemory)

$
0
0

Dear Experts,

 

I have been trying to access the clipboard for screenshot of SAP copied through "session.findById("wnd[0]").HardcopyToMemory" and pasting the same in an Excel Sheet.

 

I have been trying the same for last two weeks unsuccessfully.

 

Requesting for your Kind help if someone have already addressed this issue.

 

Please let me know if i have to furnish some more details..

 

Regards,

Kumar Santharam

Multi-threaded scripts for SAP?

$
0
0

We attach scans of invoices to our AP documents (MIRO and FB60s).  We have to check these documents on payment and it is taking a long time because the script we are using pauses as SAP pulls up the document in an outside viewer application.  Is it possible to have the script continue processing while the  scanned document is being pulled up so that by the time the user reviews the attached document, the next one has been pulled up and is ready to be reviewed?


I would like to run this out of Excel, but could do it in another program as well.


I tried to accomplish this by opening a second version of Excel and accessing a second session in SAP, but I couldn't get SAP to allow a link to the second Excel version.

 

Thank you,

Tyler

Viewing all 522 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>