Skip to Content

The RFM RFC_ABAP_INSTALL_AND_RUN offers great possibilities to achieve a high integration level between ABAP and an external scripting language, from the perspective of the scripting language. In this post I describe how to do that with PowerShell and the dotNET Connector (NCo).

 

In the last years I wrote posts how to use RFM RFC_ABAP_INSTALL_AND_RUN with COM Connector (CCo) or via NW RFC SDK for:

 

You can find detailed explantions how to use NCo with PowerShell here:

 

Here now the first script, which includes the ABAP code as here string at the top. It loads the NCo libraries and gets the destination. Then it loads the ABAP code line by line into the PROGRAM table of the RFM RFC_ABAP_INSTALL_AND_RUN and executes it. Last but not least it prints the result from the WRITES table.

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

$ABAPCode = @"
"-Begin-----------------------------------------------------------------
Report zTest Line-Size 256.

Write: 'Hello World from'.
Write: sy-sysid.

"-End-------------------------------------------------------------------
"@

  #-Sub Load-NCo--------------------------------------------------------
  Function Load-NCo {

    [String]$ScriptDir = $PSScriptRoot

    If ([Environment]::Is64BitProcess) {
      [String]$Path = $ScriptDir + "\x64\"
    } Else {
      [String]$Path = $ScriptDir + "\x86\"
    }

    [String]$File = $Path + "sapnco.dll"; Add-Type -Path $File
    $File = $Path + "sapnco_utils.dll"; Add-Type -Path $File

  }

  #-Function Get-Destination--------------------------------------------
  Function Get-Destination {

    #-Connection parameters---------------------------------------------
    $cfgParams = New-Object SAP.Middleware.Connector.RfcConfigParameters
    $cfgParams.Add("NAME", "Test")
    $cfgParams.Add("ASHOST", "NSP")
    $cfgParams.Add("SYSNR", "00")
    $cfgParams.Add("CLIENT", "001")
    $cfgParams.Add("USER", "BCUSER")
    $cfgParams.Add("PASSWD", "minisap")

    Return [SAP.Middleware.Connector.RfcDestinationManager]::GetDestination($cfgParams)

  }

  #-Sub Run-ABAP--------------------------------------------------------
  Function Run-ABAP () {

    $destination = Get-Destination

    #-Metadata----------------------------------------------------------
    $rfcFunction = `
      $destination.Repository.CreateFunction("RFC_ABAP_INSTALL_AND_RUN")

    #-Call function module----------------------------------------------
    Try {
      [SAP.Middleware.Connector.IRfcTable]$Table = `
        $rfcFunction.GetTable("PROGRAM")

      $ABAPLines = $ABAPCode -Split [System.Environment]::NewLine

      ForEach($ABAPLine In $ABAPLines){
        $Table.Append()
        $Table.SetValue("LINE", $ABAPLine)
      }

      $rfcFunction.Invoke($destination)

      [SAP.Middleware.Connector.IRfcTable]$Table = `
        $rfcFunction.GetTable("WRITES")

      ForEach ($Line In $Table) {
        Write-Host $Line.GetValue("ZEILE")
      }

    } Catch {
      Write-Host "Exception occured:`r`n" $_.Exception.Message
    }

  }

  #-Sub Main------------------------------------------------------------
  Function Main () {
    If ($PSVersionTable.PSVersion.Major -ge 5) {
      Load-NCo
      Run-ABAP
    }
  }

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

  #-Error routine-------------------------------------------------------
  Trap {
    [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") > $Null
    [Void] [System.Windows.Forms.MessageBox]::Show( `
      $_.Exception.GetType().FullName + `
      [System.Environment]::NewLine + [System.Environment]::NewLine + `
      $_.Exception.Message, "An Error Occurred", 0)
    Exit
  }

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

 

Here now another example which selects data from SFLIGHT table, returns it to the script and the script takes it into the SFlight array:

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

$ABAPCode = @"
"-Begin-----------------------------------------------------------------
"
" Important hint: Line-Size of the Report statement must be less or
"                 equal 256.
"
" Important hint: The length of a code line may not exceed 72
"                 characters.
"
"-----------------------------------------------------------------------
Report zTest Line-Size 46.

