SAPRfc
SAP::Rfc - Ruby extension for performing RFC Function calls against an SAP R/3 System.
require "SAP/Rfc"
# please note: the old style of unamed parameters nolonger works
# all parameters are named when creating the SAP::Rfc object
# WAS => rfc = SAP::Rfc.new("localhost", 18, "EN", 000, "DEVELOPER", "19920706", 1)
# NOW
rfc = SAP::Rfc.new(:ashost => "localhost",
:sysnr => 18,
:lang => "EN",
:client => 000,
:user => "DEVELOPER",
:passwd => "19920706",
:trace => 1)
# get the connection ID
print "connect id: ", rfc.connection, "\n"
# test the connection
print "is_connected: ", rfc.is_connected(), "\n"
# get the system information
print "sapinfo: "
p rfc.sapinfo()
# lookup the interface for RFC_READ_TABLE
itab = rfc.discover("RFC_READ_TABLE")
# set some interface parameters
itab.query_table.value = "TRDIR"
itab.delimiter.value = "|"
itab.rowcount.value = 10
# put a rows into table OPTIONS
itab.options.value = ["NAME LIKE 'SAPL\%RFC\%'"]
# do the RFC call
rfc.call(itab)
# access the results of a table
itab.data.nextHashRow {|h| print "GOT A HASH: "; p h }
print "close connection: ", rfc.close(), "\n"
Alternatively for registered RFC applications:
require "lib/SAP/Rfc"
# create a connection object that can talk to the gateway
rfc = SAP::Rfc.new(:trace => 1,
:tpname => "wibble.rfcexec",
:gwhost => "localhost",
:gwserv => "3300")
# create an interface object that describes the RFC that SAP will call out to
iface = SAP::Iface.new("RFC_REMOTE_PIPE")
iface.addParm( SAP::Parm.new("COMMAND", nil, RFCIMPORT, RFCTYPE_CHAR, 256) )
iface.addParm( SAP::Parm.new("READ", nil, RFCIMPORT, RFCTYPE_CHAR, 1) )
iface.addParm( SAP::Tab.new("PIPEDATA", nil, 80) )
# specify the callback
iface.callback = Proc.new do |iface|
call = `#{iface.COMMAND.value()}`
call.split(/\n/).each do |val|
iface.PIPEDATA.value.push(val.ljust(80))
end
end
# add the interface to the RFC collection
rfc.iface(iface)
# start off the main loop
rfc.accept()
The best way to describe this package is to give a brief over view, and then launch into several examples. The SAP::Rfc Class works in concert with several other Classes that also come with same distribution, these are SAP::Iface, SAP::Parm, SAP::Tab, and SAP::Struc. These come together to give you an object oriented programming interface to performing RFC function calls to SAP from a UNIX based platform with your favourite programming language - Ruby. An SAP::Rfc object holds together one ( and only one ) connection to an SAP system at a time. The SAP::Rfc object can use one or many SAP::Iface objects, each of which equate to the definition of an RFC Function in SAP ( see trans SE37 ). Each SAP::Iface object holds one or many SAP::Parm, and/or SAP::Tab objects, corresponding to the RFC Interface definition in SAP ( SE37 ). For all SAP::Tab objects, and for complex SAP::Parm objects, a SAP::Struc object can be defined. This equates to a structure definition in the data dictionary ( see trans SE11 ). Because the manual definition of interfaces and structures is a boring and tiresome exercise, there are specific methods provided to automatically discover, and add the appropriate interface definitions for an RFC Function module to the SAP::Rfc object ( see methods discover, and structure of SAP::Rfc ).
In the interests of performance it is possible to cache the results of Interface and Structure discovery - each of which require RFC calls to R/3 to determine their makeup.
To switch on the caching call SAP::Rfc.useCache = true. The location of the cache repository can be controlled by calling SAP:;Rfc.cache = "/some/directory" . The default cache directory is .rfc_cache/ - which is relative to the current working directory at run time. Caching makes use of the standard ruby serialisation mechanism Marshal.
SAPRfc
SAP::Rfc.new(:ashost => "localhost",creates a new RFC connection object.
All parameters are named (passed via a hash): Outbound RFC (client -> SAP R/3) parameters - :ashost :sysnr :lang :client :user :passwd Inbound RFC (Registered RFC - SAP R/3 -> Client) parameters - :tpname :gwhost :gwserv Both - :trace
ashost - Hostname connected tosysnr - System number to connected tolang - Language logged inclient - Client number logged in touser - User namepasswd - Passwordtpname - the R/3 gateway TPNAMgwhost - R/3 Gateway hostgwserv - R/3 Gateway service numbertrace - Trace mode of connectionconnection - The connection IDmysapsso2 - SSO2 ticket to use instead of User/Passwdgetsso2 - Have R/3 create a SSO2 ticketSAP::Rfc#get_ticketReturns the ticket if :getsso2 was set to 1 when connecting and if the SAP system supports creating SSO2 tickets.
SAP::Rfc#discover(name="RFC_READ_REPORT")Used to look up the definition of an RFC interface. Returns an instance of SAP::Iface. This also automatically defines any associated SAP::Parm, SAP::Tab, SAP::Struct, and SAP::Field objects that come together to describe a complete RFC Interface.
SAP::Rfc#structure(name="TDIR")Discover and return the definition of a valid data dictionary structure. This could be subsequently used in association with an SAP::Parm, or SAP::Tab object. Returns a SAP::Struct object.
SAP::Rfc#is_connectedTest that the SAP::Rfc object is still connected to the SAP system. Returns true or false.
SAP::Rfc#sapinfoReturn a hash of the values supplied by the RFC_SYSTEM_INFO function module. This function is only properly called once, and the data is cached until the RFC connection is closed - then it will be reset next call.
SAP::Rfc#call(iface=SAP::Iface object)Do the actual RFC call - this installs all the Export, Import, and Table Parameters in the actual C library of the extension, does the RFC call, Retrieves the table contents, and import parameter contents, and then cleans the libraries storage space again.
SAP::Rfc#iface(iface=SAP::Iface object)Add an interface to the RFC collection that defines what registered RFC calls will be handled - see SAP::Iface documentation.
SAP::Rfc#accept()Kicks off the main event loop for registered RFC applications. This is where SAP::Rfc calls out to the RFC library to register the applications with the SAP R/3 gateway.
SAP::Rfc#closeClose the current open RFC connection to an SAP system.
SAP::Rfc#resetContextReset the ABAP user Context of the current open RFC connection to an SAP system.
SAP::Iface - Ruby extension for parsing and creating an Interface Object. The interface object would then be passed to the SAP::Rfc object to carry out the actual call, and return of values.
Generally you would not create one of these manually as it is far easier to use the "discovery" functionality of the SAP::Rfc#discover("RFCNAME") method. This returns a fully formed interface object. This is achieved by using standard RFCs supplied by SAP to look up the definition of an RFC interface and any associated structures.
for registered RFC applications
require "SAP/Rfc"
iface = SAP::Iface.new("RFC_REMOTE_PIPE")
iface.addParm( SAP::Parm.new("COMMAND", nil, RFCIMPORT, RFCTYPE_CHAR, 256) )
iface.addParm( SAP::Parm.new("READ", nil, RFCIMPORT, RFCTYPE_CHAR, 1) )
iface.addParm( SAP::Tab.new("PIPEDATA", nil, 80) )
iface.callback = Proc.new do |iface|
call = `#{iface.COMMAND.value()}`
call.split(/\n/).each do |val|
iface.PIPEDATA.value.push(val.ljust(80))
end
end
rfc.iface(iface)
rfc.accept()
or more commonly:
require "SAP/Rfc"
rfc = SAP::Rfc.new( ... )
iface = rfc.discover('RFC_READ_REPORT')
iface.program.value = "SAPLGRFC"
rfc.call(iface)
None
SAP::Iface.new(name="Z_AN_RFC")creates a new RFC Interface object.
name - Name of the interfaceparms - Array of interface parameter objectsSAP::Iface#<name of a parameter>require "SAP/Rfc"
rfc = SAP::Rfc.new(...)
itab = rfc.discover("RFC_READ_TABLE")
itab.query_table.value = "TRDIR"
Returns the object of the given parameter either an SAP::Tab, or SAP::Parm object.
SAP::Iface#addParm(<SAP::Parm | SAP::Tab>)Add an RFC interface parameter to the SAP::Iface definition - see SAP::Parm, and SAP::Tab
SAP::Iface#getParm(name="name of parameter")Get a named parameter object - returns the object either a SAP::Parm or SAP::Tab instance.
SAP::Iface#resetEmpty all the tables and reset paramters to their default values - useful when you are doing multiple calls.
SAP::Parm - Ruby extension for parsing and creating an SAP parameter to be added to an RFC Interface.
Generally you would not create one of these manually as it is far easier to use the "discovery" functionality of the SAP::Rfc#discover("RFCNAME") method. This returns a fully formed interface object. This is achieved by using standard RFCs supplied by SAP to look up the definition of an RFC interface and any associated structures.
require "SAP/Rfc" eparam = SAP::Parm.new(name, structure, RFCEXPORT, datatype, intlen, decs, default, default)
None
SAP::Parm.new(name="a name", structure="structure if complex", RFCEXPORT | RFCIMPORT, datatype="SAP datatype", intlen="internal parameter length", decs="decimal places", value="value", default="default value for reset")creates a new RFC Interface Parameter object. This is either an import or export parameter (Export for parameters going into a call, Import for parameter values as a result of a call).
name - Name of the parametertype - type either RFCEXPORT | RFCIMPORTintype - Internal SAP data typelen - Length of the parameter value storeddecimals - number of decimal places | 0default - default value as specified by the Interface definition in SE37structure - SAP::Struct object for complex paramter types | nilchanged - true | false if a parameter has been changedvalue - external representation of current parameter valueintvalue - internal (SAP) representation of current parameter valueSAP::Parm#resetReset the parameter value to its default
SAP::Parm#value=(value="some value")Assign the value of the parameter - automatically converts the external (Ruby) value to the internal SAP representation.
SAP::Tab - Ruby extension for parsing and creating Tables to be added to an RFC Interface.
Generally you would not create one of these manually as it is far easier to use the "discovery" functionality of the SAP::Rfc#discover("RFCNAME") method. This returns a fully formed interface object. This is achieved by using standard RFCs supplied by SAP to look up the definition of an RFC interface and any associated structures.
require "SAP/Rfc" tab = SAP::Tab.new(name="table name", structure=SAP::Struct, len=int, value=Array))
None
SAP::Tab.new(name="table name", structure=SAP::Struct, len=int, value=Array))creates a new RFC Interface Table object. Tables are populated with rows of data to pass into an RFC call, and then refresed with the results of the call afterwards.
name - Name of the parameterlen - Length of the parameter value storedstructure - SAP::Struct object for complex paramter types | nilvalue - access to the Array object containing the rows of the table (use push to add to it)SAP::Tab#resetReset the parameter value to its default
SAP::Tab#emptyAlias for reset
SAP::Tab#value=(value=Array)Pass in an Array object of rows, that are converted and assigned to the table.
SAP::Tab#hashRows { |h| code block }Yields to a code block a Hash object representing the name/value pairs for each field of a row of table data - does not shift the values off the table value Array.
SAP::Tab#rowsreturns an Array of Hash objects representing the name/value pairs for each field of a row of table data - does not shift the values off the table value Array.
SAP::Tab#nextHashRow { |h| code block }Yields to a code block a Hash object representing the name/value pairs for each field of a row of table data - shifts the values off the table value Array, emptying the contents.
SAP::Struct - Ruby extension for parsing and creating Structure definitions to be added to an RFC Parameter and Table objects.
Generally you would not create one of these manually as it is far easier to use the "discovery" functionality of the SAP::Rfc#discover("RFCNAME") method. This returns a fully formed interface object. This is achieved by using standard RFCs supplied by SAP to look up the definition of an RFC interface and any associated structures.
require "SAP/Rfc" s = SAP::Struct.new(name="struct_name") s.addField( SAP::Field.new(field, exid, decs, intlen, off) ...
or more commonly:
require "SAP/Rfc"
rfc = SAP::Rfc.new(...)
str = rfc.structure("TRDIR")
None
SAP::Struct.new(name="DDIC structure name"))creates a new RFC Structure object. You must subsequently add fields to this structure for it to be of any use. The resulting structure object is then used for SAP::Parms, and SAP::Tab objects to manipulate complex data elements. This is normally created through the SAP::Rfc#structure('STRUCT_NAME') method that does an auto look up of the data dictionary definition of a structure, or as a result of SAP::Rfc#discover ( which create an entire interface definition).
name - Name of the Structurefields - an Array of the fields of the structureSAP::Struct#addField(field=SAP::Field)Add a field object to the structure definition
SAP::Struct#getField(name="field name")Get a SAP::Field object from the structure by name.
SAP::Struct#value=(value=String)Set the value of a structure - this automatically unpacks the string into the structure objects list of fields, and doe sthe SAP to Ruby data type conversions. Returns a Hash object of the fieldname/value pairs of the structure.
SAP::Struct#valueAutomatically packs the current value of all the structure fields into the structure and returns the complete value as a string (in all the appropriate SAP data types)
SAP::Field - Container for what is a field within an SAP::Struct object
Generally you would not create one of these manually as it is far easier to use the "discovery" functionality of the SAP::Rfc#discover("RFCNAME") method. This returns a fully formed interface object. This is achieved by using standard RFCs supplied by SAP to look up the definition of an RFC interface and any associated structures.
require "SAP/Rfc" f = SAP::Field.new(field, type, decs, intlen, off) ...
None
SAP::Field.new(field, type, decs, intlen, off)Create a new field object - these are normally created through the SAP::Rfc#structure('STRUCT_NAME') method that does an auto look up of the data dictionary definition of a structure, or as a result of SAP::Rfc#discover ( which create an entire interface definition).
name - Name of the fieldintype - Internal SAP data typelen - Length of the field value storedoffset - offset in the structuredecimals - number of decimal places | 0value - external representation of current parameter valueSAP::Field#value=(value=<something>)Assign the value of the field, and then set the length
saprfc is Copyright (c) 2003-2006 Piers Harding. It is free software, and may be redistributed under the terms specified in the README file of the Ruby distribution.
Author:: Piers Harding <piers@ompka.net> Requires:: Ruby 1.6.7 or later