Jump to content
Sign in to follow this  
StSchnell

How to Integrate AutoIt Inside SAPs Programming Language ABAP

Recommended Posts

StSchnell

Hello community,

here is my script integration library ScriptX. With this library is it very easy possible to integrate AutoIt inside SAPs programming language ABAP.

Here an ABAP example:

"-Begin-----------------------------------------------------------------
  Program ZSCRIPTX.

    "-Constants---------------------------------------------------------
      Constants CrLf(2) Type c Value %_CR_LF.
      Constants SW_SHOWNORMAL Type i Value 1.

    "-Variables---------------------------------------------------------
      Data oScriptX Type OLE2_OBJECT.
      Data Buffer Type String Value ''.
      Data WorkDir Type String Value ''.
      Data FileName Type String Value ''.
      Data rc Type i Value 0.

    "-Macros------------------------------------------------------------
      Define _.
        Concatenate Buffer &1 CrLf Into Buffer.
      End-Of-Definition.

      Define Flush.
        Call Function 'AC_SYSTEM_FLUSH' Exceptions Others = 1.
      End-Of-Definition.

    "-Main--------------------------------------------------------------
      Create Object oScriptX 'ScriptX'.
      If sy-subrc <> 0 Or  oScriptX-Handle = 0 Or oScriptX-Type <> 'OLE2'.
        Call Function 'ZSCRIPTXDLL'.
        Create Object oScriptX 'ScriptX'.
      EndIf.

      If sy-subrc = 0 And oScriptX-Handle > 0 And oScriptX-Type = 'OLE2'.

        Call Method Of oScriptX 'About'.
        Flush.

        Call Function 'ZAUTOIT3EXE'.

"-AutoIt Script begin---------------------------------------------------

  _ 'MsgBox(0, "AutoIt", "Version " & @AutoItVersion)'.

"-AutoIt Script end-----------------------------------------------------

        Call Method cl_gui_frontend_services=>get_sapgui_workdir
          Changing SAPWORKDIR = WorkDir Exceptions Others = 1.
        Concatenate WorkDir '\Version.au3' Into FileName.
        Flush.

        Call Method Of oScriptX 'WriteFile' Exporting #1 = FileName
          #2 = Buffer.
        Flush.

        Call Method Of oScriptX 'Shell' = rc Exporting
          #1 = 'AutoIt3.exe' #2 = 'Version.au3' #3 = SW_SHOWNORMAL
          #4 = 1.
        Flush.

        Free Object oScriptX.
      EndIf.

"-End-------------------------------------------------------------------

Good integration.

Cheers

Stefan