Data:
  lt_SFlight Type Standard Table Of SFLIGHT,
  lv_Price Type String
  .

Field-Symbols:
  <ls_SFlight> Type SFLIGHT
  .

Select *
  Into Table lt_SFlight
  From SFLIGHT
  Where CARRID = 'LH'
  .

Loop At lt_SFlight Assigning <ls_SFlight>.
  lv_Price = <ls_SFlight>-Price. Condense lv_Price.
  Write: <ls_SFlight>-CarrID, ';', <ls_SFlight>-ConnID, ';',
         <ls_SFlight>-FLDate, ';', lv_Price, ';',
         <ls_SFlight>-PlaneType.
EndLoop.

"-End-------------------------------------------------------------------
"@

  #-Sub Load-NCo--------------------------------------------------------
  Function Load-NCo {

    [String]$ScriptDir = $PSScriptRoot

    If ([Environment]::Is64BitProcess) {
      [String]$Path = $ScriptDir + "\x64\"
    } Else {
      [String]$Path = $ScriptDir + "\x86\"
    }

    [String]$File = $Path + "sapnco.dll"; Add-Type -Path $File
    $File = $Path + "sapnco_utils.dll"; Add-Type -Path $File

  }

  #-Function Get-Destination--------------------------------------------
  Function Get-Destination {

    #-Connection parameters---------------------------------------------
    $cfgParams = New-Object SAP.Middleware.Connector.RfcConfigParameters
    $cfgParams.Add("NAME", "Test")
    $cfgParams.Add("ASHOST", "NSP")
    $cfgParams.Add("SYSNR", "00")
    $cfgParams.Add("CLIENT", "001")
    $cfgParams.Add("USER", "BCUSER")
    $cfgParams.Add("PASSWD", "minisap")

    Return [SAP.Middleware.Connector.RfcDestinationManager]::GetDestination($cfgParams)

  }

  #-Sub Run-ABAP--------------------------------------------------------
  Function Run-ABAP () {

    $destination = Get-Destination

    #-Metadata----------------------------------------------------------
    $rfcFunction = `
      $destination.Repository.CreateFunction("RFC_ABAP_INSTALL_AND_RUN")

    #-Call function module----------------------------------------------
    Try {
      [SAP.Middleware.Connector.IRfcTable]$Table = `
        $rfcFunction.GetTable("PROGRAM")

      $ABAPLines = $ABAPCode -Split [System.Environment]::NewLine

      ForEach($ABAPLine In $ABAPLines){
        $Table.Append()
        $Table.SetValue("LINE", $ABAPLine)
      }

      $rfcFunction.Invoke($destination)

      [SAP.Middleware.Connector.IRfcTable]$Table = `
        $rfcFunction.GetTable("WRITES")

      $SFlight = @()

      ForEach ($Row In $Table) {
        [String]$Line = $Row
        $Elements = $Line.Replace("FIELD ZEILE=", "").Split(";")
        $SFlight += ,@($Elements[0].Trim(), $Elements[1].Trim(),
          $Elements[2].Trim(), $Elements[3].Trim(), $Elements[4].Trim())
      }

    } Catch {
      Write-Host "Exception occured:`r`n" $_.Exception.Message
    }

  }

  #-Sub Main------------------------------------------------------------
  Function Main () {
    If ($PSVersionTable.PSVersion.Major -ge 5) {
      Load-NCo
      Run-ABAP
    }
  }

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

  #-Error routine-------------------------------------------------------
  Trap {
    [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") > $Null
    [Void] [System.Windows.Forms.MessageBox]::Show( `
      $_.Exception.GetType().FullName + `
      [System.Environment]::NewLine + [System.Environment]::NewLine + `
      $_.Exception.Message, "An Error Occurred", 0)
    Exit
  }

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

 

With this RFM it is very easy to use ABAP in the context of PowerShell. On this way you can use ABAP functionality inside your PowerShell script easily.

 

Enjoy it.

Cheers
Stefan

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply