‎2008 Jan 26 1:33 PM
Hi,
How can I work with header, line item, and a cache techniques using hashed tables?
Thanks,
Shah.
‎2008 Jan 27 10:24 AM
Hi,
Here is an example to clarify the ideas:
In general, every time you have a header-> lines structure you have a unique key for the lines that has at least header key plus one or more fields. I'll make use of this fact.
I'll try to put an example of how to work with header -> line items and a cache technique using hashed tables.
Just suppose that you need a list of all the material movements '101'-'901' for a certain range of dates in mkpf-budat. We'll extract these fields:
mkpf-budat
mkpf-mblnr,
mseg-lifnr,
lfa1-name1,
mkpf-xblnr,
mseg-zeile
mseg-charg,
mseg-matnr,
makt-maktx,
mseg-erfmg,
mseg-erfme.
I'll use two cache: one for maintaining lfa1 related data and the other to maintain makt related data. Also I'll only describe the data gathering part. The showing of the data is left to your own imagination.
The main ideas are:
1. As this is an example I won't use inner join. If properly desingned may be faster .
2. I'll use four hashed tables: ht_mkpf, ht_mseg, ht_lfa1 and ht_makt to get data into memory. Then I'll collect all the data I want to list into a fifth table ht_lst.
3. ht_mkpf should have (at least) mkpf's primary key fields : mjahr, mblnr.
4. ht_mseg should have (at least) mseg primary key fields: mjahr mblnr and zeile.
5. ht_lfa1 should have an unique key by lifnr.
6. ht_makt should have an unique key by matnr.
7. I prefer using with header line because makes the code easier to follow and understand. The waste of time isn't quite significant (in my experience at least).
Note: When I've needed to work from header to item lines then I added a counter in ht_header that maintains the count of item lines, and I added an id in the ht_lines so I can read straight by key a given item line. But this is very tricky to implement and to follow. (Nevertheless I've programmed it and it works well.)
The data will be read in this sequence:
select data from mkpf into table ht_mkpf
select data from mseg int table ht_mseg having in count all the data in ht_mkpf
loop at ht_mseg (lines)
filter unwanted records
read cache for lfa1 and makt
fill in ht_lst and collect data
endloop.
tables
tables: mkpf, mseg, lfa1, makt.
internal tables:
data: begin of wa_mkpf, "header
mblnr like mkpf-mblnr,
mjahr like mkpf-mjahr,
budat like mkpf-budat,
xblnr like mkpf-xblnr,
end of wa_mkpf.
data ht_mkpf like hashed table of wa_mkpf
with unique key mblnr mjahr
with header line.
data: begin of wa_mseg, " line items
mblnr like mseg-mblnr,
mjahr like mseg-mjahr,
zeile like mseg-zeile,
bwart like mseg-bwart,
charg like mseg-charg,
matnr like mseg-matnr,
lifnr like mseg-lifnr,
erfmg like mseg-erfmg,
erfme like mseg-erfme,
end of wa_mseg,
.
data ht_mseg like hashed table of wa_mseg
with unique key mblnr mjahr zeile
with header line.
data: begin of wa_lfa1,
lifnr like lfa1-lifnr,
name1 like lfa1-name1,
end of wa_lfa1,
data ht_lfa1 like hashed table of wa_lfa1
with unique key lifnr
with header line.
data: begin of wa_makt,
matnr like makt-matnr,
maktx like makt-maktx,
end of wa_makt.
data: ht_makt like hashed table of wa_makt
with unique key matnr
with header line.
result table
data: begin of wa_lst, "
budat like mkpf-budat,
mblnr like mseg-mblnr,
lifnr like mseg-lifnr,
name1 like lfa1-name1,
xblnr like mkpf-xblnr,
zeile like mseg-zeile,
charg like mseg-charg,
matnr like mseg-matnr,
maktx like makt-maktx,
erfmg like mseg-erfmg,
erfme like mseg-erfme,
mjahr like mseg-mjahr,
end of wa_mseg,
data: ht_lst like hashed table of wa_lst
with unique key mblnr mjahr zeile
with header line.
data: g_lines type i.
select-options: so_budat for mkpf-budat default sy-datum.
select-options: so_matnr for mseg-matnr.
form get_data.
select mblnr mjahr budat xblnr
into table ht_mkfp
from mkpf
where budat in so_budat.
describe table ht_mkpf lines g_lines.
if lines > 0.
select mblnr mjahr zeile bwart charg
matnr lifnr erfmg erfme
into table ht_mseg
from mseg
for all entries in ht_mkpf
where mblnr = ht_mkpf-mblnr
and mjahr = ht_mjahr.
endif.
loop at ht_mseg.
filter unwanted data
check ht_mseg-bwart = '101' or ht_mseg-bwart = '901'.
check ht_mseg-matnr in so_matnr.
read header line.
read table ht_mkpf with table key mblnr = ht_mseg-mblnr
mjahr = ht_mseg-mjahr.
clear ht_lst.
note : this may be faster if you specify field by field.
move-corresponding ht_mkpf to ht_lst.
move-corresponding ht_mseg to ht_lst.
perform read_lfa1 using ht_mseg-lifnr changing ht_lst-name1.
perform read_makt using ht_mseg-matnr changing ht_lst-maktx.
insert table ht_lst.
endloop.
implementation of cache for lfa1.
form read_lfa1 using p_lifnr changing p_name1.
read table ht_lfa1 with table key lifnr = p_lifnr
transporting name1.
if sy-subrc <> 0.
clear ht_lfa1.
ht_lfa1-lifnr = p_lifnr.
select single name1
into ht_lfa1-name1
from lfa1
where lifnr = p_lifnr.
if sy-subrc <> 0. ht_lfa1-name1 = 'n/a in lfa1'. endif.
insert table ht_lfa1.
endif.
p_name1 = ht_lfa1-name1.
endform.
implementation of cache for makt
form read_makt using p_matnr changing p_maktx.
read table ht_makt with table key matnr = p_matnr
transporting maktx.
if sy-subrc <> 0.
ht_makt-matnr = p_matnr.
select single maktx into ht_matk-maktx
from makt
where spras = sy-langu
and matnr = p_matnr.
if sy-subrc <> 0. ht_makt-maktx = 'n/a in makt'. endif.
insert table ht_makt.
endif.
p_maktx = ht_makt-maktx.
endform.
Reward points if found helpfull...
Cheers,
Siva.