2006 Mar 08 3:33 PM
Hi Guys,
In one of my user exits, i am trying to calculate value for a field.
DATA: l_s_abc TYPE TABLE OF BIW_ABC,
tmpmatnr LIKE mara-matnr VALUE ' '.
tmpntgew LIKE mara-ntgew.
My code for one data_package is:
LOOP AT i_t_DATA into l_s_abc.
IF l_s_abc-brgew <> 0.
IF l_s_abc-matnr <> tmpmatnr.
tmpmatnr = l_s_abc-matnr.
SELECT SINGLE ntgew INTO
(tmpmara-ntgew)
FROM mara WHERE matnr = l_s_abc-matnr.
ELSE.
SELECT SINGLE ntgew INTO
(tmpntgew)
FROM mara.
tmpmara-ntgew = tmpntgew.
ENDIF.
l_s_abc-zzwt = l_s_abc-umrez * tmpmara-ntgew.
MODIFY i_t_data FROM l_s_abc.
CLEAR tmpmara.
ENDIF.
ENDLOOP.
My question is, if i have multiple records for same material number in the data package,i want to store that into a temporary matnr so that i don't endup doing lookup again. I tried the above code. But, i see that i am ending up doing a lookup (2nd SELECT) for the same matnr.
How to avoid multiple lookups for my case.
Regards
Message was edited by: George Smith
2006 Mar 08 7:11 PM
Ok that still doesn't answer the need for the second select which is not having any WHERE clause.
Try this code
DATA: l_s_abc TYPE TABLE OF BIW_ABC.
DATA: BEGIN OF matnr_ntgew OCCURS 0,
matnr LIKE mara-matnr,
ntgew LIKE mara-ntgew.
DATA: END OF matnr_ntgew.
SELECT matnr ntgew FROM mara
INTO TABLE matnr_ntgew
FOR ALL ENTRIES IN i_t_data
WHERE matnr = i_t_data-matnr.
SORT matnr_ntgew BY matnr.
LOOP AT i_t_DATA into l_s_abc.
IF l_s_abc-brgew <> 0.
CLEAR matnr_ntgew.
READ TABLE matnr_ntgew WITH KEY matnr = l_s_abc-matnr BINARY SEARCH.
CHECK SY-SUBRC = 0.
l_s_abc-zzwt = l_s_abc-umrez * matnr_ntgew-ntgew.
MODIFY i_t_data FROM l_s_abc.
ENDIF.
ENDLOOP.
2006 Mar 08 3:37 PM
Hi,
SAP allow you to select two times in the same table adding the special char * before the tables.
tables : mara ,
*mara.
select * from *mara where ...Rgd
Frédéric
2006 Mar 08 3:38 PM
IF l_s_abc-matnr <> tmpmatnr.
tmpmatnr = l_s_abc-matnr.
SELECT SINGLE ntgew INTO
(tmpmara-ntgew)
FROM mara WHERE matnr = l_s_abc-matnr.
ELSE.
<b>SELECT SINGLE ntgew INTO
(tmpntgew)
FROM mara.
dt_mara-ntgew = tmpntgew.</b>
ENDIF.
Do you need the second select if the matnr are the same?
Regards,
RIch Heilman
2006 Mar 08 3:40 PM
Hi Guys,
Thanks for the response. I don't need second SELECT. But, if i don't use 2nd SELECT, how to get the new value for ntgew.
Say for a matnr - 1000, i have 3 records
where ntgew1 = 100, ntgew2 = 50, ntgew3 = 20
If i don't use 2nd SELECT, for the second record of matnr (1000), i will still have old value of ntgew i.e. 100 instead of the new value 50.
Am i right?
Regards
2006 Mar 08 3:39 PM
You can try using COntrol break statements which will trigger only for each Material and then if required you can modify data for all entries of that Material using WHERE clause.
Try this out.
Message was edited by: Ashish Gundawar
2006 Mar 08 3:41 PM
Hi George,
you need to create a internal table containing matnr and ntgew:
types: begin of t_ntgew,
matnr type matnr,
ntgew type ntgew,
end of t_ntgew.
data: it_ntgew type hashed table of t_ntgew
with unique key matnr,
wa_ntgew type t_ntgew.
populate the table before looping at the data package.
select matnr ntgew into table it_ntgew from mara for all entries in i_t_data
where matnr = i_t_data-matnr.
in the loop, instead of doing the select,
read table it_ntgew into wa_ntgew
with table key matnr = l_s_abc.
Hope this helps!
regards
Siggi
PS: Next time you can post such questions in the bw forum.
Message was edited by: Siegfried Szameitat
2006 Mar 08 3:44 PM
Hi George,
R u trying to simulate the "At new" functionality for matnr field?
In such case, move the contents of the i_t_DATA table into another table which has the matnr field as the first field and use,
sort i_t_DATA_2 by matnr.
loop at i_t_DATA_2.
at new matnr.
.
.
..
<Triggered only once for one material.
endat.
.
.
.
<Triggered for all loop passes>
endloop.
2006 Mar 08 3:55 PM
Hi Guys,
My issue is, if i have records like
matnr brgew mara-ntgew
1000 100 50
1000 20 20
1000 50 75
2000 100 125
In this case, i would want to loop only once for the 1st 3 records, since the matnr is same and then i want to loop once for the 4th record.
Regards
2006 Mar 08 3:58 PM
Hi George,
Sort your internal table on matnr.
And do the processing in either <b>at new matnr</b> OR <b>at end of matnr</b>.
This will serve your purpose.
Regards,
Raj
2006 Mar 08 4:09 PM
Hi,
In this case,
matnr brgew mara-ntgew
1000 100 50
1000 20 20
1000 50 75
2000 100 125
In this case, even though i want to loop only once for the 1st 3 records, i will have to do calculation for ntgew in data_package 3 times since the 3 records have diff. values for ntgew in mara.
Regards
2006 Mar 08 4:17 PM
Hi George,
Its like this...
Once you sort the internal table on matnr..
Loop on internal table.
<i><logic for ntgew></i>
at end of matnr.
<i><final processing></i>
endat.
Endloop.
Regards,
Raj
2006 Mar 08 4:44 PM
Hi Raj,
FORM exit_for_0XXX TABLES i_t_data.
TYPES: BEGIN OF t_mara,
matnr LIKE mara-matnr,
ntgew LIKE mara-ntgew,
END OF t_mara.
DATA: dt_mara TYPE TABLE OF t_mara WITH HEADER LINE,
tmpmatnr LIKE mara-matnr VALUE ' ',
tmpntgew LIKE mara-ntgew.
LOOP AT i_t_data INTO l_s_abc.
IF l_s_abc-brgew <> 0.
IF l_s_abc-matnr <> tmpmatnr.
tmpmatnr = l_s_abc-matnr.
SELECT SINGLE ntgew INTO (tmpmara-ntgew)
FROM mara WHERE matnr = l_s_abc-matnr.
ELSE.
SELECT SINGLE ntgew INTO (tmpntgew)
FROM mara.
dt_mara-ntgew = tmpntgew.
ENDIF.
l_s_abc-zzntgew = l_s_abc-umrez * dt_mara-ntgew.
MODIFY i_t_data FROM l_s_abc.
CLEAR dt_mara.
ENDIF.
ENDLOOP.
ENDFORM.
I want to remove 2 SELECTs and want to do only a one-time lookup.
Regards
Message was edited by: George Smith
2006 Mar 08 5:02 PM
Hi George,
Here is your code (after making changes to it)
FORM exit_for_0XXX TABLES i_t_data.
TYPES: BEGIN OF t_mara,
matnr LIKE mara-matnr,
ntgew LIKE mara-ntgew,
END OF t_mara.
DATA: dt_mara TYPE TABLE OF t_mara WITH HEADER LINE,
tmpmatnr LIKE mara-matnr VALUE ' ',
tmpntgew LIKE mara-ntgew.
i_t_data2[] = i_t_data[].
sort i_t_data2 by matnr.
LOOP AT i_t_data INTO l_s_abc.
IF l_s_abc-brgew <> 0.
IF l_s_abc-matnr <> tmpmatnr.
tmpmatnr = l_s_abc-matnr.
SELECT SINGLE ntgew INTO (tmpmara-ntgew)
FROM mara WHERE matnr = l_s_abc-matnr.
l_s_abc-zzntgew = l_s_abc-umrez * dt_mara-ntgew.
loop at i_t_data2 where matnr = i_t_data-matnr.
MODIFY i_t_data2 FROM l_s_abc.
endloop.
CLEAR dt_mara.
ENDIF.
ENDLOOP.
i_t_data[] = i_t_data2[].
ENDFORM.
Regards,
Raj
Message was edited by: Rajasekhar Dinavahi
2006 Mar 08 5:22 PM
George,
A couple of questions. You are doing the select on MARA with a MATNR value. How did you get different NTGEW values for the same MATNR when you are going to get only one record?
Also, when you are doing two selects I saw that you are trying to get the record with MATNR once, and if that fails you are just selecting any record from MARA for the value NTGEW. Is this correct? If you cannot find the record for MATNR in MARA then it should be an error. Instead you are just trying to get some NTGEW from MARA that may not even be for this material.
Srinivas
2006 Mar 08 6:00 PM
Hi Raj,
For the same material, will your code not end up looping twice to calculate net weight. i mean to say will the single SELECT statement not execute twice for 1000.
Say ,we have the foll. recs in the data package.
matnr meinh umren brgew <b>zzntgew</b>
1000 CAS 1 10
1000 LB 2 20
2000 LB 1 50
mara:
matnr meinh brgew <b>ntgew</b>
1000 CAS 10 10
1000 LB 20 40
I want the output to be:
matnr meinh umren brgew <b>zzntgew</b>
1000 CAS 1 10 10 (10*1)
1000 LB 2 20 80 (40*2)
2000 LB 1 50 0
Srinivas,
The values are just sample values. Not exact values.
Regards
2006 Mar 08 6:50 PM
Hi George,
If you need to process all records (for ntgew processing), but still want to go for the select only once per matnr... then
1.Have a internal table with just matnr and ntgew and get ntgew for all materials in your internal table.
2. loop at your internal table (items table), read the internal table (with ntgew values) and process.
Hope i am clear.
select matnr ntgew into table i_tab2
from mara for all entries in i_data
where matnr = i_data-matnr.
if sy-subrc = 0.
sort i_tab2 by matnr.
delete adjacent duplicates from i_tab2 comparing matnr.
endif.
loop at i_data.
read table i_tab2 with key matnr = i_data-matnr.
if sy-subrc = 0.
<your processing>
endif.
endloop.
Regards,
Raj
Message was edited by: Rajasekhar Dinavahi
2006 Mar 08 7:11 PM
Ok that still doesn't answer the need for the second select which is not having any WHERE clause.
Try this code
DATA: l_s_abc TYPE TABLE OF BIW_ABC.
DATA: BEGIN OF matnr_ntgew OCCURS 0,
matnr LIKE mara-matnr,
ntgew LIKE mara-ntgew.
DATA: END OF matnr_ntgew.
SELECT matnr ntgew FROM mara
INTO TABLE matnr_ntgew
FOR ALL ENTRIES IN i_t_data
WHERE matnr = i_t_data-matnr.
SORT matnr_ntgew BY matnr.
LOOP AT i_t_DATA into l_s_abc.
IF l_s_abc-brgew <> 0.
CLEAR matnr_ntgew.
READ TABLE matnr_ntgew WITH KEY matnr = l_s_abc-matnr BINARY SEARCH.
CHECK SY-SUBRC = 0.
l_s_abc-zzwt = l_s_abc-umrez * matnr_ntgew-ntgew.
MODIFY i_t_data FROM l_s_abc.
ENDIF.
ENDLOOP.
2006 Mar 08 7:33 PM
Hi Guys,
Thanks for your response and patience. The thing is i get an error when i execute the SELECT statement.
SELECT matnr ntgew FROM mara
INTO TABLE matnr_ntgew
FOR ALL ENTRIES IN i_t_data
WHERE matnr = i_t_data-matnr.
This is because i_t_data is not an internal table.
As i mentioned, i am writing this code in a FORM and calling this FORM with a PERFORM in the master data user exit (EXIT_SAPLRSAP_002).
Regards
2006 Mar 08 7:49 PM
But how are you doing the "LOOP AT i_t_data" in your code in that case?
I looked at this user exit and i_t_data is a tables paramter there. So how is your code in the include ZXRSAU02?
Is it something like this?
LOOP AT i_t_data INTO abc.
PERFORM calculate_weight USING abc.
ENDLOOP.
2006 Mar 08 7:54 PM
Hi,
In my ZXRSAU02, i have
WHEN 'datasource name'.
PERFORM exit_for_0XXX TABLES i_t_data.
Regards
The error i get:
The specified type has no structure and therefore no component called "MATNR".
Regards
Message was edited by: George Smith
2006 Mar 08 8:21 PM
OK. In your "FORM exit_for_0XXX TABLES i_t_data." add this code.
DATA: l_i_abc TYPE TABLE OF BIW_ABC with header line.
l_i_abc[] = i_t_data[].
and then change all the previous code I gave to use 'l_i_abc' instead of 'i_t_data'.
and just before the 'endform' add this line.
i_t_data[] = l_i_abc[].
2006 Mar 08 8:26 PM
So your 'FORM' code will be like this
FORM exit_for_0XXX TABLES i_t_data.
DATA: l_i_abc TYPE TABLE OF BIW_ABC OCCURS 0.
DATA: BEGIN OF matnr_ntgew OCCURS 0,
matnr LIKE mara-matnr,
ntgew LIKE mara-ntgew.
DATA: END OF matnr_ntgew.
l_i_abc[] = i_t_data[].
SELECT matnr ntgew FROM mara
INTO TABLE matnr_ntgew
FOR ALL ENTRIES IN l_i_abc
WHERE matnr = l_i_abc-matnr.
SORT matnr_ntgew BY matnr.
LOOP AT l_i_abc.
IF l_i_abc-brgew <> 0.
CLEAR matnr_ntgew.
READ TABLE matnr_ntgew WITH KEY matnr = l_i_abc-matnr BINARY SEARCH.
CHECK SY-SUBRC = 0.
l_i_abc-zzwt = l_i_abc-umrez * matnr_ntgew-ntgew.
MODIFY l_i_abc.
ENDIF.
ENDLOOP.i_t_data[] = l_i_abc[].
ENDFORM.
corrected some typos.
Message was edited by: Srinivas Adavi
2006 Mar 08 8:50 PM
Hi sRinivas,
I guess this is what i am looking for. Let me validate and get back to you. Thanks a bunch for helping me.
regards
George