Skip to Content
Author's profile photo Daniel Güntner

SAP XI/PI/PO Mapping tricks and UDF samples

Hi all

This blog should give you some examples how the graphical mapping can be done without bad results.

This is only a proposal and my experience, this should not mean that there is no other solution.

But maybe it is helpful for some PI developer without SAP Mapping Training or deep experience.

We all know that the graphical tool looks very easy.

But to get a waterproof mapping and not only a LuckyPunch success you really need to know how it works.

I think and know

  • 99,9% of all mappings can be done by using graphical mapping tool
  • If you know how the target queue must look like then you can start with development
  • All other approach is trail & error with LuckyPunch result

Below you will find a summary of the most needed actions from my point of view.
(…and in this blog you can copy and paste the UDF code… )

IF Function

It looks easy but I saw a lot of garbage in the past.

So please notice: the two input “Queues” must have same number of values and same structure (ContextChanges). If not you have to think about this.
Maybe “MapWithDefault” or change Context can help!

Target Element should only appear one time but source element is multiple.

Most solutions I saw have used CopyValue[0] or “RemoveContext” in combination “CollapsContext”.

Please be care full by using these 3 functions. I like to use “sum” for this.

equalS vs. FixFalue

Sometimes a FixValue Table is better than equalS

How to combine different hierarchies or levels (useOneAsMany and formatByExample)

Sometimes the target structure has 3 Elements which are relevant for one target field.

Sample: If qualifier of each position has value XY then value the Text of sub segment should be used.

(all of us know TDLINE Problems)

UDF: GetSystemname and SetFileName

String sysName = “EMPTY”;


sysName = (String) System.getProperty(“SAPSYSTEMNAME”);

}catch(Exception e) {

sysName = “ERROR”;


return sysName;

String filename = new String(“EMPTY”);

DynamicConfiguration conf1 = (DynamicConfiguration) container.getTransformationParameters().get(StreamTransformationConstants.DYNAMIC_CONFIGURATION); DynamicConfigurationKey key1 = DynamicConfigurationKey.create(“http:/”+”/”,”FileName”);

filename = var1;



}catch(Exception e) {



return filename;


UDF: how to handle SUPPRESS and CC


for ( int i = 0; i <  var1.length; i++){

if( var1[i].equals(ResultList.CC)){

result.addValue(“found CC”);


if( var1[i].equals(ResultList.SUPPRESS)){

result.addValue(“found SUPPRESS”);



}//end els

}//end else

}//end for


//below how to set SUPPRESS und CC in UDF




}catch(Exception e) {


}//end try

UDF: how to put all values of one CC into one target field (concat)

String stringle = “”;


for ( int i = 0; i <  var1.length; i++){

if(! var1[i].equals(ResultList.CC)){

stringle = stringle + var1[i];

}//end if

}//end for


}catch(Exception e) {


}//end try


UDF: to convert number to decimal

String in = var1.trim();


try {

double value = Double.parseDouble(in);

value = value / 1000d;


String res = new String (new java.text.DecimalFormat(“0.000”).format(value));

if (res.length() > 11)

res = res.substring(0, 11);

return (res);


} catch (NumberFormatException e) {

return (“ERROR ” + e.toString());


UDF: check if number. (the format number PI function throws errors, so this function helps to avoid mapping error)

String ret;

int i = 0;

ret = “false”;



i = Integer.valueOf(var1).intValue();

ret = “true”;


}catch ( Exception e){

ret = “false”;



return ret;


UDF: channelJump during mapping (asy)

MappingTrace trace;

trace = container.getTrace();


String back=”default”;



back = “start”;

//instance the channel to invoke the service.

Channel channel = LookupService.getChannel(“”,BS,CC);

SystemAccessor accessor = LookupService.getSystemAccessor(channel);

//payload xml

InputStream inputStream =new ByteArrayInputStream(payload.getBytes());

XmlPayload xmlpayload = LookupService.getXmlPayload(inputStream);

Payload SOAPOutPayload = null;

//The response will be a Payload. Parse this to get the response field out.

SOAPOutPayload =;


/* Parse the SOAPPayload to get the SOAP Response back.

The conversion rate is available under the Field Name ConversionRateResult */

InputStream inp = SOAPOutPayload.getContent();

back = “ende”;


} catch(Exception ex) {


back = “ERROR”;


return back;


UDF: date plus or minus x days

try {
SimpleDateFormat sdf = new SimpleDateFormat(“yyyyMMdd”);
Date date = sdf.parse(var1[0],new ParsePosition(0));

Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, var2[0]);

date = cal.getTime();
String output = sdf.format(date);


} catch (Exception e) {


Assigned Tags

      You must be Logged on to comment or reply to a post.
      Author's profile photo Daniel Graversen
      Daniel Graversen

      Hi Daniel
      The functions and UDF here covers quite a lot of the UDF that I would normally create.

      There is a good amount UDF in the B2B addon that you want to try. For the set/get dynamic properties.

      Author's profile photo Daniel Güntner
      Daniel Güntner
      Blog Post Author

      Hi Daniel

      Yes with “B2B add on” or Seeburger you will have nice UDF collection.

      But this is not available for all developer. It depends on the SAP license you have.

      My intention with this blog is that PI developer should know what they are doing and in case of UDF it is very important to cover “error cases” as well.

      So the important hint from my side is: do not forget “try and catch”.

      As PI trainer for SAP education Germany and Switzerland.

      I realized that we have a big gap in the PI developer world about understanding of XML structure and meaning of queue context.

      I like the graphical mapping tool and the “display Queue” option.
      But I see a big gap in case of Mapping quality.

      Does they really know what they are doing or is this only a LuckyPunch?


      This is the reason why I started to write blogs (I do not like to write, but it is important that we share our deep knowledge).

      We have to help the new developer to have it easier as we in the past ?

      The most developer I know have only visit the TBIT40/BIT400 (PI/PO overall basics) but more important is the BIT460 “PI Message Mapping”.

      For all developer which are not tired about my words, use this link to get a better understanding about “Mapping Functionality in XI”.

      If you are aware about this and know how the target “Queue” has to look like then you are close to get “senior” title.

      Also please use the wonderful Test option, and do negative tests.

      Delete some Fields / Segments, duplicate some elements …

      and if your mapping will work then as well, then you are close to get “principal” on your business card ?