Application Development Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
stefan_schnell
Active Contributor
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 256.

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

Field-Symbols:
Type SFLIGHT
.

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

Loop At lt_SFlight Assigning .
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 LoadNCo-----------------------------------------------------------
Function LoadNCo {

[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 RunABAP-----------------------------------------------------------
Function RunABAP {

$destination = Get-Destination

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

#-Call function module------------------------------------------------
[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")

$arrSFlight = New-Object System.Collections.Generic.List[Object]

ForEach ($Row In $Table) {
[String]$Line = $Row
$Elements = $Line.Replace("FIELD ZEILE=", "").Split(";")
$SFlight = New-Object PSObject -Property @{
CARRID = $Elements[0].Trim()
CONNID = $Elements[1].Trim()
FLDATE = $Elements[2].Trim()
PRICE = $Elements[3].Trim()
PLANETYPE = $Elements[4].Trim()
}
$arrSFlight.Add($SFlight)
}

$arrSFlight | Out-GridView -Title "SFLIGHT"

}

#-Sub Main--------------------------------------------------------------
Function Main {
If ($PSVersionTable.PSVersion.Major -ge 5) {
LoadNCo
RunABAP
}
}

#-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.
1 Comment