cancel
Showing results for 
Search instead for 
Did you mean: 

Advanced User Function

helmut_berger
Explorer
0 Kudos

Hi all,

I am new to XI and Java and hope that some can help me with the following problem:

I need to map two structures. One is a RFC function

module with two tables

material     (contains material data (key is matnr))
materialtext (material texts in more than one language (key is matnr textid language and line))

Source structure:

<E_MATERIAL>
      <item>
         <MANDT>201</MANDT>
         <MATNR>4711</MATNR>
         <ERSDA>01.01.2006</ERSDA>
		...
      </item>
      <item>
         <MANDT>201</MANDT>
         <MATNR>4712</MATNR>
         <ERSDA>02.01.2006</ERSDA>
		...
      </item>
</E_MATERIAL>
<E_MATERIALTEXT>
      <item>
         <MANDT>201</MANDT>
         <MATNR>4711</MATNR>
         <SPRAS>EN</SPRAS>
         <TDID>MVKE</TDID>
         <LINE>1</LINE>
         <TDLINE>textline 1</TDLINE>
      </item>
      <item>
         <MANDT>201</MANDT>
         <MATNR>4711</MATNR>
         <SPRAS>EN</SPRAS>
         <TDID>MVKE</TDID>
         <LINE>2</LINE>
         <TDLINE>textline 2</TDLINE>
      </item>
      <item>
         <MANDT>201</MANDT>
         <MATNR>4711</MATNR>
         <SPRAS>DE</SPRAS>
         <TDID>MVKE</TDID>
         <LINE>1</LINE>
         <TDLINE>Textzeile 1</TDLINE>
      </item>
</E_MATERIALTEXT>

The target structure looks like this:

<product> 
  <matnr>4711</matnr>
  <...>
  <descriptions>
    <description textid="MVKE" language="EN"
       <line number=1>textline 1</line>
       <line number=2>textline 2</line>
    </description>
    <description textid="MVKE" language="DE"
       <line number=1>Textzeile 1</line>
    </description>

  </descriptions>
</product>

The element <descritption> is optional and each text can consist of multiple lines and can be transmitted in multiple languages.

I have to check for each material, wether at least one line exists in materialtexts an generate an element <descriptions>.

That is not that difficult.

But the number of the next tag <description> is dependend of the four elements matnr tdid spras and line. How can I achieve this

mapping via a user defined function?

I searched the documentation and web for hours, but I can not find a hint how to solve this problem.

I tried to put the relevant values into a HashMap with key matnr and a inner class object (with the keys) as value.

That works well in Eclipse but not in XI.

Thanks in advance for any help!

Helmut

Accepted Solutions (1)

Accepted Solutions (1)

stefan_grube
Active Contributor
0 Kudos

Hi Helmut,

I thought, there must be a solution with standard function, and finally I found one:

MATNR SPRAS

concat(delimiter = 12 spaces)

TDID

concat

removeContexts

SplitByValue(valueChanged)

collapseContexts

substring(0,12)

SplitByValue(valueChanged)

-> description

For line I have:

MATNR SPRAS

concat

TDID

concat

removeContexts

TDLINE

formatByExample

-> line

The attributes:

SPRAS MATNR

concat

TDID

concat

removeContexts

SplitByValue(valueChanged)

collapseContexts

substring(0,2)

-> language

TDID MATNR

concat

SPRAS

concat

removeContexts

SplitByValue(valueChanged)

collapseContexts

substring(0,4)

-> textid

Regards

Stefan

helmut_berger
Explorer
0 Kudos

Hello all,

thank you for your answers. I was now able to solve my problem (with some slight modifications)

Kind Regards

Helmut

Answers (4)

Answers (4)

STALANKI
Active Contributor
0 Kudos

Hi helmut,

write a advanced user defined function which takes 3 parameters matnr(a),spras(b),tdid(c).

set the contexts of matnr,spras,tdid to root level and use the algo below..

String merge3Arrays[];

for(int k=0;k<a.length;k++)

merge3Arrays[k] = a[k]”!”b[k]”!”c[k];

//sort merge3Arrays.write java syntax for the same

//Delete duplicates from merge3Arrays.write java syntax for the same.

for(int k=0;k<merge3Arrays.length;k++)

result.addValue(" ");

//this will give you generates the number of description fields.

//if you want values in the descripton then replace space in the above step with the value.

//Note:you have to take care of inserting contexts.

read the blogs by me and stefan.You will definetly find it helpful.

/people/stefan.grube/blog/2005/12/30/test-user-defined-functions-for-the-xi-graphical-mapping-tool-in-developer-studio

Former Member
0 Kudos

Hi Helmut

