<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>SAP &#8211; Xojo Programming Blog</title>
	<atom:link href="https://blog.xojo.com/tag/sap/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.xojo.com</link>
	<description>Blog about the Xojo programming language and IDE</description>
	<lastBuildDate>Tue, 02 Mar 2021 17:04:32 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>Building an RFC interface with MBS Xojo Plugin to SAP R/3 or SAP S/4 HANA</title>
		<link>https://blog.xojo.com/2020/05/28/building-an-rfc-interface-with-mbs-xojo-plugin-to-sap-r-3-or-sap-s-4-hana/</link>
		
		<dc:creator><![CDATA[Michael Eckert]]></dc:creator>
		<pubDate>Thu, 28 May 2020 10:00:00 +0000</pubDate>
				<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Enterprise Software]]></category>
		<category><![CDATA[Monkeybread Software]]></category>
		<category><![CDATA[SAP]]></category>
		<category><![CDATA[Third Party]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=7032</guid>

					<description><![CDATA[With the RFC classes of the MBS Xojo Tools Plugin you can build RFC interfaces to SAP systems.]]></description>
										<content:encoded><![CDATA[
<p>If you work with large companies, you&#8217;ve most likely heard of SAP, a widely used enterprise software solution. With the RFC classes of the <a href="https://www.monkeybreadsoftware.de/xojo/plugins.shtml">MBS Xojo Plugin</a> you can build RFC (Remote Function Call) interfaces so that Xojo apps can communicate with SAP systems. I’ve done this to SAP R/3 and SAP S/4 HANA. The MBS plugin covers the libraries of the SAP NetWeaver RFC SDK 7.50.</p>



<h3 class="wp-block-heading">The SAP interface has four steps:</h3>



<ol class="wp-block-list"><li>Determine the path to the SAP library&nbsp;</li><li>Build a connection to the SAP system</li><li>Transfer data to the SAP system</li><li>Receive data from the SAP system</li></ol>



<h3 class="wp-block-heading">Connect the SAP System</h3>



<p>Your SAP user must have the authority for RFC connections. If so, you must know some data of your SAP logon to connect to an SAP system, such as:</p>



<ul class="wp-block-list"><li>host name &#8211; a name or an IP address (ashost)</li><li>router string&nbsp;</li><li>system number (sysnr)</li><li>client (client)</li><li>language (lang)</li><li>user (user)</li><li>password (passwd)</li></ul>



<p>At first you must set the path to the SAP libraries. In Windows you have some DLL’s around SAPNWRFC.DLL and on macOS you have some DYLIB’s around LIBSAPNWRFC.DYLIB.</p>



<pre class="wp-block-preformatted">If TargetWin32
  var LibFile as string = "sapnwrfc.dll"
Else
  // get the actual folder and handle the exception
  var MacOsFolder as folderitem = app.ExecutableFile.Parent
  System.EnvironmentVariable("DYLD_LIBRARY_PATH") = MacOsFolder.NativePath
  If System.EnvironmentVariable("DYLD_LIBRARY_PATH") = "" Then
    MessageBox("DYLD_LIBRARY_PATH variable not set")
    return
  end if
  var LibFile as FolderItem = MacOsFolder.Child("libsapnwrfc.dylib")
  var LibPath As String = LibFile.parent.NativePath
  Call RFCModuleMBS.SetCurrentWorkingDirectory(libPath)
EndIf</pre>



<p>I’ve copied the SAP libraries with the Xojo build settings into the application resource folders.&nbsp;</p>



<p>If the setting of the LibPath fails then send the error message:</p>



<pre class="wp-block-preformatted">If not RFCModuleMBS.LoadLibrary(LibFile) Then
  // Failed to load library
  Messagebox RFCModuleMBS.LibraryLoadErrorMessage
  return
End If </pre>



<p>And if the LibPath is set you can do the logon as second step:</p>



<pre class="wp-block-preformatted">var loginParams As New Dictionary
loginParams.Value("ashost") = "12.345.67.89"
loginParams.Value("sysnr")  = "10"
loginParams.Value("client") = "100"
loginParams.Value("user")   = "MYUSERNAME”
loginParams.Value("passwd") = "MyPassword"
loginParams.Value("lang")   = "EN"
var ConnectionToSAP As New RFCConnectionMBS(loginParams) </pre>



<p>Please note if you have a router string you must build the host name (ashost) with a concatenation of router string and host name like this:</p>



<pre class="wp-block-preformatted">loginParams.Value("ashost") = &lt;router string&gt; + "/H/" + &lt;host name&gt;</pre>



<p>If the connection fails you will get the reason with:</p>



<pre class="wp-block-preformatted">Exception r As RFCErrorExceptionMBS
 MessageBox r.message </pre>



<h3 class="wp-block-heading">Calling an SAP Function Module</h3>



<p>If you are calling a SAP Function Module you will export key values to SAP and you will receive data or i.e. error messages. To understand the import and export parameters you must look out of the SAP function module in the surrounding world.</p>



<p>This example calls the SAP function module RFC_READ_TABLE. With this standard RFC module you can get the content of a database table and/or the SAP data dictionary description of this table.</p>



<h4 class="wp-block-heading">Exporting key values to SAP</h4>



<p>For exporting the key values to the SAP function module you must load a functions description and create a data container for executing the function module.</p>



<pre class="wp-block-preformatted">var fd as RFCFunctionDescriptionMBS = app.ConnectionToSAP.FunctionDescription("RFC_READ_TABLE")
var f as RFCFunctionMBS = fd.CreateFunction </pre>



<p>The function module RFC_READ_TABLE has two parameters:</p>



<ul class="wp-block-list"><li>the name of the table as import parameter: QUERY_TABLE</li><li>the select options of the where clause as tables parameter: OPTIONS</li></ul>



<pre class="wp-block-preformatted">f.StringValue("QUERY_TABLE") = "&lt;name of the table&gt;"

var it_OPTIONS as RFCTableMBS = f.TableValue("OPTIONS")
var is_OPTIONS as RFCStructureMBS

is_OPTIONS = it_OPTIONS.AppendNewRow
is_OPTIONS.StringValue("TEXT") = "(MATNR = '4711')" // WHERE clause</pre>



<p>You must consider that the maximum length of a where clause for the table OPTIONS is 72 digits. If the where clause length is greater than 72 you must split the clause to several lines. The clause must look like this “(MATNR = ‘1234’ AND WERKS = ‘1000’) OR (MATNR = ‘3456’ AND WERKS = ‘1000’)”.&nbsp;</p>



<p>And now you can execute the function module into the backend system:</p>



<pre class="wp-block-preformatted">f.invoke</pre>



<h4 class="wp-block-heading">Receiving data from SAP</h4>



<p>The function module RFC_READ_TABLE returns now to tables parameters:</p>



<ul class="wp-block-list"><li>FIELDS – contains the SAP data dictionary description of the returned table</li><li>DATA – contains the data found for the transferred where clauses</li></ul>



<pre class="wp-block-preformatted">TableFields as RFCTableMBS = f.TableValue("FIELDS")
TableData as RFCTableMBS = f.TableValue("DATA") </pre>



<p>If the TableFields.RowCount = 0 then the returned table contains no data. To get the content of a returned table you must loop like this:</p>



<pre class="wp-block-preformatted">If TableData.RowCount &gt; 0 then
  TableData.MoveToFirstRow
End if
For iRow as integer = 1 to TableData.RowCount
  // get a field value
  Var FieldValue as string = TableData.StringValue("&lt;Fieldname in the table record&gt;")
  If iRow &lt; TableData.RowCount then
    TabeData.MoveToNextRow
  End if
next</pre>



<h4 class="wp-block-heading">Error Handling</h4>



<p>To catch an exception, you should code into your method something like this:</p>



<pre class="wp-block-preformatted"> Exception r As RFCErrorExceptionMBS
  MessageBox r.message </pre>



<h4 class="wp-block-heading">Interpretation of Returned Data</h4>



<p>If you want to get after the INVOKE the returned data you will have&nbsp;</p>



<ul class="wp-block-list"><li>a table or</li><li>a structure or</li><li>a field</li></ul>



<p>If you have a table you will get a certain field with:</p>



<pre class="wp-block-preformatted">Var TableContent as RFCTableMBS
TableContent = f.TableValue("&lt;Name of the returned table parameters&gt;")
If TableContent.RowCount &gt; 0 then
  TableContent.MoveToFirstRow
End if
For iRow as integer = 1 to TableContent.RowCount
  ListBox1.AddRow(TableContent.StringValue("FieldOne"), TableContent.StringValue("FieldTwo"))
  If iRow &lt; TableContent.RowCount then
    TableContent.MoveToNextRow
  End if
Next</pre>



<p>If you have a structure you will get a certain field with:</p>



<pre class="wp-block-preformatted">var s As RFCStructureMBS = f.StructureValue("ES_MESSAGE")</pre>



<pre class="wp-block-preformatted">TextField1.Value = s.StringValue("FieldOne")</pre>



<p>If you have a field you will get the data with:</p>



<pre class="wp-block-preformatted">TextField1.Value = f.StringValue("FieldName")</pre>



<p>Using the above techniques with the MBS plugin, your Xojo apps can now access information contained in SAP.</p>



<p><em>Michael Eckert studied economics from 1982-1986 and has been employed at T-Systems as a software architect since 1989. Michael has worked with ERP systems for 34 years, until 1998 with PL/1, since 1998 with ABAP in SAP R/3 and SAP S/4 HANA. He&#8217;s been developing with Xojo for about 9 years.</em></p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
