Quantcast
Channel: SCN : Document List - Scripting Languages
Viewing all 100 articles
Browse latest View live

Tip: How to Code a GuiXT Conformable Dynamic Link Library (DLL)

$
0
0


Hello community,

 

I show here an example how to call the Windows API function ShellExecute inside a GuiXT script. You can call a DLL function with the command Call, look here for the technical documentation. And now I show an example, how to code your own dynamic link library (DLL) with FreeBASIC to use it inside a GuiXT script.

 

As you can see, in the section "Calling a dll function" in the technical documentation from Synactive, the Call function from GuiXT needs only pointer to strings as input and output arguments. With this knowledge I implement a DLL in FreeBASIC with one export function expMsgBox. These export function has only string arguments, two input and one output. Inside the export function I call a simple MessagBox function with the input parameters. The result of the MessageBox function I convert to a string and put it to the output argument.


'-Begin-----------------------------------------------------------------
'-
'- FreeBasic Dynamic Link Library (DLL) for GuiXT
'- Compile it with -dll option.
'-
'- Author: Stefan Schnell
'-
'-----------------------------------------------------------------------

 

  '-Includes------------------------------------------------------------
    #Include Once "windows.bi"

 

  Extern "Windows-MS"

 

    '-Function expMsgBox------------------------------------------------
      Function expMsgBox Alias "expMsgBox" (ByVal inMsg As String, _
        ByVal inTitle As String, ByVal outRes As String) As Long Export

 

        '-Variables-----------------------------------------------------
          Dim resMsgBox As Long

 

        resMsgBox = MessageBox(NULL, inMsg, inTitle, MB_YESNOCANCEL)
        outRes = Str(resMsgBox)
        expMsgBox = resMsgBox

 

      End Function

 

  End Extern

 

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

 

 

I call this DLL function from GuiXT with the following script:


//-Begin----------------------------------------------------------------

 

  Call "expMsgBox" dll="FreeBasic.dll" In="Hello World" In="GuiXT" Out="res"
  Message "&[res]"

 

//-End------------------------------------------------------------------

 

 

It works perfect with GuiXT.

msgbox.JPG

 

result.JPG

 

With this possibility you can combine the power of GuiXT script with the power of FreeBASIC. GuiXT is standard part of the SAP GUI for Windows installation and FreeBASIC is a free/open source compiler.

 

15/11/25 Addition

This example above is originated with FreeBasic 0.90. With higher compiler versions the example don't work anymore, so it is not recommended. Here an equivalent PureBasic example:

 

; Begin-----------------------------------------------------------------

;

; PureBasic Dynamic Link Library (DLL) for GuiXT

;

; Author: Stefan Schnell

;