Recently I had similar use case and also found out that XI doesn't support inner classes I think it is a bug and it will be fixed with next SP.

But for a while I used the following solution and I thing it can help you. Instead of inner class and the code


 class Record{
  public Record(String _a, String _b, String _c){
    a= _a;
    b= _b;
    c= _c;
  }
  String a;
  String b;
  String c;
 }

 Map map = new HashMap();
 String key =...
 map.put(key, new Record("1", "2", "3"));

You can use the following workaround


 Map map = new HashMap();
 String key =...
 map.put(key+"a", "1");
 map.put(key+"b", "2");
 map.put(key+"c", "3");
 //and the same to get value
 String valueOfC = (String)map.get(key+"c");

Hope it will help.

Best regards

Dmitry Yankovsky

STALANKI
Active Contributor
0 Kudos

Did you have a look at mapping patterns guide in service market place?

helmut_berger
Explorer
0 Kudos

Hello Sravya,

yes I know these documents. But I could not

find a solution for my specific problem.

Kind regards

Helmut

Former Member
0 Kudos

Can you use the follow structure ?

<line>

<number>1</number>

<description>TextLine 1</description>

</line>

<line>

<number>2</number>

<description>TextLine 2</description>

</line>

You can create the number in the RFC.

helmut_berger
Explorer
0 Kudos

Hello Evandro,

thank you for your answer.

The target structure is fixed an I can't change it.

The problem is, how can I produce the right

context changes for the target nodes depending

on the keys matnr tdid and spras and assign the elements

to the right product.

Kind regards

Helmut

Former Member
0 Kudos

Helmut,

I did the folowing test:

FileOut

Record Element

Row Element xsd:string 0..ubounded

Number Attribute xsd:string required

in Row Element

[value you want] -


> Row

in "Number" attribule:

function"counter" -


> @Number

helmut_berger
Explorer
0 Kudos

Hello Evandro,

my problem is not to generate the numbers for the text lines.

I am sorry if my question was not clear enough.

For example for the tag <description> I have to generate

this node for every text for a specific product. The text is

identified by material number(Matnr), Textid (TDID) and Language(Spras). The

text can consist of multiple lines, therfore I get a line number.

Example for the contents of the table I get:

MATNR TDID SPRAS Line TDLINE

4711 MVKE EN 1 This is line 1 in English

4711 MVKE EN 2 This is line 2 in English

4711 MVKE DE 1 This is line 1 in German

4712 MVKE EN 1 This is line 1 in English

For this example I have to produce 2 occurances of tag <descriptions> for Material 4711

because the first two lines belong to the same text (4711, MVKE, EN) and the third line

belongs to the second text (4711, MVKE, DE).

In the mean time I have created a advanced user defined function

(prod is the material number of <material>).

The values stored in s are not used yet, but I need them

in an other function and want to store them in a container.

But I think that there is an easier solution for the problem.

public void GetDescr(String[] prod,String[] matnr,String[] tdid,String[] 
                     spras,ResultList result,Container container){

String LastMatnr = " ";
String LastTdid = " ";
String LastSpras = " ";

int j = 0;


ArrayList DescrList = new ArrayList();
HashMap hm = new HashMap();

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

	if (!LastMatnr.equals(matnr<i>)
	    || !LastTdid.equals(tdid<i>)
	    || !LastSpras.equals(spras<i>)) {

		if (LastMatnr.equals(matnr<i>)) {
			String[] s = new String[3];
			s[0] = matnr<i>;
			s[1] = tdid<i>;
			s[2] = spras<i>;
			
			DescrList.add(j, s);
			j++;
		} else {
			if (i > 0) {
				hm.put(matnr<i>, DescrList);
			}

			DescrList = new ArrayList();
			j = 0;
			String[] s = new String[3];
			s[0] = matnr<i>;
			s[1] = tdid<i>;
			s[2] = spras<i>;

			DescrList.add(j, s);
			j++;
		}

		LastMatnr = matnr<i>;
		LastTdid = tdid<i>;
		LastSpras = spras<i>;
	}
	hm.put(matnr<i>, DescrList);
} 

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

	ArrayList d = (ArrayList) hm.get(prod<i>);
	if (d != null) {
		for (j = 0; j < d.size(); j++) {
			String[] y = (String[]) d.get(j);
			result.addValue(" ");
		}
		result.addContextChange();
	} else {
		result.addContextChange();
	}

}
}

I would be grateful for any comments.

Kind regards

Helmut

stefan_grube
Active Contributor
0 Kudos

Hi Helmut,

my first comment is: Please exchange all variables <b>i</b> with another value like <b>k</b>

[ + i + ] cannot be shown, as it is the font format code for italic.

Regards

Stefan