问题
I have some calculations in the area of payroll which result in a lot of data each per month/year and two dates: an begin date (mm/yyyy) and an end date (mm/yyyy).
What I want: generating an internal table which has as many columns as begda-year till endda-year has (in years). For example my begda is 05/2010 and endda is 03/2013, then I need a table like this which has columns 2010, 2011, 2012, 2013 and rows for each month:
The difficult part for me is, that the table colums (or the endda and begda) are always varying, how could I realize this? Creating some kind of dynamic table?
回答1:
Check this code. Hope it helps:
report zdynamiccol.
type-pools: slis.
data: gt_fieldcat type slis_t_fieldcat_alv with header line,
gs_layout type slis_layout_alv,
g_repid type sy-repid.
types: begin of ty_years,
zyear(4) type c,
end of ty_years.
data it_years type table of ty_years. " The structure that will hold the years to create the dynamic columns
types: begin of st_output, " Sample data
zmonth type string,
zyear(4) type c,
zvalue type i,
check type c,
end of st_output,
gt_tbl_data type standard table of st_output.
data: gt_output type standard table of st_output ,
gt_output2 type standard table of st_output.
data:
r_dyn_table type ref to data,
t_fieldcat1 type lvc_t_fcat,
wa_fieldcat1 type lvc_s_fcat.
data:
t_fieldcat2 type slis_t_fieldcat_alv,
wa_fieldcat2 like line of t_fieldcat2.
field-symbols:
<t_dyn_table> type standard table,
<wa_dyn_table> type any,
<w_field> type any,
<fs_st_output> type st_output,
<wa_years> type ty_years.
initialization.
g_repid = sy-repid.
select-options s_dats for sy-datum.
start-of-selection.
perform get_years. " Make the year column structure
perform create_catalog. " Make the field catalog with the columns
perform get_data. " Sample data
perform process_data. " Fill table
perform build_alv. " Create ALV
form get_years.
refresh: it_years.
data zline like line of it_years.
data year type i.
year = s_dats-low(4).
while year <= s_dats-high(4).
clear zline.
zline-zyear = year.
append zline to it_years.
add 1 to year.
endwhile.
endform.
form create_catalog.
data: cont type i.
refresh: t_fieldcat1, t_fieldcat2.
clear: wa_fieldcat1, wa_fieldcat2.
cont = 1.
wa_fieldcat1-fieldname = 'ZMONTH'.
wa_fieldcat1-col_pos = cont.
wa_fieldcat1-coltext = 'MONTH'.
wa_fieldcat1-key = 'X'.
wa_fieldcat1-seltext = wa_fieldcat1-coltext.
append wa_fieldcat1 to t_fieldcat1.
wa_fieldcat2-fieldname = 'ZMONTH'.
wa_fieldcat2-ref_fieldname = 'MONTH'.
wa_fieldcat2-seltext_l = 'Month'.
wa_fieldcat2-seltext_m = 'Month'.
wa_fieldcat2-seltext_s = 'Month'.
wa_fieldcat2-key = 'X' .
wa_fieldcat2-outputlen = 10.
wa_fieldcat2-col_pos = cont.
append wa_fieldcat2 to t_fieldcat2.
loop at it_years assigning <wa_years>.
at new zyear.
clear: wa_fieldcat1, wa_fieldcat2.
wa_fieldcat1-fieldname = <wa_years>-zyear.
wa_fieldcat1-inttype = 'I'.
wa_fieldcat1-col_pos = cont.
wa_fieldcat1-coltext = <wa_years>-zyear.
wa_fieldcat1-seltext = wa_fieldcat1-coltext.
append wa_fieldcat1 to t_fieldcat1.
wa_fieldcat2-fieldname = wa_fieldcat1-fieldname.
wa_fieldcat2-seltext_l = wa_fieldcat1-seltext.
wa_fieldcat2-col_pos = cont.
append wa_fieldcat2 to t_fieldcat2.
add 1 to cont.
endat.
endloop.
call method cl_alv_table_create=>create_dynamic_table
exporting
it_fieldcatalog = t_fieldcat1
importing
ep_table = r_dyn_table
exceptions
generate_subpool_dir_full = 1
others = 2.
assign r_dyn_table->* to <t_dyn_table>.
endform.
form get_data.
data zrows type i value 10.
data month type i.
data line like line of gt_output.
field-symbols <wa_gt_output> type st_output.
clear line.
line-zmonth = 'January'.
line-zyear = 2010.
line-zvalue = 100.
append line to gt_output.
append line to gt_output2.
clear line.
line-zmonth = 'February'.
line-zyear = 2010.
line-zvalue = 150.
append line to gt_output.
append line to gt_output2.
clear line.
line-zmonth = 'March'.
line-zyear = 2010.
line-zvalue = 160.
append line to gt_output.
append line to gt_output2.
clear line.
line-zmonth = 'April'.
line-zyear = 2010.
line-zvalue = 240.
append line to gt_output.
append line to gt_output2.
clear line.
line-zmonth = 'April'.
line-zyear = 2013.
line-zvalue = 233.
append line to gt_output.
append line to gt_output2.
clear line.
line-zmonth = 'January'.
line-zyear = 2012.
line-zvalue = 151.
append line to gt_output.
append line to gt_output2.
clear line.
line-zmonth = 'May'.
line-zyear = 2012.
line-zvalue = 101.
append line to gt_output.
append line to gt_output2.
clear line.
line-zmonth = 'June'.
line-zyear = 2012.
line-zvalue = 762.
append line to gt_output.
append line to gt_output2.
clear line.
line-zmonth = 'September'.
line-zyear = 2012.
line-zvalue = 666.
append line to gt_output.
append line to gt_output2.
clear line.
line-zmonth = 'October'.
line-zyear = 2012.
line-zvalue = 500.
append line to gt_output.
append line to gt_output2.
clear line.
line-zmonth = 'November'.
line-zyear = 2012.
line-zvalue = 101.
append line to gt_output.
append line to gt_output2.
clear line.
line-zmonth = 'December'.
line-zyear = 2013.
line-zvalue = 829.
append line to gt_output.
append line to gt_output2.
clear line.
line-zmonth = 'December'. " Sum to the same month
line-zyear = 2013.
line-zvalue = 1.
append line to gt_output.
append line to gt_output2.
endform.
form process_data.
field-symbols <fs_data> type st_output.
field-symbols <fs_check> type st_output.
data lv_index type sy-tabix.
loop at gt_output assigning <fs_st_output>.
check <fs_st_output>-check eq space.
append initial line to <t_dyn_table> assigning <wa_dyn_table>.
assign component 'ZMONTH' of structure <wa_dyn_table> to <w_field>.
<w_field> = <fs_st_output>-zmonth.
loop at gt_output2 assigning <fs_data> where zmonth = <fs_st_output>-zmonth and check eq space.
lv_index = sy-tabix.
check <wa_dyn_table> is assigned.
assign component <fs_data>-zyear of structure <wa_dyn_table> to <w_field>.
<w_field> = <w_field> + <fs_data>-zvalue.
read table gt_output assigning <fs_check> index lv_index. " Check so the position will never be processed later
<fs_check>-check = 'X'.
endloop.
endloop.
endform.
form build_alv.
data: x_layout type slis_layout_alv,
t_fieldcat type slis_t_fieldcat_alv.
refresh t_fieldcat.
clear x_layout.
g_repid = sy-repid.
call function 'REUSE_ALV_GRID_DISPLAY'
exporting
i_callback_program = g_repid
is_layout = gs_layout
it_fieldcat = t_fieldcat2
tables
t_outtab = <t_dyn_table>
exceptions program_error = 1
others = 2 .
if sy-subrc <> 0.
message id sy-msgid type sy-msgty number sy-msgno with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
endif.
endform.
回答2:
How many years are going to be working with on general? Instead of thinking of it in terms of rows perhaps just remember that there are only as many rows in a table as you append to it.
You can create the dynamic structure through whichever means, either through create_data or cl_alv_table_create (which will work fine as long as you don't have several thousand columns).
So do psuedo code and help you out a bit:
Step 1) Create a structure which contains a column for each year
Step 2) Pass the structure to CL_ALV_TABLE_CREATE=>CREATE_DYNAMIC_TABLE and get the table
with the unique structure
Step 3) Append 12 rows to the table, 1 row representing each month of the year
Step 4) When needing to read the data, READ TABLE <table> WITH TABLE KEY monthname = 'MONTHNAME' INTO <structure>.
Step 5) ASSIGN <year>->* OF STRUCTURE <structure> TO <data>.
Step 6) <data> = whatever.
I don't remember off the top of my head how to work with run-time created data, but a quick search on google can let you know that.
回答3:
Check CREATE DATA HANDLE documentation. I do not recommend to use cl_alv_table_create=>create_dynamic_table
because of its internal limitations.
来源:https://stackoverflow.com/questions/15587774/how-to-generate-a-table-with-dynamic-amount-of-colums-and-a-fixed-set-of-rows