; ----------------------------------------------------------------------

 

  ; Function expMsgBox--------------------------------------------------

    ProcedureDLL.i expMsgBox(inMsg.s, inTitle.s, *outRes)

 

      ; Variables-------------------------------------------------------

        Protected resMsgBox.i

 

      resMsgBox = MessageRequester(inTitle, inMsg, #PB_MessageRequester_YesNoCancel)

      PokeS(*outRes, Str(resMsgBox))

      ProcedureReturn resMsgBox

 

    EndProcedure

 

; End-------------------------------------------------------------------

 

Cheers

Stefan


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

scriptingstructure.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

 

2015/12/06

  • An update is available.
  • Add the property UsePwdRequest to disable the password requester in the case of using SAPNWRFC.INI via DEST connection parameter or the using of MYSAPSSO2 connection parameter.

 

2015/11/20

  • New Version 1.7 is available.
  • Externalization of the routine to register the library without admin rights as script, because this function doesn't work with Windows 10.
  • Checked with Windows 10 x64.
  • Checked with actual RFC library patch level 38.

 

2015/01/01

  • New Version 1.5 is available.
  • It includes now for arguments by reference a set of typed attributes, e.g. lngByRef for a long variable by reference. This attributes gets and sets the arguments by reference, on any method with a corresponding in and out argument.
  • So it is now possible to use CCo with JavaScript inside IE11 in edge mode, to use it in UI5 environments. New examples are included.
  • Also you can use CCo on the same way with PowerShell. New examples are included.
  • CCo is now backwards compatible, the new SAP functions since the first PL - implemented in version 1.4 - doesn't create an error message at the creation of the instantiation.
  • Checked with actual RFC library patch level 33.

 

2014/12/21:

  • New Version 1.4 is available.
  • Implementation of the functions RfcAppendNewRows, RfcGetRowType, RfcLanguageIsoToSap, RfcLanguageSapToIso and RfcSetCpicTraceLevel - Hint: From this point CCo is not backward compatible, use always the actual SAP NetWeaver RFC library.
  • New examples to create SAP server applications - synchronous and asynchronous.
  • New interprocess communication functions (IPC) to enable implementation of other processes.

 

2014/12/11:

  • Updated Version 1.3 is available.
  • No functional changes, only a few interface changes in the context of bgRFC calls.
  • Many new examples, e.g. VBScript BAPI examples, t/qRFC and bgRFC examples.
  • Checked with actual RFC library patch level 31.
  • Corrected register routine.

 

2014/09/21:

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

 

 

Comments are welcome.

 

Cheers

Stefan

How to use Freestyle BASIC Script Language (FBSL) inside ABAP

$
0
0

Hello community,


in this forum we only discus how to connect SAP from different scripting languages. We never talk about the possibility how to use a scripting language from the SAP side. I published a little bit in 2009 about this theme in my blog with AutoItX. But AutoItX, the ActiveX component of Autoit, is, compared with AutoIt, restricted in its functionality. Now from this point I want to introduce another brilliant script language: Freestyle BASIC Script Language.

 

Freestyle BASIC Script Language (FBSL) is a multi-syntax all-in-one high-level language (HLL) development environment. Its interpretative layer is a vastly extended superset of traditional BASIC that targets seamless integration of FBSL applications with Windows API and third-party dynamic link libraries. Its integrated Dynamic Assembler and Dynamic C JIT compiler layers enable the user to interleave BASIC code with verbatim Intel-style assembly and ANSI C, respectively. You could it find FBSL here, but the domain is not reachable (2016/01/22).

 

To use FBSL inside ABAP I build an ActiveX library, called FBSLX. FBSLX contains wrapper functions around the library FBSL.dll. With FBSLX you have the possibility to use FBSL inside any language which is COM-enabled, also ABAP. The integration of FBSL insisde ABAP offers inter alia the possibilities to use on the presentation server easily

  • API/DLL functions,
  • a console window for input and/or output,
  • a GUI window,
  • memory functions,
  • memory map files for interprocess communication (IPC),
  • etc. etc. etc.

 

Here an example how easy it is to use FBSL inside ABAP:

 

"-Begin-----------------------------------------------------------------
  Program ZFBSL.

 

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

 

    "-Variables---------------------------------------------------------
      Data oFBSL Type OLE2_OBJECT.
      Data Buffer Type String Value ''.
      Data rc Type i.
      Data RetVal Type i.

 

    "-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 oFBSL 'FbslX'.

      If sy-subrc <> 0 Or  oFBSL-Handle = 0 Or oFBSL-Type <> 'OLE2'.
        CallFunction'ZFBSL_WININC'.
        Call Function 'ZFBSL_DLL'.

        Call Function 'ZFBSLX'.
        Create Object oFBSL 'FbslX'.
      EndIf.

 

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

 

        CallMethodcl_gui_frontend_services=>get_sapgui_workdir
          ChangingSAPWORKDIR=WorkDirExceptionsOthers=1.
        Concatenate'#Include "'WorkDir'\Windows.inc"'IntoWinInc.

 

"-FBSL script begin-----------------------------------------------------

 

_ WinInc
_ '#Option Strict'.
_ '#AppType GUI'.

 

_ 'Dim %rc'.
_ 'rc = Msgbox(Null, "Message", "Title", MB_ABORTRETRYIGNORE)'.
_ 'Return rc'.

 

"-FBSL script end-------------------------------------------------------

 

        "-Here we execute the script------------------------------------
          Call Method Of oFBSL 'ExecuteScriptBuffer' = rc
            Exporting #1 = Buffer.
          Flush.

 

        "-Here we get the return value of the script--------------------
          Call Method Of oFBSL 'GetReturnValueInteger' = RetVal.
          Flush.

 

        Write: RetVal.

 

        Free Object oFBSL.

      EndIf.

 

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

 

FBSL offers a lot of new possibilities to integrate the presentation server in the context of ABAP on the application server. To implement FBSL complete in the ABAP context I use BinFile2ABAP, it works excellent.

 

Further links:

  • Here an experimental ABAP code, how to use ANSI C code inside ABAP via this FBSL environment and here an example how to use C code inside ABAP.
  • Here an ABAP code, how to use a drop zone.
  • Here a FBSL code, how to create an SAP server application.

 

Update 2014/10/11

  • FBSLX is outdated now, an new library, called ScriptX, replaces FBSLX.

 

Teapot.JPG

 

Here another example which shows  a Mandelbrot benchmark test with FbslX and FBSL inside ABAP.

 

zMandelbrot.jpg

 

Comments are welcome.

 

Enjoy it.

 

Cheers
Stefan

How to use Freestyle BASIC Script Language (FBSL) with SAP GUI Scripting

$
0
0

Hello community,

 

Freestyle BASIC Script Language (FBSL - but the domain is not reachable [2016/01/22]) is a true multitalent. It is possible to use it inside ABAP, to build client and server applications and to use it with SAP GUI Scripting, as the example here shows. It is only a simple logon, but it shows how to use FBSL in this case.


//-Begin----------------------------------------------------------------

 

  //-Directives---------------------------------------------------------
    #AppType Console
    #Option Strict

 

  //-Includes-----------------------------------------------------------
    #Include <Windows.inc>
 
  //-Main---------------------------------------------------------------
    Sub Main()

 

      //-Variables------------------------------------------------------
        Dim %SAPROTWrapper, %SapGuiAuto, %application, %connection
        Dim %session

 

      SAPROTWrapper = CreateObject("SapROTWr.SapROTWrapper", "")
      If Not SAPROTWrapper Then
        ExitProgram
      End If

 

      SapGuiAuto = GetValue("%o", SAPROTWrapper, ".GetROTEntry(%s)", _
        "SAPGUI")
      If Not SapGuiAuto Then
        ExitProgram
      End If

 

      application = GetValue("%o", SapGuiAuto, ".GetScriptingEngine")
      If Not application Then
        ExitProgram
      End If

 

      connection = GetValue("%o", application, ".Children(%d)", 0)
      If Not connection Then
        ExitProgram
      End If

 

      session = GetValue("%o", connection, ".Children(%d)", 0)
      If Not session Then
        ExitProgram
      End If

 

      PutValue(session, ".findById(%s).text = %s", _
        "wnd[0]/usr/txtRSYST-MANDT", "001")
      PutValue(session, ".findById(%s).text = %s", _
        "wnd[0]/usr/txtRSYST-BNAME", "BCUSER")
      PutValue(session, ".findById(%s).text = %s", _
        "wnd[0]/usr/pwdRSYST-BCODE", "minisap")
      PutValue(session, ".findById(%s).text = %s", _
        "wnd[0]/usr/txtRSYST-LANGU", "EN")
      CallMethod(session, ".findById(%s).sendVKey %d", _
        "wnd[0]", 0)

 

      ReleaseObject(SAPROTWrapper)

 

    End Sub

 

//-End------------------------------------------------------------------

 

FBSL can compile scripts to executable. On this way you can deliver your SAP GUI script to any target computer on Windows platform, without any dependencies.

 

Good Scripting.

 

Cheers

Stefan

How to use actual SAP NetWeaver RFC Library with Python - Call ABAP Report

$
0
0

Hello community,

 

I presented until now in the series "How to use actual SAP NetWeaver RFC Library with Python":

 

 

Here now an example how to execute an ABAP report and get the result back.

 

At first a very easy ABAP report:

 

"-Begin-----------------------------------------------------------------

  Program Z_TEST.

 

    Write: / 'Hello World'.

 

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

 

 

Now we need an RFC-enabled function module, which wraps the execution of the ABAP report and delivers the result back. We call the report via SUBMIT with the addition EXPORTING LIST TO MEMORY. Therewith the result of the report is put into memory. With the function modules LIST_FROM_MEMORY we get the list and with the function module LIST_TO_ASCI we convert it into a readable format.

 

FUNCTION Z_TEST.

*"----------------------------------------------------------------------

*"*"Local Interface:

*"  EXPORTING

*"     VALUE(E_TAB_LISTZEILE) TYPE  Z_TAB_LISTZEILE

*"----------------------------------------------------------------------

*" Z_TAB_LISTZEILE is a Table Type with the Line Type LISTZEILE

**----------------------------------------------------------------------

 

  DATA lt_abaplist TYPE STANDARD TABLE OF abaplist.

  DATA lt_listzeile TYPE STANDARD TABLE OF listzeile.

 

  SUBMIT z_test EXPORTING LIST TO MEMORY AND RETURN.

 

  CALL FUNCTION 'LIST_FROM_MEMORY'

    TABLES

      listobject = lt_abaplist

    EXCEPTIONS

      not_found  = 1

      OTHERS     = 2.

  IF sy-subrc = 0.

 

    CALL FUNCTION 'LIST_TO_ASCI'

      TABLES

        listasci = lt_listzeile

        listobject = lt_abaplist

      EXCEPTIONS

        Others     = 1.

    IF sy-subrc = 0.

      e_tab_listzeile = lt_listzeile.

    ENDIF.

 

  ENDIF.

 

ENDFUNCTION.

 

 

On this way it is possible to call this ABAP report via RFC from Python. We set the connection parameters, open a connection, get the function description from Z_TEST function module, create a function and invoke it. Now we get the result from E_TAB_LISTZEILE and print it line by line.

 

# -*- coding: iso-8859-15 -*-

#-Begin-----------------------------------------------------------------

 

#-Include---------------------------------------------------------------

FileName = "sapnwrfc.py"

exec(compile(open(FileName).read(), FileName, "exec"))

 

#-Sub Main--------------------------------------------------------------

def main():

 

  #-Connection parameters-----------------------------------------------

  RfcConnParams[0].name = "ASHOST"; RfcConnParams[0].value = "ABAP"

  RfcConnParams[1].name = "SYSNR" ; RfcConnParams[1].value = "00"

  RfcConnParams[2].name = "CLIENT"; RfcConnParams[2].value = "001"

  RfcConnParams[3].name = "USER"  ; RfcConnParams[3].value = "BCUSER"

  RfcConnParams[4].name = "PASSWD"; RfcConnParams[4].value = "minisap"

 

  hRFC = SAP.RfcOpenConnection(RfcConnParams, 5, RfcErrInf)

  if hRFC is not None:

 

    charBuffer = create_unicode_buffer(256 + 1)

 

    hFuncDesc = SAP.RfcGetFunctionDesc(hRFC, "Z_TEST", RfcErrInf)

    if hFuncDesc != 0:

      hFunc = SAP.RfcCreateFunction(hFuncDesc, RfcErrInf)

      if hFunc != 0:

        if SAP.RfcInvoke(hRFC, hFunc, RfcErrInf) == RFC_OK:

 

          hTable = c_void_p(0)

          if SAP.RfcGetTable(hFunc, "E_TAB_LISTZEILE", hTable, \

            RfcErrInf) == RFC_OK:

 

            RowCount = c_ulong(0)

            rc = SAP.RfcGetRowCount(hTable, RowCount, RfcErrInf)

            rc = SAP.RfcMoveToFirstRow(hTable, RfcErrInf)

            for i in range(0, RowCount.value):

              hRow = SAP.RfcGetCurrentRow(hTable, RfcErrInf)

              rc = SAP.RfcGetChars(hRow, "ZEILE", charBuffer, 256, \

                RfcErrInf)

              print(charBuffer.value.rstrip())

              if i < RowCount.value:

                rc = SAP.RfcMoveToNextRow(hTable, RfcErrInf)

 

        rc = SAP.RfcDestroyFunction(hFunc, RfcErrInf)

 

    rc = SAP.RfcCloseConnection(hRFC, RfcErrInf)

 

  else:

    print(RfcErrInf.key)

    print(RfcErrInf.message)

 

#-Main------------------------------------------------------------------

if __name__ == "__main__":

  main()

 

#-End-------------------------------------------------------------------

 

001.jpg

 

Now you can easily use e.g. the report RSUSR002 - swap only the report names in the function module.

002.jpg

 

Here now a tiny addendum to fill the select options of the report RSUSR002.

 

At first the function module. I changed the interface, I add I_TAB_RSPARAMS and I add WITH SELECTION-TABLE to the SUBMIT command:

 

FUNCTION Z_TEST.

*"----------------------------------------------------------------------

*"*"Local Interface:

*"  IMPORTING

*"     VALUE(I_TAB_RSPARAMS) TYPE  RSPARAMS_TT OPTIONAL

*"  EXPORTING

*"     VALUE(E_TAB_LISTZEILE) TYPE  Z_TAB_LISTZEILE

*"----------------------------------------------------------------------

 

  DATA lt_abaplist TYPE STANDARD TABLE OF abaplist.

  DATA lt_listzeile TYPE STANDARD TABLE OF listzeile.

 

  SUBMIT rsusr002 WITH SELECTION-TABLE i_tab_rsparams

    EXPORTING LIST TO MEMORY AND RETURN.

 

  CALL FUNCTION 'LIST_FROM_MEMORY'

    TABLES

      listobject = lt_abaplist

    EXCEPTIONS

      not_found  = 1

      OTHERS     = 2.

  IF sy-subrc = 0.

 

    CALL FUNCTION 'LIST_TO_ASCI'

      TABLES

        listasci   = lt_listzeile

        listobject = lt_abaplist

      EXCEPTIONS

        Others     = 1.

    IF sy-subrc = 0.

      e_tab_listzeile = lt_listzeile.

    ENDIF.

 

  ENDIF.

 

ENDFUNCTION.

 

 

Here now the changed Python program, with the new import parameter I_TAB_RSPARAMS.

 

# -*- coding: iso-8859-15 -*-

#-Begin-----------------------------------------------------------------

 

#-Imports---------------------------------------------------------------

import os, platform

 

#-Include---------------------------------------------------------------

FileName = "sapnwrfc.py"

exec(compile(open(FileName).read(), FileName, "exec"))

 

#-Sub Main--------------------------------------------------------------

def main():

 

  #-Connection parameters-----------------------------------------------

  RfcConnParams[0].name = "ASHOST"; RfcConnParams[0].value = "ABAP"

  RfcConnParams[1].name = "SYSNR" ; RfcConnParams[1].value = "00"

  RfcConnParams[2].name = "CLIENT"; RfcConnParams[2].value = "001"

  RfcConnParams[3].name = "USER"  ; RfcConnParams[3].value = "BCUSER"

  RfcConnParams[4].name = "PASSWD"; RfcConnParams[4].value = "minisap"

 

  hRFC = SAP.RfcOpenConnection(RfcConnParams, 5, RfcErrInf)

  if hRFC is not None:

 

    charBuffer = create_unicode_buffer(256 + 1)

 

    hFuncDesc = SAP.RfcGetFunctionDesc(hRFC, "Z_TEST", RfcErrInf)

    if hFuncDesc != 0:

      hFunc = SAP.RfcCreateFunction(hFuncDesc, RfcErrInf)

      if hFunc != 0:

 

        hTable = c_void_p(0)

        if SAP.RfcGetTable(hFunc, "I_TAB_RSPARAMS", hTable, RfcErrInf) == RFC_OK:

          hRow = SAP.RfcAppendNewRow(hTable, RfcErrInf)

          rc = SAP.RfcSetChars(hRow, "SELNAME", "USER", 4, RfcErrInf)

          rc = SAP.RfcSetChars(hRow, "KIND", "S", 1, RfcErrInf)

          rc = SAP.RfcSetChars(hRow, "SIGN", "I", 1, RfcErrInf)

          rc = SAP.RfcSetChars(hRow, "OPTION", "EQ", 2, RfcErrInf)

          rc = SAP.RfcSetChars(hRow, "LOW", "BCUSER", 6, RfcErrInf)

 

        if SAP.RfcInvoke(hRFC, hFunc, RfcErrInf) == RFC_OK:

 

          if SAP.RfcGetTable(hFunc, "E_TAB_LISTZEILE", hTable, \

            RfcErrInf) == RFC_OK:

 

            RowCount = c_ulong(0)

            rc = SAP.RfcGetRowCount(hTable, RowCount, RfcErrInf)

            rc = SAP.RfcMoveToFirstRow(hTable, RfcErrInf)

            for i in range(0, RowCount.value):

              hRow = SAP.RfcGetCurrentRow(hTable, RfcErrInf)

              rc = SAP.RfcGetChars(hRow, "ZEILE", charBuffer, 256, \

                RfcErrInf)

              print(charBuffer.value.rstrip())

              if i < RowCount.value:

                rc = SAP.RfcMoveToNextRow(hTable, RfcErrInf)

 

        rc = SAP.RfcDestroyFunction(hFunc, RfcErrInf)

 

    rc = SAP.RfcCloseConnection(hRFC, RfcErrInf)

 

  else:

    print(RfcErrInf.key)

    print(RfcErrInf.message)

 

#-Main------------------------------------------------------------------

if __name__ == "__main__":

  print("Python", platform.python_version(), "on",

    platform.system(), "(" + platform.architecture()[0] + ")",

    end="\n\n")

  main()

  print("\n")

  os.system('pause')

 

#-End-------------------------------------------------------------------

 

 

And here the expecting result.

003.JPG

 

Enjoy it.

 

Cheers

Stefan

How to use SAP GUI Scripting Inside Windows PowerShell (Part 2)

$
0
0

Hello community,

 

two and a half year ago I wrote here about the possiblity how to use SAP GUI Scripting with Windows PowerShell. But this solution uses Microsoft Script Control engine and it is not clear how the future will look like. So I develop a solution which works with PowerShell without the Microsoft Script Control engine:

 

#-Begin-----------------------------------------------------------------

 

  #-Get-Property--------------------------------------------------------

    function Get-Property {

      param([__ComObject] $object, [String] $propertyName)

      $objectType = [System.Type]::GetType($object)

      $objectType.InvokeMember($propertyName,

        "GetProperty", $NULL, $object, $NULL)

    }

 

  #-Set-Property--------------------------------------------------------

    function Set-Property {

      param([__ComObject] $object, [String] $propertyName,

        $propertyValue)

      $objectType = [System.Type]::GetType($object)

      [Void] $objectType.InvokeMember($propertyName,

        "SetProperty", $NULL, $object, $propertyValue)

    }

 

  #-Invoke-Method-------------------------------------------------------

    function Invoke-Method {

      param([__ComObject] $object, [String] $methodName,

        $methodParameters)

      $objectType = [System.Type]::GetType($object)

      $output = $objectType.InvokeMember($methodName,

        "InvokeMethod", $NULL, $object, $methodParameters)

      if ( $output ) { $output }

    }

 

  #-Main----------------------------------------------------------------

    $SapGuiAuto = [microsoft.visualbasic.Interaction]::GetObject("SAPGUI")

    $application = Invoke-Method $SapGuiAuto "GetScriptingEngine"

    $connection = Get-Property $application "Children" @(0)

    $session = Get-Property $connection "Children" @(0)

 

    $ID = Invoke-Method $session "findById" @("wnd[0]/usr/txtRSYST-MANDT")

    Set-Property $ID "Text" @("001")

    $ID = Invoke-Method $session "findById" @("wnd[0]/usr/txtRSYST-BNAME")

    Set-Property $ID "Text" @("BCUSER")

    $ID = Invoke-Method $session "findById" @("wnd[0]/usr/pwdRSYST-BCODE")

    Set-Property $ID "Text" @("minisap")

    $ID = Invoke-Method $session "findById" @("wnd[0]/usr/txtRSYST-LANGU")

    Set-Property $ID "Text" @("EN")

 

    $ID = Invoke-Method $session "findById" @("wnd[0]")

    Invoke-Method $ID "sendVKey" @(0)

 

#-End-------------------------------------------------------------------

 

Hint: The wrapper functions are from Bill Stewart - thanks for that.

 

Here the equivalent code but with Microsoft Script Control engine:

 

#-Begin-----------------------------------------------------------------


  $VB = New-Object -COMObject MSScriptControl.ScriptControl

 

$Cmd = @"

Set SapGuiAuto = GetObject(`"SAPGUI`")`n

Set application = SapGuiAuto.GetScriptingEngine`n

Set connection = application.Children(0)`n

Set session = connection.Children(0)`n

session.findById(`"wnd[0]/usr/txtRSYST-MANDT`").text = `"001`"`n

session.findById(`"wnd[0]/usr/txtRSYST-BNAME`").text = `"BCUSER`"`n

session.findById(`"wnd[0]/usr/pwdRSYST-BCODE`").text = `"minisap`"`n

session.findById(`"wnd[0]/usr/txtRSYST-LANGU`").text = `"EN`"`n

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

"@

 

  $VB.Language = "VBScript"

  $VB.AllowUI = $TRUE

  $VB.ExecuteStatement($Cmd)

 

#-End-------------------------------------------------------------------

 

As you can see looks the code a little bit unusual, but on this way you use only a VB.net function and PowerShell natively.

 


2016/03/08

Minor changes, explicit type detection for PowerShell 5 compatibility.

 

 

Enjoy it.

 

Cheers

Stefan

Control Visualizer

$
0
0

Hello community,

 

we all know the good old Scripting Wizard, which is not longer supported since Windows 7 and SAP GUI for Windows 7.20 PL?.

 

But SAP offers a Control Visualizer, maybe a replacment.

 

If you press the buttons  Ctrl  +  Shift  +  Z at the same time, it opens an additional window, called CMyControl Visualizer.

 

Hint: It is the Z key on keyboard with German keyboard layout - QWERTZ.

 

Visualizer.jpg

You got the field name, the style, the content and some other technical stuff about the selected control.

I am not really sure if this is a replacment, but it seems a little bit.

 

Hint: It works not with any screen and it is not very stable.

 

Addition 2016/04/13:

It still works with the actual version of the SAP GUI for Windows 7.40 PL 7 e.g. with TAC SE16.

 

Addition 2015/07/14:

It still works with the actual version of the SAP GUI for Windows 7.40 PL 3.

 

visualizer.JPG

 

Cheers

Stefan

New Patchlevel of SAP GUI for Windows is Available

$
0
0

Hello community,

 

since three days offers SAP the new patchlevel 8 of the SAP GUI for Windows 7.40. From the perspective of the SAP GUI Scripting there has been some small addtions in comparisation to the patchlevel 7:

 

  • To the enumeration GuiMagicDispIDs the constants
    GuiDispIDSBServiceReq = 32751
    GuiDispIDSBSuppMessage = 32752
    have been added.
  • To the class GuiStatusBar the methods
    ServiceRequestClick()
    CreateSupportMessageClick()
    have been added.

 

In the attachment you find a file with detailed information about the sapfewse.ocx 7.40.3.8.256 library like enumerations, classes with its methods and property.

 

Cheers

Stefan


Tip: Use Git Repository as Version Control System for your Script Programming

$
0
0

Hello community,

 

in different context we hear a lot about Git, a version control system. You can find Git here and you can find a very good introduction, explanation and instruction manual here - and this in many different languages. With Git it is very easy possible to use a version control system for your script programming, independent which programming language you use, e.g. AutoIt, PowerShell, VBScript etc. All you have to do is to download the Git release you need and to install it, e.g. in my case I download the x86 portable version for Windows.

001.jpg

I unpack the 7-zip file and add to path variable the path to git.exe.

 

Now I change in my script directory and enter git init to create a Git repository.

In the next step I add all my scripts with git add *.vbs and git commit to the Git repository.

 

You can add new files on the same way and if you change a file you can see the with git status an overview and git diff the details, but don't forget to add it in the staging area with git add. Last but not least a new git commit. You have a lot of possibilities with Git version control system.

 

I work with the command line version, but you can also use a GUI - you can find different here.

 

As I wrote here, script programming is really programming and for really programming it is standard to use a version control system. Git a is free and very good one, easy to handle and powerful.

 

Enjoy it.

 

Cheers

Stefan

Tip: SAP GUI for Windows 7.40 Administration Guide

$
0
0

Hello community,

 

in the context of this post I have found the Administration Guide for SAP GUI for Windows here. It is a very interesting document, it describes in any detail how to configure and to administer the SAP GUI for Windows. All registry keys with any value and information about corresponding OSS notes are exactly described here. Of course all keys which has effect to SAP GUI Scripting.

 

Enjoy it.

 

Cheers

Stefan

Tip: Complete Launch Sequence of SAP GUI Scritping in PowerShell

$
0
0

Hello community,

 

in the context of the discussion here I developed and presented a complete launch sequence of SAP GUI Scripting in VBScript here. But for the future it seems better to use PowerShell, for reasons which I have described here. Now the equivalent in PowerShell script language:

 

#-Begin-----------------------------------------------------------------

 

  #-Includes------------------------------------------------------------

    . "$PSScriptRoot\COM.ps1"

 

  #-Sub Main------------------------------------------------------------

    Function Main() {

 

      $OpenNewConnFlag = $false

 

      if (-Not (Get-Process saplogon -ErrorAction silentlycontinue)) {

        Start-Process "C:\Program Files (x86)\SAP\FrontEnd\SAPgui\saplogon.exe"

         do {

           Start-Sleep -Milliseconds 250

         } until(Get-Process | where {$_.mainWindowTitle -like "SAP Logon 740"})

      }

      $SapGuiAuto = Get-Object "SAPGUI"

      $application = Invoke-Method $SapGuiAuto "GetScriptingEngine"

      $connection = Get-Property $application "Children" @(0)

      if ($connection -eq $Null) {

        $OpenNewConnFlag = $true

        Invoke-Method $application "OpenConnectionByConnectionString" `

          @("/H/10.100.202.145/S/3263", $true) > $Null

        $connection = Get-Property $application "Children" @(0)

      }

      if ($application.Children().Count() -gt 1) {

        $connection = $connection[0]

      }

      $session = Get-Property $connection "Children" @(0)

      if ($connection.Children().Count() -gt 1) {

        $session = $session[0]

      }

 

      if ($OpenNewConnFlag -eq $true) {

        $ID = Invoke-Method $session "findById" @("wnd[0]/usr/txtRSYST-MANDT")

        Set-Property $ID "Text" @("001")

        $ID = Invoke-Method $session "findById" @("wnd[0]/usr/txtRSYST-BNAME")

        Set-Property $ID "Text" @("BCUSER")

        $ID = Invoke-Method $session "findById" @("wnd[0]/usr/pwdRSYST-BCODE")

        Set-Property $ID "Text" @("minisap")

        $ID = Invoke-Method $session "findById" @("wnd[0]/usr/txtRSYST-LANGU")

        Set-Property $ID "Text" @("EN")

        $ID = Invoke-Method $session "findById" @("wnd[0]")

        Invoke-Method $ID "sendVKey" @(0)

      }

 

      Free-Object $session

      Free-Object $connection

      Free-Object $application

      Free-Object $SapGuiAuto

 

    }

 

  #-Main----------------------------------------------------------------

    Main

 

#-End-------------------------------------------------------------------

 

 

Here now the facelifted COM include, which I introduced here:

 

#-Begin-----------------------------------------------------------------

 

  #-Load assembly-------------------------------------------------------

    [Reflection.Assembly]::LoadWithPartialName("Microsoft.VisualBasic") > $Null

 

  #-Function Create-Object----------------------------------------------

    Function Create-Object {

      param([String] $objectName)

      try {

        New-Object -ComObject $objectName

      }

      catch {

        [Void] [System.Windows.Forms.MessageBox]::Show(

          "Can't create object", "Important hint", 0)

      } 

    }

 

  #-Function Get-Object-------------------------------------------------

    Function Get-Object {

      param([String] $objectName)

      [Microsoft.VisualBasic.Interaction]::GetObject($objectName)

    }

 

  #-Sub Free-Object-----------------------------------------------------

    Function Free-Object {

      param([__ComObject] $object)

      [Void] [System.Runtime.Interopservices.Marshal]::ReleaseComObject($object)

    }

 

  #-Function Get-Property-----------------------------------------------

    function Get-Property {

      param([__ComObject] $object, [String] $propertyName)

      $objectType = [System.Type]::GetType($object)

      $objectType.InvokeMember($propertyName,

        "GetProperty", $NULL, $object, $NULL)

    }

 

  #-Sub Set-Property----------------------------------------------------

    function Set-Property {

      param([__ComObject] $object, [String] $propertyName,

        $propertyValue)

      $objectType = [System.Type]::GetType($object)

      [Void] $objectType.InvokeMember($propertyName,

        "SetProperty", $NULL, $object, $propertyValue)

    }

 

  #-Function Invoke-Method----------------------------------------------

    function Invoke-Method {

      param([__ComObject] $object, [String] $methodName,

        $methodParameters)

      $objectType = [System.Type]::GetType($object)

      $output = $objectType.InvokeMember($methodName,

        "InvokeMethod", $NULL, $object, $methodParameters)

      if ( $output ) { $output }

    }

 

#-End-------------------------------------------------------------------

 

 

Hint: This code is a different perspective from the solution here.

 

Enjoy it.

 

Cheers

Stefan

How To Use SQLite ODBC with PowerShell

$
0
0

Hello community,

 

two month ago I presented here the possibility to use SQLite databases via ADO and ODBC driver with ABAP.

Over one year ago I presented here the possibility to export SAP tables into local SQLite databases.

Here is an approach how to use this SQLite databases with PowerShell script language via the same ODBC driver.

 

#-Begin-----------------------------------------------------------------

 

  #-Sub Main------------------------------------------------------------

    Function Main() {

 

      #-Define connection string with the filename of the database------

      $DBDriver = "Driver=SQLite3 ODBC Driver;"

      $DBFile = "Database=C:\Dummy\sflight.sqlite;"

      $DBConnString = $DBDriver + $DBFile

 

      #-Open connection to database-------------------------------------

      $DBConnection = New-Object System.Data.Odbc.OdbcConnection `

        -ArgumentList $DBConnString

      $DBConnection.Open()

 

      #-Create SQL command----------------------------------------------

      $DBCommand = $DBConnection.CreateCommand()

      $SQLCmd = "SELECT * FROM sflight"

      $DBCommand.CommandText = $SQLCmd

 

      #-Execute SQL command---------------------------------------------

      try {

        $DBResult = $DBCommand.ExecuteReader()

        #-Get the number of fields in one record------------------------

        $DBCounter = $DBResult.FieldCount

        #-View result line by line--------------------------------------

        while ($DBResult.Read()) {

          for ($i = 0; $i -lt $DBCounter; $i++) {

            @{ $DBResult.GetName($i) = $DBResult.GetValue($i); }

          }

        }

      }

      catch {

        Write-Host "Database access error"

      }

 

      #-Close connection to database------------------------------------

      $DBConnection.Close()

 

    }

 

  #-Main----------------------------------------------------------------

    Main

 

#-End-------------------------------------------------------------------

 

On this way we have the possibility to export tables from an SAP system into a SQLite container, to use it from the backend via ABAP and also to use it from the frontend via PowerShell. It should be also considered that SQLite is available for Android, Linux, Mac OS X and different Windows platforms e.g. like Windows Phone. So we can exchange static data or data without permanent changes easily.

 

Enjoy it.

 

Cheers

Stefan

How to use SAP GUI Scripting inside Java

$
0
0


Hello community,

 

the SAP GUI Scripting bases on Windows OLE resp. ActiveX technic. In a normal case Java do not work with this platform dependent technic. Under this circumstances it is not possible to use SAP GUI Scripting with Java.

But there is a very good project on sourceforge.net which offers this possibility, it call JACOB - this means Java-COM Bridge. You find JACOB here.

 

With JACOB it is very easy to use SAP GUI Scripting inside Java, as the following examples shows.

The first example SAPGUIScriptingVersion.java shows a message box with the SAP GUI Scripting version. The second example SAPGUIScriptingLogon.java shows a complete automatic logon on an SAP system. Both sources includes the equivalent VBScript commands, from the SAP GUI Script Recorder, as comments.

 

Now you can easiely integrate your SAP GUI Scripting code inside your Java sources.

 

Enjoy it.

 

Cheers
Stefan

 

//-Begin----------------------------------------------------------------
//-
//- How to use SAP GUI Scripting inside Java
//- Example: Get version of SAP GUI Scripting
//-
//- Author: Stefan Schnell
//-
//----------------------------------------------------------------------  //-Import-------------------------------------------------------------    import com.jacob.activeX.ActiveXComponent;    import com.jacob.com.ComThread;    import com.jacob.com.Dispatch;    import com.jacob.com.Variant;    import javax.swing.*;  public class SAPGUIScriptingVersion {    public static void main(String[] args) {      //-Variables------------------------------------------------------        ActiveXComponent SAPROTWr, GUIApp;        Dispatch ROTEntry;        String MajorVersion, MinorVersion;        Variant ScriptEngine;                ComThread.InitSTA();      //-Set SapGuiAuto = GetObject("SAPGUI")---------------------------        SAPROTWr = new ActiveXComponent("SapROTWr.SapROTWrapper");        try {          ROTEntry = SAPROTWr.invoke("GetROTEntry", "SAPGUI").toDispatch();          //-Set application = SapGuiAuto.GetScriptingEngine------------            ScriptEngine = Dispatch.call(ROTEntry, "GetScriptingEngine");            GUIApp = new ActiveXComponent(ScriptEngine.toDispatch());          //-Get version of SAP GUI Scripting---------------------------            //-MajorVersion = application.MajorVersion()----------------              MajorVersion = GUIApp.getProperty("MajorVersion").toString();            //-MinorVersion = application.MinorVersion()----------------              MinorVersion = GUIApp.getProperty("MinorVersion").toString();            //-MsgBox "SAP GUI Scripting " & MajorVersion & "." & _            //   MinorVersion-------------------------------------------              JOptionPane.showMessageDialog(null, "SAP GUI Scripting " +                MajorVersion + "." + MinorVersion);      }      catch (Exception e) {      }      finally {        ComThread.Release();        System.exit(0);      }    }  }

//-End------------------------------------------------------------------

 

SAPGUIScripting.jpg

 

//-Begin----------------------------------------------------------------
//-
//- How to use SAP GUI Scripting inside Java
//- Example: Logon to an SAP system
//-
//- Author: Stefan Schnell
//-
//----------------------------------------------------------------------  //-Import-------------------------------------------------------------    import com.jacob.activeX.ActiveXComponent;    import com.jacob.com.ComThread;    import com.jacob.com.Dispatch;    import com.jacob.com.Variant;  public class SAPGUIScriptingLogon {    public static void main(String[] args) {      //-Variables------------------------------------------------------        ActiveXComponent SAPROTWr, GUIApp, Connection, Session, Obj;        Dispatch ROTEntry;        Variant ScriptEngine;                ComThread.InitSTA();      //-Set SapGuiAuto = GetObject("SAPGUI")---------------------------        SAPROTWr = new ActiveXComponent("SapROTWr.SapROTWrapper");        try {          ROTEntry = SAPROTWr.invoke("GetROTEntry", "SAPGUI").toDispatch();          //-Set application = SapGuiAuto.GetScriptingEngine------------            ScriptEngine = Dispatch.call(ROTEntry, "GetScriptingEngine");            GUIApp = new ActiveXComponent(ScriptEngine.toDispatch());          //-Set connection = application.Children(0)-------------------            Connection = new ActiveXComponent(              GUIApp.invoke("Children", 0).toDispatch());          //-Set session = connection.Children(0)-----------------------            Session = new ActiveXComponent(              Connection.invoke("Children", 0).toDispatch());          //-Set GUITextField Client------------------------------------          //-          //- session.findById("wnd[0]/usr/txtRSYST-MANDT").text = "000"          //-          //------------------------------------------------------------            Obj = new ActiveXComponent(Session.invoke("FindById",              "wnd[0]/usr/txtRSYST-MANDT").toDispatch());            Obj.setProperty("Text", "000");          //-Set GUITextField User--------------------------------------          //-          //- session.findById("wnd[0]/usr/txtRSYST-BNAME").text = _          //-   "BCUSER"          //-          //------------------------------------------------------------            Obj = new ActiveXComponent(Session.invoke("FindById",              "wnd[0]/usr/txtRSYST-BNAME").toDispatch());            Obj.setProperty("Text", "BCUSER");          //-Set GUIPasswordField Password------------------------------          //-          //- session.findById("wnd[0]/usr/pwdRSYST-BCODE").text = _          //-   "minisap"          //-          //------------------------------------------------------------            Obj = new ActiveXComponent(Session.invoke("FindById",              "wnd[0]/usr/pwdRSYST-BCODE").toDispatch());            Obj.setProperty("Text", "minisap");          //-Set GUITextField Language----------------------------------          //-          //- session.findById("wnd[0]/usr/txtRSYST-LANGU").text = "DE"          //-          //------------------------------------------------------------            Obj = new ActiveXComponent(Session.invoke("FindById",              "wnd[0]/usr/txtRSYST-LANGU").toDispatch());            Obj.setProperty("Text", "DE");          //-Press enter------------------------------------------------          //-          //- session.findById("wnd[0]").sendVKey 0          //-          //------------------------------------------------------------            Obj = new ActiveXComponent(Session.invoke("FindById",              "wnd[0]").toDispatch());            Obj.invoke("sendVKey", 0);      }      catch (Exception e) {      }      finally {        ComThread.Release();        System.exit(0);      }    }  }

//-End------------------------------------------------------------------

How To Use PowerShell Script Inside Java

$
0
0

Hello community,

 

I wrote here about the using of SAP GUI Scripting inside Java. Also I wrote here, here, here and here about the using of PowerShell inside ABAP. Here now a combination of both. I use JaCoB (Java COM Bridge) with SAPIEN Technologies ActiveX PowerShell library. On this way it is possible to use PowerShell seamless and easily inside Java.

 

//-Begin----------------------------------------------------------------

//-

//- Example program how to use PowerShell inside Java

//-

//- Author: Stefan Schnell

//-

//----------------------------------------------------------------------

 

  //-Package------------------------------------------------------------

    package de.stschnell;

 

  //-Import-------------------------------------------------------------

    import com.jacob.activeX.ActiveXComponent;

    import com.jacob.com.ComThread;

    import com.jacob.com.Variant;

 

  //-Class--------------------------------------------------------------

    public class GetPSVersion {

 

    //-Constants--------------------------------------------------------

      public static final int OUTPUT_CONSOLE = 0;

      public static final int OUTPUT_WINDOW = 1;

      public static final int OUTPUT_BUFFER = 2;

 

    //-Main-------------------------------------------------------------

        public static void main(String[] args) {

 

        ComThread.InitSTA();

 

        ActiveXComponent PS = new ActiveXComponent("SAPIEN.ActiveXPoSHV3");

        try {

 

              if (PS.invoke("Init", false).changeType(Variant.VariantInt).getInt() != 0) {

            throw new RuntimeException();

          }

 

          if (PS.getProperty("IsPowerShellInstalled").changeType(Variant.VariantInt).getInt() == 0) {

            throw new RuntimeException();

          }

 

          PS.setProperty("OutputMode", OUTPUT_BUFFER);

          PS.invoke("ClearOutput");

    

          String PSCommand = "Get-Host;$PSVersionTable.PSVersion";

    

          PS.invoke("Execute", PSCommand);

          String Output = PS.getProperty("OutputString").toString();

 

          System.out.println(Output);

  

        }

 

        catch (Exception e) {

          System.out.println("An exception has occurred");

        }

 

        finally {

          ComThread.Release();

          System.exit(0);

        }

 

      }         

      

    }

 

//-End------------------------------------------------------------------

 

002.jpg

 

With regard to the Eclipse IDE this may be an interesting aspect - but I must admit a little bit exotic.

 

Enjoy it.

 

Cheers

Stefan

How To Use VB.NET via PowerShell Inside Java

$
0
0

Hello community,

 

I presented here the possibility how to use PowerShell inside Java. Here now on the same way an example how to use VB.NET inside Java, equivalent to the ABAP example. The VB code is in an external file in a project directory from Eclipse.

 

//-Begin----------------------------------------------------------------

//-

//- Example program how to use VB.NET via PowerShell inside Java

//-

//- Author: Stefan Schnell

//-

//----------------------------------------------------------------------

 

  //-Package------------------------------------------------------------

    package de.stschnell;

 

  //-Import-------------------------------------------------------------

    import com.jacob.activeX.ActiveXComponent;

    import com.jacob.com.*;

    import java.io.*;

 

  //-Class--------------------------------------------------------------

    public class RunVBSharp {

 

    //-Constants--------------------------------------------------------

      public static final int OUTPUT_CONSOLE = 0;

      public static final int OUTPUT_WINDOW = 1;

      public static final int OUTPUT_BUFFER = 2;

 

    //-ReadFile---------------------------------------------------------

      public static String ReadFile(String FileName) {

      

        char[] FileContent = new char[0];

        try {

          String FileNamePath = System.getProperty("user.dir") +

            FileName;

          File PSFile = new File(FileNamePath);

          FileReader PSFileRead = new FileReader(PSFile);

          FileContent = new char[(int) PSFile.length()];

          PSFileRead.read(FileContent);

          PSFileRead.close();

        }

        catch (Exception e) {

          System.out.println("Can't read file");

        }

        return String.valueOf(FileContent);

      }

    

    //-Main-------------------------------------------------------------

      public static void main(String[] args) {

 

        ComThread.InitSTA();

      

        ActiveXComponent PS = new ActiveXComponent("SAPIEN.ActiveXPoSHV3");

        try {

 

          if (PS.invoke("Init", false).changeType(Variant.VariantInt).getInt() != 0) {

            throw new RuntimeException();

          }

 

          if (PS.getProperty("IsPowerShellInstalled").changeType(Variant.VariantInt).getInt() == 0) {

            throw new RuntimeException();

          }

 

          PS.setProperty("OutputMode", OUTPUT_CONSOLE);

 

          //-Read Visual Basic dotNET file------------------------------

            String VBCode = ReadFile("\\src\\de\\stschnell\\Test.vb");

            if (VBCode.length() == 0) {

              throw new RuntimeException();

            }

          

          //-Concatenate PowerShell command with VB code----------------

            String PSCmd = "$VBCode = @\"\r\n";

            PSCmd += VBCode + "\r\n";

            PSCmd += "\"@;\r\n";

            PSCmd += "Add-Type -TypeDefinition $VBCode " +

              "-Language VisualBasic\r\n";

            PSCmd += "$VB = new-Object VBCode.VB\r\n";

 

          //-Call the VB methods on different ways----------------------

            //-Static call with return value----------------------------

              PSCmd += "[VBCode.VB]::Hello1()\r\n";

            //-Instance call with return value--------------------------

              PSCmd += "$VB.Hello2(\"Stefan\")\r\n";

            //-Instance call with MessageBox----------------------------

              PSCmd += "$VB.Hello3(\"Stefan\")\r\n";      

  

          PS.invoke("Execute", PSCmd);

 

        }

 

        catch (Exception e) {

          System.out.println("An exception occurred");

        }

 

        finally {

          ComThread.Release();

          System.exit(0);

        }

 

      }

 

    }

 

//-End------------------------------------------------------------------

 

 

Here a snapshot of the running VB.NET example inside Java with Eclipse:

002.jpg

 

Here a snapshot of the VB.NET file:

001.jpg

 

Enjoy it.

 

Cheers

Stefan


REPL Interface for VBScript

$
0
0

Hello community,

 

more and more moves Read-Eval-Print-Loop (REPL) shells in the focus of scripting languages. You can find more information about REPL here.

 

Here is a tiny REPL shell for VBScript:

 

'-Begin-----------------------------------------------------------------

'-

'- REPL interactive shell for VBScript

'- (REPL = Read Eval Print Loop)

'- Call it with CSCRIPT REPL.VBS //NOLOGO

'-

'-----------------------------------------------------------------------

 

  WScript.StdOut.Write("Welcome to REPL interactive shell for " & _

    "VBScript" & vbCrLf)

 

  repl_Quit = False

  Do

 

    If repl_SubFlag = False Then

      WScript.StdOut.Write(vbCrLf & "> ")

    Else

      WScript.StdOut.Write("  ")

    End If

 

    repl_Line = WScript.StdIn.ReadLine

 

    repl_Pos = InStr(repl_Line, " ")

    If repl_Pos > 0 Then

      repl_Cmd = Trim(Left(repl_Line, repl_Pos))

    Else

      repl_Cmd = repl_Line

    End If

 

    If repl_SubFlag = True Then

      repl_Lines = repl_Lines & repl_Line & vbCrLf

    End If

 

    Select Case LCase(repl_Cmd)

      Case "quit"

        repl_Quit = True

      Case "print", "echo"

        On Error Resume Next

        Err.Clear

        Execute("WScript.Echo(" & _

          Trim(Right(repl_Line, Len(repl_Line) - repl_Pos)) & ")")

        If Err.Number <> 0 Then

          WScript.Echo(Err.Description)

        End If

        On Error Goto 0

      Case "sub", "function", "class"

        repl_SubFlag = true

        repl_Lines = repl_Line & vbCrLf

      Case Else

        If repl_SubFlag = False Then

          On Error Resume Next

          Err.Clear

          Execute repl_Lines & repl_Line

          If Err.Number <> 0 Then

            WScript.Echo(Err.Description)

          End If

          On Error Goto 0

          repl_Lines = ""

        End If

    End Select

 

  Loop While repl_Quit = False

 

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

 

Start this script with cscript repl.vbs //nologo from the command line.

 

002.jpg

With this shell you have the possiblity to check easily commands, sub routines, functions etc. etc. etc.

 

Enjoy it.

 

Cheers

Stefan

The Equality of the Use of Various REPL Shells

$
0
0

Hello community,

 

a few days ago I presented here a REPL shell for VBScript. In the last few days I experimented with Julia REPL shell and SAP NetWeaver RFC Library, you can find more about it here. So I asked myself the question, what is the difference if I use varying REPL shells in the same context?

 

Here now the result, side by side:

 

VBScript REPL ShellJulia REPL Shell

 

REPL_VBScript.jpg

 

REPL_Julia.jpg

 

As you can see, it is a small difference, based on the different languages - that's all. To check out the RFC functionality there is no difference. From this perspective both REPL shells a equal.

 

REPL shells are a typical characteristic of scripting languages. So it is somewhat surprising that non scripting languages, e.g. like Java 9, implement a REPL shell called JShell, look here. It is very interesting to see that basic ideas of scripting languages find their way into compiler languages. When will the ABAP environment offer this feature?

 

Enjoy REPL.

 

Cheers

Stefan

Julia High-Level and High-Performance Dynamic Programming Language with SAP via NetWeaver RFC Library (Part 1 - Introduction)

$
0
0

Hello community,

 

Julia is a very incredible high-performance programming language for technical computing. You can find Julia here. You can find more information about Julia here. You can find the first introduction of Julia in SCN Innovation Management here from Alvaro Tejada Galindo. Julia offers new perspectives, e.g. in parallel programming or speed. Julia uses a low level virtual machine (LLVM) to execute the code. The VM generates optimized processor dependent machine code, so Julia is very fast. Here now an include to use Julia with the SAP NetWeaver RFC library - but only with a few functions:

 

#-Begin-----------------------------------------------------------------

 

  #-User Defined Types--------------------------------------------------

    type RFC_CONNECTION_PARAMETER

      nameASHost::Ptr{UInt16}

      valueASHost::Ptr{UInt16}

      nameSysNr::Ptr{UInt16}

      valueSysNr::Ptr{UInt16}

      nameClient::Ptr{UInt16}

      valueClient::Ptr{UInt16}

      nameUser::Ptr{UInt16}

      valueUser::Ptr{UInt16}

      namePassWd::Ptr{UInt16}

      valuePassWd::Ptr{UInt16}

      nameLang::Ptr{UInt16}

      valueLang::Ptr{UInt16}

    end

 

    type RFC_ERROR_INFO

      code::Int32

      group::Int32

      key::Ptr{UInt16}

      message::Ptr{UInt16}

      abapMsgClass::Ptr{UInt16}

      abapMsgType::Ptr{UInt16}

      abapMsgNumber::Ptr{UInt16}

      abapMsgV1::Ptr{UInt16}

      abapMsgV2::Ptr{UInt16}

      abapMsgV3::Ptr{UInt16}

      abapMsgV4::Ptr{UInt16}

    end

 

  #-Constants-----------------------------------------------------------

    const sapnwrfc = "sapnwrfc.dll"

 

  #-Main----------------------------------------------------------------

    cd("C:\\Projects\\SAP\\RFC\\Julia")

 

    code = 0

    group = 0

    key = ""

    message = ""

    abapMsgClass = ""

    abapMsgType = ""

    abapMsgNumber = ""

    abapMsgV1 = ""

    abapMsgV2 = ""

    abapMsgV3 = ""

    abapMsgV4 = ""

    RfcErrorInfo = RFC_ERROR_INFO(

     code, group, pointer(utf16(key)), pointer(utf16(message)),

     pointer(utf16(abapMsgClass)), pointer(utf16(abapMsgType)),

     pointer(utf16(abapMsgNumber)), pointer(utf16(abapMsgV1)),

     pointer(utf16(abapMsgV2)), pointer(utf16(abapMsgV3)),

     pointer(utf16(abapMsgV4))

    )

 

  #-RfcGetVersion-------------------------------------------------------

    function RfcGetVersion()

      majorVersion = Ref{UInt32}(0)

      minorVersion = Ref{UInt32}(0)

      patchLevel = Ref{UInt32}(0)

      ptrVersion = ccall((:RfcGetVersion, sapnwrfc), stdcall,

        Ptr{UInt16}, (Ptr{UInt32}, Ptr{UInt32}, Ptr{UInt32}),

        majorVersion, minorVersion, patchLevel)

      return utf16(ptrVersion), majorVersion[], minorVersion[],

        patchLevel[]

    end

 

  #-RfcOpenConnection---------------------------------------------------

    function RfcOpenConnection(ashost::AbstractString,

      sysnr::AbstractString, client::AbstractString,

      user::AbstractString, passwd::AbstractString,

      lang::AbstractString = "EN")

      nameASHost = "ASHOST"

      valueASHost = ashost

      nameSysNr = "SYSNR"

      valueSysNr = sysnr

      nameClient = "CLIENT"

      valueClient = client

      nameUser = "USER"

      valueUser = user

      namePassWd = "PASSWD"

      valuePassWd = passwd

      nameLang = "LANG"

      valueLang = lang

      RfcConnectionParameter = RFC_CONNECTION_PARAMETER(

        pointer(utf16(nameASHost)), pointer(utf16(valueASHost)),

        pointer(utf16(nameSysNr)), pointer(utf16(valueSysNr)),

        pointer(utf16(nameClient)), pointer(utf16(valueClient)),

        pointer(utf16(nameUser)), pointer(utf16(valueUser)),

        pointer(utf16(namePassWd)), pointer(utf16(valuePassWd)),

        pointer(utf16(nameLang)), pointer(utf16(valueLang))

      )

      return ccall((:RfcOpenConnection, sapnwrfc), stdcall,

        UInt32, (Ref{RFC_CONNECTION_PARAMETER}, UInt32,

        Ref{RFC_ERROR_INFO}), RfcConnectionParameter, 6, RfcErrorInfo)

    end

 

  #-RfcGetFunctionDesc--------------------------------------------------

    function RfcGetFunctionDesc(rfcHandle::UInt32,

      funcName::AbstractString)

      return ccall((:RfcGetFunctionDesc, sapnwrfc), stdcall,

        UInt32, (UInt32, Ptr{UInt16}, Ref{RFC_ERROR_INFO}),

        rfcHandle, utf16(funcName), RfcErrorInfo)

    end

 

  #-RfcCreateFunction---------------------------------------------------

    function RfcCreateFunction(funcDescHandle::UInt32)

      return ccall((:RfcCreateFunction, sapnwrfc), stdcall,

        UInt32, (UInt32, Ref{RFC_ERROR_INFO}),

        funcDescHandle, RfcErrorInfo)

    end

 

  #-RfcInvoke-----------------------------------------------------------

    function RfcInvoke(rfcHandle::UInt32, funcHandle::UInt32)

      return ccall((:RfcInvoke, sapnwrfc), stdcall,

        UInt32, (UInt32, UInt32, Ref{RFC_ERROR_INFO}),

        rfcHandle, funcHandle, RfcErrorInfo)

    end

 

  #-RfcDestroyFunction--------------------------------------------------

    function RfcDestroyFunction(funcHandle::UInt32)

      return ccall((:RfcDestroyFunction, sapnwrfc), stdcall,

        UInt32, (UInt32, Ref{RFC_ERROR_INFO}),

        funcHandle, RfcErrorInfo)

    end

 

  #-RfcCloseConnection--------------------------------------------------

    function RfcCloseConnection(rfcHandle::UInt32)

      return ccall((:RfcCloseConnection, sapnwrfc), stdcall,

        UInt32, (UInt32, Ref{RFC_ERROR_INFO}),

        rfcHandle, RfcErrorInfo)

    end

 

#-End-------------------------------------------------------------------

 

With this include it is easy possible to use NetWeaver RFC Library with Julia REPL interface (Read - Eval - Print - Loop):

 

JuliaMeetsSAP2.jpg

In the example above you see loading of the include and a sequence of SAP NetWeaver RFC commands to invoke the RFC_PING function module.

 

After the RfcOpenConnection command you see the connected Julia in the Gateway Monitor (TAC SMGW):

JuliaMeetsSAP.JPG

 

It should be not very difficult now to extend the include with the other functions from the SAP NetWeaver RFC library.

 

More information:

Part 2: Read a table

Part 3: sapnwrfc.jl include - with the examples for RFCSI_EXPORT and RFC_ABAP_INSTALL_AND_RUN

 

Enjoy it.

 

Cheers

Stefan

Julia High-Level and High-Performance Dynamic Programming Language with SAP via NetWeaver RFC Library (Part 2 - Read a Table)

$
0
0

Hello community,

 

a few days ago I presented the programming language Julia here. Now an add-on with a few SAP NetWeaver RFC functions to the include to read tables.

 

At first the Julia code:

 

  #-RfcSetChars---------------------------------------------------------

    function RfcSetChars(dataHandle::UInt32, name::AbstractString,

      charValue::AbstractString)

      return ccall((:RfcSetChars, sapnwrfc), stdcall,

        UInt32, (UInt32, Ptr{UInt16}, Ptr{UInt16}, UInt32,

        Ref{RFC_ERROR_INFO}),

        dataHandle, utf16(name), utf16(charValue), length(charValue),

        RfcErrorInfo)

    end

 

  #-RfcGetTable---------------------------------------------------------

    function RfcGetTable(dataHandle::UInt32, name::AbstractString)

      ref_tableHandle = Ref{UInt32}(0)

      rc = ccall((:RfcGetTable, sapnwrfc), stdcall,

        UInt32, (UInt32, Ptr{UInt16}, Ref{UInt32}, Ref{RFC_ERROR_INFO}),

        dataHandle, utf16(name), ref_tableHandle, RfcErrorInfo)

      return rc, ref_tableHandle[]

    end

 

  #-RfcGetRowCount------------------------------------------------------

    function RfcGetRowCount(tableHandle::UInt32)

      ref_rowCount = Ref{UInt32}(0)

      rc = ccall((:RfcGetRowCount, sapnwrfc), stdcall,

        UInt32, (UInt32, Ref{UInt32}, Ref{RFC_ERROR_INFO}),

        tableHandle, ref_rowCount, RfcErrorInfo)

      return rc, ref_rowCount[]

    end

 

  #-RfcMoveToFirstRow---------------------------------------------------

    function RfcMoveToFirstRow(tableHandle::UInt32)

      return ccall((:RfcMoveToFirstRow, sapnwrfc), stdcall,

        UInt32, (UInt32, Ref{RFC_ERROR_INFO}),

        tableHandle, RfcErrorInfo)

    end

 

  #-RfcGetCurrentRow----------------------------------------------------

    function RfcGetCurrentRow(tableHandle::UInt32)

      return ccall((:RfcGetCurrentRow, sapnwrfc), stdcall,

        UInt32, (UInt32, Ref{RFC_ERROR_INFO}),

        tableHandle, RfcErrorInfo)

    end

 

  #-RfcGetChars---------------------------------------------------------

    function RfcGetChars(dataHandle::UInt32, name::AbstractString,

      bufferLength::Int32)

      charBuffer = Array(UInt16, bufferLength + 1)

      rc = ccall((:RfcGetChars, sapnwrfc), stdcall,

        UInt32, (UInt32, Ptr{UInt16}, Ptr{UInt16}, UInt32,

        Ref{RFC_ERROR_INFO}),

        dataHandle, utf16(name), charBuffer, sizeof(charBuffer),

        RfcErrorInfo)

      charBuffer[end] = 0

      return rc, charBuffer

    end

 

  #-RfcMoveToNextRow()--------------------------------------------------

    function RfcMoveToNextRow(tableHandle::UInt32)

      return ccall((:RfcMoveToNextRow, sapnwrfc), stdcall,

        UInt32, (UInt32, Ref{RFC_ERROR_INFO}),

        tableHandle, RfcErrorInfo)

    end

 

 

Here a sequence of the commands above, to read the table USR01:

JuliaMeetsSAP3.jpg


In the example above you see loading of the include and a sequence of SAP NetWeaver RFC commands to invoke the RFC_READ_TABLE function module. With the function RfcSetChars we set the import parameters of the function module. After the invoke we get the table via RfcGetTable and check the numbers of rows which are delivered with RfcGetRowCount. Now we get the current row and read the first line with RfcGetChars. With RfcMoveToNextRow we jump into the next line and read it also. Last but not least we close the connection.

 

Here the content of my USR01 table to show that the result in Julia exactly corresponds to the content of the table.

JuliaMeetsSAP33.JPG

 

It is very interesting to experiment with Julias REPL interface.

 

More information:

Part 3: sapnwrfc.jl include - with the examples for RFCSI_EXPORT and RFC_ABAP_INSTALL_AND_RUN

 

Enjoy it.

 

Cheers

Stefan

Julia High-Level and High-Performance Dynamic Programming Language with SAP via NetWeaver RFC Library (Part 3 - sapnwrfc.jl Include)

$
0
0

Hello community,

 

in part one of this serie I introduced Julia programming language here. In part two I show here how to use the ABAP function module RFC_READ_TABLE to get data from an SAP system. Here now the sapnwrfc.jl include file for Julia, with all function stubs of the SAP NetWeaver RFC library 7.21 PL 39. A few functions contains code and I will add the code for the other functions successively.

 

Here another example how to use the function module RFCSI_EXPORT:

Julia_RFCSI_EXPORT.jpg

 

 

Here another example how to use the function module RFC_ABAP_INSTALL_AND_RUN - on this way you have the possibility to define and to execute an ABAP report from Julia:

Julia_ABAP_Install_And_Run.jpg

 

Enjoy it.

 

Cheers

Stefan

Viewing all 100 articles
Browse latest View live


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