cancel
Showing results for 
Search instead for 
Did you mean: 

DEBMAS text mapping

Former Member
0 Kudos

Hi all,

we send DEBMAS-IDocs out of a SAP 4.7 system to XI. The target is a MS SQL db (connected via JDBC), where the segments are mapped into several tables.

I have difficulties to map texts from IDoc to SQL-table. In the SQL-DB there is only one table for customer texts, so I have to flatten header and line information in one structure in the target table.

That worked fine until in one IDoc there came a delete request for one text and one or more insert requests for other texts. I used the function "useOneAsMany" to copy the header information to the table and combined it with the line information. But because there is no line sent with the delete request the function caused an error: there are more contexts on header level than on item level.

Example:

In the IDoc are three texts, the first has to be deleted, the others have to be created. The first has no lines, the others have multiple lines.

How can I map that?

Example with data:

<E1KNA1H SEGMENT="1">

<MSGFN>003</MSGFN> /* delete function */

<TDOBJECT>KNA1</TDOBJECT>

<TDNAME>0000021321</TDNAME>

<TDID>9010</TDID>

<TDSPRASISO>EN</TDSPRASISO>

</E1KNA1H>

<E1KNA1H SEGMENT="1">

<MSGFN>005</MSGFN>

<TDOBJECT>KNA1</TDOBJECT>

<TDNAME>0000021321</TDNAME>

<TDID>9025</TDID>

<TDSPRASISO>EN</TDSPRASISO>

<E1KNA1L SEGMENT="1">

<MSGFN>005</MSGFN>

<TDFORMAT>*</TDFORMAT>

<TDLINE>Textline 1</TDLINE>

</E1KNA1L>

<E1KNA1L SEGMENT="1">

<MSGFN>005</MSGFN>

<TDFORMAT>*</TDFORMAT>

<TDLINE>Textline 2</TDLINE>

</E1KNA1L>

</E1KNA1H>

<E1KNA1H SEGMENT="1">

<MSGFN>005</MSGFN>

<TDOBJECT>KNA1</TDOBJECT>

<TDNAME>0000021321</TDNAME>

<TDID>9080</TDID>

<TDSPRASISO>EN</TDSPRASISO>

<E1KNA1L SEGMENT="1">

<MSGFN>005</MSGFN>

<TDFORMAT>*</TDFORMAT>

<TDLINE>EFTA 1</TDLINE>

</E1KNA1L>

<E1KNA1L SEGMENT="1">

<MSGFN>005</MSGFN>

<TDFORMAT>*</TDFORMAT>

<TDLINE>EFTA 2</TDLINE>

</E1KNA1L>

<E1KNA1L SEGMENT="1">

<MSGFN>005</MSGFN>

<TDFORMAT>*</TDFORMAT>

<TDLINE>EFTA 3</TDLINE>

</E1KNA1L>

</E1KNA1H>

The result should be as follows:

Action -- Customer -- Text -- ID -- SPRAS -- LINE -- TEXT

DELETE -- 0000021321 -- KNA1 -- 9010 -- EN

INSERT -- 0000021321 -- KNA1 -- 9025 -- EN -- 1 -- Textline 1

INSERT -- 0000021321 -- KNA1 -- 9025 -- EN -- 2 -- Textline 2

INSERT -- 0000021321 -- KNA1 -- 9080 -- EN -- 1 -- EFTA1

INSERT -- 0000021321 -- KNA1 -- 9080 -- EN -- 2 -- EFTA2

INSERT -- 0000021321 -- KNA1 -- 9080 -- EN -- 2 -- EFTA3

Any idea?

Best regards

Lars

Accepted Solutions (0)

Answers (2)

Answers (2)

Former Member
0 Kudos

Hi Stefan,

I'm afraid that I described the result wrong, it is a little more complicated.

Because we can't compare the texts we delete every text in a previous step:

Action -- Customer -- Textobject -- ID -


SPRAS

DELETE -- 0000021321 -- KNA1 -- 9010 -- EN

DELETE -- 0000021321 -- KNA1 -- 9025 -- EN

DELETE -- 0000021321 -- KNA1 -- 9080 -- EN

In the second step there should be no DELETE action for the delete request, only INSERT actions.

The result should look like this:

Action -- Customer -- Textobject -- ID -- SPRAS -- LINE -- TEXT

INSERT -- 0000021321 -- KNA1 -- 9025 -- EN -- 1 -- Textline 1

INSERT -- 0000021321 -- KNA1 -- 9025 -- EN -- 2 -- Textline 2

INSERT -- 0000021321 -- KNA1 -- 9080 -- EN -- 1 -- EFTA1