Edited by StSchnell
  • Like 1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Similar Content

    • PauloRodrigues
      By PauloRodrigues
      I need to select an item from a SAP combobox, could anyone help me or did something like that? I tried to use some AutoIt functions but without success.
      When i try to identify the combobox with au3Info, this is the return:


      Could anyone help me with this challange?
    • StSchnell
      By StSchnell
      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 is COM-enabled, like AutoIt. With CCo it is easily possible to use the SAP NetWeaver RFC functions inside AutoIt.
      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, SAP passport required.
      You find CCo here: cco.stschnell.de
      You find a few examples how to use CCo here, in particular three examples in AutoIt Script how to call BAPI functions - here BAPI_USER_ * functions.
      Cheers
      Stefan
    • StSchnell
      By StSchnell
      Hello community,

      here is an example code of a server application for an SAP system in AutoIt language.

      My problem is, that this AutoIt example crashs after the first function call of ABAPCall from an ABAP report.

      I try two methods:
      Use DllCallbackGetPtr Use CreateThread and get the address of the thread. But both methods crashs at the same code position, look at the example below.
      Is there any other way to use this kind of multithreading?

      Thanks for hints.

      Cheers
      Stefan


      ;-Begin----------------------------------------------------------------- ;-Directives---------------------------------------------------------- AutoItSetOption("MustDeclareVars", 1) ;-Constants----------------------------------------------------------- Const $RFC_OK = 0 Const $RFC_RETRY = 14 ;-Variables----------------------------------------------------------- Dim $SAP, $ABAPCall, $ptrABAPCall, $hDesc, $conPar[3] Dim $ptrConPar[3], $ConParPtr, $i, $rc, $hCon ; Dim $hThread ;-Function CreateThread----------------------------------------------- Func CreateThread($Handle) Local $Ret $Ret = DllCall("kernel32.dll", "handle", "CreateThread", "ptr", 0, _ "dword", 0, "long", DllCallbackGetPtr($Handle), "ptr", 0, _ "long", 0, "int*", 0) Return $Ret[0] EndFunc ;-Function GetThreadAddr---------------------------------------------- Func GetThreadAddr($hThread) Local $ThreadAddr = DllStructCreate("ptr") DllCall("NTDLL.dll", "long", "NtQueryInformationThread", _ "handle", $hThread, "long", 9, "ptr", _ DllStructGetPtr($ThreadAddr), "ulong", 4, "ulong*", 0) Return Number(DllStructGetData($ThreadAddr, 1)) EndFunc ;-Function OutputDebugString------------------------------------------ Func OutputDebugString($OutputString) Local $strOut = String($OutputString) DllCall("kernel32.dll", "none", "OutputDebugStringW", "wstr", _ $strOut) EndFunc ;-Function ABAPCall--------------------------------------------------- Func ABAPCall() MsgBox(0, "", "Ja") Return $RFC_OK ;-Important hint-------------------------------------------------- ;- ;- Program crashs here, because AutoIt is not able to use multi ;- threading with SAP NetWeaver RFC library ;- ;----------------------------------------------------------------- EndFunc ;-Main---------------------------------------------------------------- $SAP = ObjCreate("COMNWRFC") If IsObj($SAP) Then $ABAPCall = DllCallbackRegister("ABAPCall", "long", "") $hDesc = $SAP.RfcCreateFunctionDesc("ABAPCall") If $hDesc And $ABAPCall Then ;-Define RFC_CONNECTION_PARAMETER structures-------------------- For $i = 0 To 2 $conPar[$i] = DllStructCreate("wchar name[16];wchar value[16]") Next ;-Set RFC_CONNECTION_PARAMETER---------------------------------- DllStructSetData($conPar[0], "name", "program_id") DllStructSetData($conPar[0], "value", "AUTOITSERVER") DllStructSetData($conPar[1], "name", "gwhost") DllStructSetData($conPar[1], "value", "ABAP") DllStructSetData($conPar[2], "name", "gwserv") DllStructSetData($conPar[2], "value", "sapgw00") ;-Switch RFC_CONNECTION_PARAMETER strings to pointers----------- $ptrConPar = DllStructCreate("ptr;ptr;ptr;ptr;ptr;ptr") DllStructSetData($ptrConPar, 1, DllStructGetPtr($conPar[0], "name")) DllStructSetData($ptrConPar, 2, DllStructGetPtr($conPar[0], "value")) DllStructSetData($ptrConPar, 3, DllStructGetPtr($conPar[1], "name")) DllStructSetData($ptrConPar, 4, DllStructGetPtr($conPar[1], "value")) DllStructSetData($ptrConPar, 5, DllStructGetPtr($conPar[2], "name")) DllStructSetData($ptrConPar, 6, DllStructGetPtr($conPar[2], "value")) $ptrABAPCall = Number(DllCallbackGetPtr($ABAPCall)) ;-Alternative----------------------------------------------------------- ; ; $hThread = CreateThread($ABAPCall) ; If $hThread Then ; $ptrABAPCall = GetThreadAddr($hThread) ; If $ptrABAPCall Then ; ;----------------------------------------------------------------------- $rc = $SAP.RfcInstallServerFunction("", $hDesc, $ptrABAPCall) If $rc = $RFC_OK Then $ConParPtr = Number(DllStructGetPtr($ptrConPar)) $hCon = $SAP.RfcRegisterServer($ConParPtr, 3) If $hCon Then While $rc = $RFC_OK Or $rc = $RFC_RETRY $rc = $SAP.RfcListenAndDispatch($hCon, 1) Select Case $rc = $RFC_OK OutputDebugString("RFC_OK") Case $rc = $RFC_RETRY OutputDebugString("RFC_RETRY") EndSelect Sleep(256) Wend EndIf EndIf $SAP.RfcDestroyFunctionDesc($hDesc) DllCallbackFree($ABAPCall) ; DllCall("kernel32.dll", "boolean", "CloseHandle", _ ; "handle", $hThread) ; EndIf ; EndIf EndIf $SAP = 0 EndIf ;-End-------------------------------------------------------------------
    • Bennet
      By Bennet
      I'm actually really proud of myself today. I'm always keen on using AutoIT wherever I can, as I've been developing in it since the age of 14 and whenever I meet any new technical staff or developers at the different clients I visit it always gets a mention and a demonstration. So we had a minor problem today at one of our clients, whereby they had an existing Windows Service implemented with a config file but the source-code was missing, which limited the ability of our company to enhance the interface in any way.

      Now considering the fact that I was paid to develop this I will refrain from divulging any company names or "secrets" as, of course, there are clauses in my contract that state that my work belongs to them. I am however a SAP ABAP developer by trade so anything that falls outside of the defined limits of this trade I can technically share, but regardless I'll keep the information limited.

      So the requirement was to pull data from IBM Websphere, write it out to a file and post it into SAP through a custom built RFC. It turned out to be much less complicated than I imagined and through the research on these forums, I had discovered that similar things had been attempted but that nothing concrete had been written for AutoIT specifically (The MQ part, not the SAP part). So without further adieu I present my thinking.

      I started out with the IBM Websphere dll using DllOpen and DllCall. After a few frustrating attempts at creating COM objects through the DLL Call. I finally discovered that there was another dll that I could register using regsrv32. It was called MQAX200.dll

      Once this dll was registered on the system I could access the following piece of code;



      EnvSet("MQSERVER", $iniServer) ;MQ Server Environment Variable $MQSess = ObjCreate("MQAX200.MQSession") $QMgr = ObjCreate("MQAX200.MQQueueManager") $QMgr = $MQSess.AccessQueueManager($iniQM) ;Queue Manager ConsoleWrite("Connected" & @CRLF)
      After this was complete and I successfully tested my connection I added the following to read from MQ;


      $Queue = $QMgr.AccessQueue($iniQueue, 2) ;Queue (2=MQOO_INPUT, 16=MQOO_OUTPUT) While 1 $GetMsg = $MQSess.AccessMessage $GetOptions = $MQSess.AccessGetMessageOptions $Queue.Get($GetMsg, $GetOptions) If $Queue.ReasonCode = 2033 Then ;When there aren't any new messages sleep for 2 seconds. Sleep(2000) Else #EndRegion Accessing MQ #Region Write File $MsgData = $GetMsg.MessageData ....
      I then wrote this out to a file and attempted my SAP connection using the following code;


      Dim $LoggedIn = False $oConnection = $LogonControl.NewConnection $oConnection.System = $System $oConnection.ApplicationServer = $AppServer $oConnection.SystemNumber = $SysNumb $oConnection.User = $User $oConnection.Password = $Password $oConnection.Client = $Client $oConnection.Language = $Language $LoggedIn = $oConnection.Logon(0, True) Return $LoggedIn
      which resulted in failure as the SAP COM object wasn't registered on the system. After attempting to register the correct object without installing SAP GUI, I ended up with a slightly different solution for an executable supplied by SAP called startrfc.exe;


      $foo = Run(@ComSpec & " /c " & $RFCExec & " -3 -h " & $AppServer & " -s " & $SysNumber & " -F " & $RFC & " -u " & $User & " -p " & $Password & " -c " & $Client & " -l " & $Language & " -E FNAME=" & $FilePath & " -E PNAME=" & $Program, "", @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD) While 1 $line = StdoutRead($foo) If @error Then ExitLoop ConsoleWrite($line) $LogFile = FileOpen(StringReplace($FilePath, "\In\","\Logs\"), 2) FileWrite($LogFile, $Line) FileClose($LogFile) FileMove($FilePath, StringReplace($FilePath, "\In\","\Out\")) WEnd While 1 $line = StderrRead($foo) If @error Then ExitLoop ConsoleWrite($line) $ErrFile = FileOpen(StringReplace($FilePath, "\In\","\Errors\E"), 2) FileWrite($ErrFile, $Line) FileClose($ErrFile) FileMove($FilePath, StringReplace($FilePath, "\In\","\Errors\")) WEnd

      One last piece of code that you should keep in mind if you attempt this so that your program doesn't stop when a COM error is returned (MQ returns an error that indicates there is no data available on the queue as you see with the reason code check earlier);


      Global $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc") ;Catch COM errors
      In conclusion, I really enjoyed implementing something that'll be used for the foreseeable future at a powerful company and writing it in my favorite language. I hope you find some use in these snippets.

      This will be running as a Windows Service from now on using srvany.exe.
    • ozmike
      By ozmike
      here is a SAP hit tool ( like the SAP wizard) for anyone doing SAP automation windows 7.

      This lets you click on a control on any SAP GUI and highlights
      it just like the wizard did and tells you the control path.

      The SAP wizard has problems on windows 7 due to it use of Office Assistants Agents (remember Clippy?) which are no longer supported in windows 7.

      Note, GUI Scripting needs to be turned on see your system admin (or see transaction rz11 to turn on)

      Enjoy

      For general SAP automation see
      griffin the great's SAP.UDF

      tags SAP GUI scripting wizard not working
      SAPWizard.zip
×