cancel
Showing results for 
Search instead for 
Did you mean: 

Sum quantities in message mapping

valter_oliveira
Active Contributor
0 Kudos

Hello there.

I'm trying to map a xml message with items (material/quantity) into another one with exact same structure but collecting the lines by material.

The XML's structure is like:


header_fields ...
<items>
  <item>
    <matnr>1</matnr>
    <qty>1</qty>
  </item>
  <item>
    <matnr>2</matnr>
    <qty>10</qty>
  </item>
 <item>
    <matnr>1</matnr>
    <qty>5</qty>
  </item>
</items>

When mapping <item> tag, I used a user-defined function Like this:


public void addMaterial(String[] material,ResultList result,Container container){
Vector vMats = new Vector();
for (int i = 0; i < material.length; i++ ){
   if (!vMats.contains(material<i>)){
      vMats.addElement(material<i>);
   }   
}
for (int i = 0; i < vMats.size()-1; i++){
	result.addValue("");
}

This is working well (I think) because i only get different materials in output queque in mapping.

Now, I want to actually calculate quantities, mapping qty tag, collected by material, and i'm trying something like:


public void sumQuantities(String[] material,String[] units,ResultList result,Container container){
Vector vMats = new Vector();
Vector vQuant = new Vector();

for (int i = 0; i < material.length; i++ ){
   if (!vMats.contains(material<i>)){
      vMats.addElement(material<i>);
      vQuant.addElement(units<i>);
   }   
  else {
???????????????
   }
}

for (int i = 0; i < vQuant.size()-1; i++){
	result.addValue("");
}

I'm creating a vector vMats to have an array with not repeated material, and a vQuant array to sum quantities. There is the ???? part ...

I'm sorry for the SIMPLE question but i'm an abaper trying a bit in the java workd

The needed result is:


header_fields ...
<items>
  <item>
    <matnr>1</matnr>
    <qty>6</qty>
  </item>
  <item>
    <matnr>2</matnr>
    <qty>10</qty>
  </item>
</items>

Regards,

Valter Oliveira.

Accepted Solutions (0)

Answers (3)

Answers (3)

Former Member
0 Kudos

Hi,

As per the query I believe you can do it using graphical mapping itself.

Kindly try this out:

Quantity----

Format By Example(Node Function)---add(arithmeticfunction)--- Quantity

Material-----

Please take care of the context here, bothe Quantity and Material should be having the same context. I think this will wotk easily and if you want to keep sort function that also can be provided as per the need.

Regards,

Nutan

stefan_grube
Active Contributor
0 Kudos

You can do this easily with standard function, when you sort the nodes.

If your structure is very complex, you should sort with an XSLT mapping as separate mapping step.

Otherwise you can use the sort function of the mapping tool.

This blog could give some ideas:

/people/stefan.grube/blog/2005/12/29/new-functions-in-the-graphical-mapping-tool-xi-30-sp13

VijayKonam
Active Contributor
0 Kudos

>


> public void sumQuantities(String[] material,String[] units,ResultList result,Container container){
> Vector vMats = new Vector();
> Vector vQuant = new Vector();
> 
> for (int i = 0; i < material.length; i++ ){
>    if (!vMats.contains(material<i>)){
>       vMats.addElement(material<i>);
>       vQuant.addElement(units<i>);
>    }   
>   else {
>            int p = vMats.indexOf(material<i>);
              int sumQuant = vQuant<i> + vQuant[p]
              vQuant.set(p, sumQuant);
>    }
> }
> 
> for (int i = 0; i < vQuant.size()-1; i++){
> 	result.addValue("");
> }
> 

> I'm creating a vector vMats to have an array with not repeated material, and a vQuant array to sum quantities. There is the ???? part ...

>

Not sure if it works but definitely you can try.

VJ

valter_oliveira
Active Contributor
0 Kudos

Hello VJ.

Thanks for your input. There were some problems in the type convertion in your code, but using your idea with small changes found in java foruns I got one of the possible solutions (probably not the best one). I've tryied it with several complex combinations and so far so good ... always got what we need.

The code for the 3 UDF's that I created is:

For <Item> (non-repeated materials)


public void additem(String[] material,ResultList result,Container container){
Vector vMats = new Vector();
for (int i = 0; i < material.length; i++ ){
   if (!vMats.contains(material<i>)){
      vMats.addElement(material<i>);
      result.addValue("X");
   }   
} 
} 

For <matnr> (non-repeated materials)


public void addmaterial(String[] material,ResultList result,Container container){
Vector vMats = new Vector();
for (int i = 0; i < material.length; i++ ){
   if (!vMats.contains(material<i>)){
      vMats.addElement(material<i>);
      result.addValue(material<i>);
   }   
} 
}

For <qty> (collected by material)


public void sumQuantities(String[] material,String[] units,ResultList result,Container container){
Vector vMats = new Vector();
Vector vQty = new Vector();

for (int i = 0; i < material.length; i++ ){
   if (!vMats.contains(material<i>)){
              vMats.addElement(material<i>);
              vQty.addElement(units<i>);
   }   
  else {
              int p = vMats.indexOf(material<i>);
              int actual = Integer.parseInt(units<i>);
              String[] aux = (String[])vQty.toArray(new String[vQty.size()]); 
              int previous = Integer.parseInt(aux[p]);
              int sum = actual + previous;
              String strsum = Integer.toString(sum);
              vQty.set(p, strsum);
   }
}
String[] end = (String[])vQty.toArray(new String[vQty.size()]); 
for (int i = 0; i < vQty.size(); i++){
	result.addValue(end<i>);
}
}

After the UDF's, to achieve <matnr> and <qty> in output XML, I had to use SPLIT by VALUE.

I'll keep this open for a while to see if anyone has a better solution.

Regards,

Valter Oliveira