INSERT -- 0000021321 -- KNA1 -- 9080 -- EN -- 2 -- EFTA2

INSERT -- 0000021321 -- KNA1 -- 9080 -- EN -- 2 -- EFTA3

What the JDBC-adapter expects is the following XML-Statement:


<StatementKNA1_TextDelete>
  <mssql_db action="DELETE">
    <table>KNA1_Text</table>
      <key1><KUNNR>0000021321</KUNNR><TextId>9010</TextId><Langu>EN</Langu><Textobj>KNA1</Textobj></key1>
  </mssql_db>
</StatementKNA1_TextDelete>
<StatementKNA1_TextDelete>
  <mssql_db action="DELETE">
    <table>KNA1_Text</table>
      <key1><KUNNR>0000021321</KUNNR><TextId>9025</TextId><Langu>EN</Langu><Textobj>KNA1</Textobj></key1>
  </mssql_db>
</StatementKNA1_TextDelete>
<StatementKNA1_TextDelete>
  <mssql_db action="DELETE">
    <table>KNA1_Text</table>
      <key1><KUNNR>0000021321</KUNNR><TextId>9080</TextId><Langu>EN</Langu><Textobj>KNA1</Textobj></key1>
  </mssql_db>
</StatementKNA1_TextDelete>

The DELETE action is not the problem, it is a simple 1:1 mapping.

But for the INSERT action there is one more input-context than output-context.


<StatementKNA1_Text>
  <mssql_db action="INSERT">
    <table>KNA1_Text</table>
      <access>
        <KUNNR>0000021321</KUNNR><TextId>9025</TextId><Langu>EN</Langu><Textobj>KNA1</Textobj><Line>1</Line>
        <Text>Textline 1</Text>
      </access>
      <access>
        <KUNNR>0000021321</KUNNR><TextId>9025</TextId><Langu>EN</Langu><Textobj>KNA1</Textobj><Line>2</Line>
        <Text>Textline 2</Text>
      </access>
  </mssql_db>
</StatementKNA1_Text>
<StatementKNA1_Text>
  <mssql_db action="INSERT">
    <table>KNA1_Text</table>
      <access>
        <KUNNR>0000021321</KUNNR><TextId>9080</TextId><Langu>EN</Langu><Textobj>KNA1</Textobj><Line>1</Line>
        <Text>EFTA1</Text>
      </access>
      <access>
        <KUNNR>0000021321</KUNNR><TextId>9080</TextId><Langu>EN</Langu><Textobj>KNA1</Textobj><Line>2</Line>
        <Text>EFTA2</Text>
      </access>
      <access>
        <KUNNR>0000021321</KUNNR><TextId>9080</TextId><Langu>EN</Langu><Textobj>KNA1</Textobj><Line>3</Line>
        <Text>EFTA2</Text>
      </access>
  </mssql_db>
</StatementKNA1_Text>

I think for this case I can't use the function <i>useOneAsMany</i>. Have you any idea how this can be mapped?

BTW, we are on XI 3.0 SP14

Thank you for the hint about the function <i>mapWithDefault</i>, it helps for copying empty fields ;-).

Best regards,

Lars

stefan_grube
Active Contributor
0 Kudos

The delete lines you can filter with following structure:

MSGFN - removeContexts - FixValues(*) - createIf - StatementKNA1_Text

*) 003 = false, 005 = true

Look here for details of the createIf function:

/people/stefan.grube/blog/2006/01/09/the-use-of-suppress-in-the-xi-30-graphical-mapping-tool

You can of course use the function <i>useOneAsMany</i>, but you have to assure, that every context has values. That you achieve with <i>mapWithDefault</i>.

E1KNA1L - mapWithDefault - access

Regards

Stefan

Former Member
0 Kudos

Now it works!

After your suggestions there was only an IF-clause missing to combine the fields TextId, Langu and Textobj with MSGFN.

Thanks for your help.

Best regards,

Lars

stefan_grube
Active Contributor
0 Kudos

Hi Lars,

use the node function <i>mapWithDefault</i>. If you have not SP13, then create this user defined function instead:

Here an example for action:


                              MSGFN - FixValues(*) 
                          E1KNA1L - mapWithDefault - useOneAsMany - Action
E1KNA1L - mapWithDefault - SplitByValue(eachValue) /

(*) 003 = DELETE, 005 = INSERT

Customer -> SPRAS similar

E1KNA1L - index - mapWithDefault - LINE
TDLINE(context=E1KNA1H) - mapWithDefault - SplitByValue - TextLine

Hope that helps

Stefan

Former Member
0 Kudos

Hi Stefan,

thanks for your answer. I will check that when I'm again on the system.

Best regards,

Lars