*&---------------------------------------------------------------------*
*& Report ZZINFOTYPES
*&
*&---------------------------------------------------------------------*
*& Join up various HR infotypes so you can see in one line the
*& relationship between the various tables
*& Mark Langenhoven
*& 2022/10/19
*&---------------------------------------------------------------------*
report zzinfotypes.
*--- Data declarations ----------------------------------------------
tables: pa0000.
data: lv_infotype(4) type n,
lv_infoname(30) type c,
lv_fieldname(30) type c,
overlapped type boole_d.
data: begin of fieldrec,
infotype like lv_infotype,
fieldname like dd03l-fieldname,
end of fieldrec,
begin of selrec,
infotype like lv_infotype,
whereclause type rsds_twhere,
end of selrec,
begin of looprec,
loop(2) type n,
infotype like lv_infotype,
end of looprec,
lt_loop like standard table of looprec,
ls_loop like looprec,
lt_disp like standard table of fieldrec,
ls_disp like fieldrec,
lt_sel like standard table of selrec,
ls_sel like selrec.
data: lt_cat type lvc_t_fcat,
lt_maincat type lvc_t_fcat,
ls_cat type line of lvc_t_fcat,
lt_dyntab type ref to data,
ls_dynwa type ref to data,
ls_dynwa2 type ref to data,
added type boole_d,
lv_loop(2) type n,
lv_maxloop(2) type n,
lv_tabix type i,
lt_split type string occurs 0 with header line,
lv_left type string,
lv_operand type string,
lv_right type string,
lv_and type string,
lv_pos type i,
lv_next type i,
lv_low type i,
lv_high type i,
dodel type boole_d,
lv_cnt type i.
data: ls_where type rsds_where,
lt_wheretab type rsds_where_tab,
ls_wheretab type rsdswhere,
lv_where type string.
data: begin of infotyperec,
fieldname like rp50g-choic, "Have to use a fieldname otherwise F4 doesn't work "lv_infotype,
desc like dd02t-ddtext,
end of infotyperec,
lt_infotypes like standard table of infotyperec,
ls_infotype like infotyperec,
lt_return like ddshretval occurs 0 with header line.
ranges: r_pernr for pa0000-pernr.
field-symbols:
type table,
type table,
type table,
type table,
type table,
type table,
type table,
type table,
type table,
type table,
type table,
type table,
type table,
type table,
type table,
type table,
type table,
type table,
type table,
type table,
type table,
type table,
type any,
type any,
type any,
type any,
type any,
type any,
type any,
type any,
type any,
type any,
type any.
*--- Selection screen -----------------------------------------------
select-options: s_info for lv_infotype,
s_pernr for pa0000-pernr no-display.
selection-screen skip.
selection-screen begin of line.
selection-screen: pushbutton 1(18) p_disp user-command dis.
parameters: p_disc type i.
selection-screen end of line.
selection-screen begin of line.
selection-screen: pushbutton 1(18) p_sel user-command sel.
parameters: p_selc type i.
selection-screen end of line.
selection-screen skip.
parameters: p_curr as checkbox default 'X', "Only pull current records
p_hide as checkbox default 'X'. "Only show the first PERNR field
initialization.
p_disp = 'Fields'.
p_sel = 'Selections'.
lv_maxloop = 20.
p_disc = 0.
p_selc = 0.
at selection-screen.
if sy-ucomm = 'DIS'.
perform get_disp_fields.
endif.
if sy-ucomm = 'SEL'.
perform get_sel_fields.
endif.
at selection-screen output.
describe table lt_disp lines p_disc.
clear p_selc.
loop at lt_sel transporting no fields where whereclause is not initial.
p_selc = p_selc + 1.
endloop.
loop at screen.
if screen-name = 'P_DISC' or
screen-name = 'P_SELC'.
screen-input = 0.
modify screen.
endif.
endloop.
at selection-screen on value-request for s_info-low.
perform get_infotypes tables lt_infotypes.
call function 'F4IF_INT_TABLE_VALUE_REQUEST'
exporting
retfield = 'FIELDNAME'
value_org = 'S'
tables
value_tab = lt_infotypes
return_tab = lt_return
exceptions
parameter_error = 1
no_values_found = 2
others = 3.
if sy-subrc <> 0.
* Implement suitable error handling here
endif.
loop at lt_return.
s_info-low = lt_return-fieldval.
s_info-sign = 'I'.
s_info-option = 'EQ'.
append s_info.
endloop.
sort s_info.
delete adjacent duplicates from s_info.
at selection-screen on value-request for s_info-high.
perform get_infotypes tables lt_infotypes.
call function 'F4IF_INT_TABLE_VALUE_REQUEST'
exporting
retfield = 'FIELDNAME'
value_org = 'S'
tables
value_tab = lt_infotypes
return_tab = lt_return
exceptions
parameter_error = 1
no_values_found = 2
others = 3.
if sy-subrc <> 0.
* Implement suitable error handling here
endif.
loop at lt_return.
loop at s_info.
s_info-high = lt_return-fieldval.
s_info-sign = 'I'.
s_info-option = 'BT'.
modify s_info.
endloop.
if sy-subrc <> 0.
s_info-high = lt_return-fieldval.
s_info-sign = 'I'.
s_info-option = 'BT'.
append s_info.
endif.
endloop.
sort s_info.
delete adjacent duplicates from s_info.
*--- Helper macros --------------------------------------------------
"Create a field symbol table and select the right data into it
define tablesel.
assign lt_dyntab->* to .
lv_low = 1.
lv_high = 1000.
DESCRIBE TABLE s_pernr LINES lv_next.
do.
refresh r_pernr.
append lines of s_pernr from lv_low to lv_high to r_pernr.
if sy-subrc <> 0 or lv_low > lv_next.
exit.
endif.
lv_low = lv_low + 1000.
lv_high = lv_high + 1000.
if lv_where is initial.
if p_curr is INITIAL.
select * from (lv_infoname) APPENDING CORRESPONDING FIELDS OF table
where pernr in r_pernr
order by pernr begda endda.
else.
select * from (lv_infoname) APPENDING CORRESPONDING FIELDS OF table
where pernr in r_pernr
and begda <= sy-datum
and endda >= sy-datum
order by pernr begda endda.
endif.
else.
if p_curr is INITIAL.
select * from (lv_infoname) APPENDING CORRESPONDING FIELDS OF table
where (lv_where)
and pernr in r_pernr
order by pernr begda endda.
else.
select * from (lv_infoname) APPENDING CORRESPONDING FIELDS OF table
where (lv_where)
and pernr in r_pernr
and begda <= sy-datum
and endda >= sy-datum
order by pernr begda endda.
endif.
endif.
enddo.
end-of-definition.
"Move a value from to
define fieldmove.
"Add a loop modifier to the name to avoid name collisions
CONCATENATE &1 &2 into lv_fieldname.
ASSIGN COMPONENT lv_fieldname OF STRUCTURE to .
lv_fieldname = &1.
ASSIGN COMPONENT lv_fieldname of STRUCTURE to .
= .
end-of-definition.
"Get the key fields from the main table
define getfields.
CONCATENATE 'PERNR' '01' into lv_fieldname.
ASSIGN COMPONENT lv_fieldname of STRUCTURE to .
CONCATENATE 'BEGDA' '01' into lv_fieldname.
ASSIGN COMPONENT lv_fieldname of STRUCTURE to .
CONCATENATE 'ENDDA' '01' into lv_fieldname.
ASSIGN COMPONENT lv_fieldname of STRUCTURE to .
end-of-definition.
"Get the key fields from the selection table
define getfields2.
lv_fieldname = 'PERNR'.
ASSIGN COMPONENT lv_fieldname of STRUCTURE to .
lv_fieldname = 'BEGDA'.
ASSIGN COMPONENT lv_fieldname of STRUCTURE to .
lv_fieldname = 'ENDDA'.
ASSIGN COMPONENT lv_fieldname of STRUCTURE to .
end-of-definition.
"Build up the main table from each successive table
define buildmain.
read table lt_loop into ls_loop with key loop = &1.
if is assigned.
create data ls_dynwa2 like line of .
assign ls_dynwa2 to .
added = abap_false.
loop at assigning .
getfields2.
loop at assigning .
"Make sure we're dealing with the correct PERNR
getfields.
check = .
"Make sure we're in the right timeframe
perform check_overlap changing overlapped.
check overlapped = abap_true.
"Now decide if the main table needs another record or if the current record
"should go to multiple main records
"Check if the main table is blank for every field that's filled in this table
"If that's the case, then we just fill this record, if not, then we
"create a new record
concatenate 'PERNR' '&1' into lv_fieldname.
assign component lv_fieldname of structure to .
if is initial.
"Move all our values to this record
loop at lt_disp into ls_disp where infotype = ls_loop-infotype.
fieldmove ls_disp-fieldname '&1'.
endloop.
else.
"Move all our values to this record then append it to the table
move-corresponding to .
loop at lt_disp into ls_disp where infotype = ls_loop-infotype.
concatenate ls_disp-fieldname '&1' into lv_fieldname.
assign component lv_fieldname of structure to .
lv_fieldname = ls_disp-fieldname.
assign component lv_fieldname of structure to .
= .
endloop.
"Append to a new table so we don't process this record another time
append to .
endif.
added = abap_true.
endloop.
if sy-subrc <> 0 or added = abap_false.
"No records added yet, start off with this table's data
loop at lt_disp into ls_disp where infotype = ls_loop-infotype.
fieldmove ls_disp-fieldname '&1'.
endloop.
append to .
endif.
endloop.
endif.
append lines of to .
refresh .
end-of-definition.
*== Main program ====================================================
start-of-selection.
if lt_disp is initial or lt_sel is initial.
message e000(38) with 'Select fields to display'.
endif.
perform pre_select.
perform get_data.
perform disp_data.
*&---------------------------------------------------------------------*
*& Form GET_DISP_FIELDS
*&---------------------------------------------------------------------*
* Get all the fields we want to display for each infotype
*----------------------------------------------------------------------*
form get_disp_fields .
data: lt_popli type standard table of spopli,
ls_popli type spopli,
lt_options type string occurs 0 with header line.
refresh lt_disp.
lv_infotype = '0000'.
do 999 times.
refresh lt_popli.
if lv_infotype in s_info.
concatenate 'PA' lv_infotype into lv_infoname.
select single tabname from dd03l into @data(lv_tabname)
where tabname = @lv_infoname.
check sy-subrc = 0.
select l~tabname, l~fieldname, l~keyflag, l~rollname, t~ddtext
from dd03l as l
inner join dd04t as t
on l~rollname = t~rollname
into table @data(lt_dd03)
where l~tabname = @lv_infoname
and t~ddlanguage = @sy-langu
order by l~position.
delete lt_dd03 where fieldname cs '.INCL'.
delete lt_dd03 where rollname = 'MANDT'.
"Suppress these fields from the selection because we're going to default them
"in for every table
delete lt_dd03 where fieldname = 'PERNR' or fieldname = 'BEGDA' or fieldname = 'ENDDA'.
loop at lt_dd03 into data(ls_dd03).
clear ls_popli-selflag.
concatenate ls_dd03-tabname+2(4) ls_dd03-fieldname ls_dd03-ddtext into ls_popli-varoption separated by '~'.
append ls_popli to lt_popli.
endloop.
call function 'POPUP_TO_DECIDE_LIST'
exporting
mark_flag = 'X'
mark_max = 900
textline1 = lv_infoname
titel = 'Select fields'
tables
t_spopli = lt_popli
exceptions
not_enough_answers = 1
too_much_answers = 2
too_much_marks = 3
others = 4.
if sy-subrc <> 0.
* Implement suitable error handling here
endif.
ls_disp-infotype = lv_infotype.
ls_disp-fieldname = 'PERNR'.
append ls_disp to lt_disp.
ls_disp-fieldname = 'BEGDA'.
append ls_disp to lt_disp.
ls_disp-fieldname = 'ENDDA'.
append ls_disp to lt_disp.
loop at lt_popli into ls_popli where selflag = abap_true.
split ls_popli-varoption at '~' into table lt_options.
read table lt_options index 1.
clear ls_disp.
ls_disp-infotype = lt_options.
read table lt_options index 2.
ls_disp-fieldname = lt_options.
append ls_disp to lt_disp.
endloop.
endif.
lv_infotype = lv_infotype + 1.
enddo.
describe table lt_disp.
p_disc = sy-tfill.
endform.
*&---------------------------------------------------------------------*
*& Form GET_SEL_FIELDS
*&---------------------------------------------------------------------*
* See how the user wants to limit the selections
*----------------------------------------------------------------------*
form get_sel_fields .
data: lv_title like sy-title,
lv_expr type rsds_texpr,
lt_tables like rsdstabs occurs 0 with header line,
lt_fields like rsdsfields occurs 0 with header line,
lv_selid like rsdynsel-selid,
lv_actnum like sy-tfill,
lv_where type rsds_twhere.
check lt_disp is not initial.
refresh lt_sel.
lv_infotype = '0000'.
do 999 times.
if lv_infotype in s_info.
concatenate 'PA' lv_infotype into lv_infoname.
select single tabname from dd03l into @data(lv_tabname)
where tabname = @lv_infoname.
check sy-subrc = 0.
refresh: lt_tables, lt_fields.
clear: lv_where.
lt_tables-prim_tab = lv_infoname.
append lt_tables.
loop at lt_disp into ls_disp where infotype = lv_infotype.
lt_fields-tablename = lv_infoname.
lt_fields-fieldname = ls_disp-fieldname.
append lt_fields.
endloop.
call function 'FREE_SELECTIONS_INIT'
exporting
kind = 'T'
expressions = lv_expr
importing
selection_id = lv_selid
number_of_active_fields = lv_actnum
tables
tables_tab = lt_tables
fields_tab = lt_fields
exceptions
fields_incomplete = 1
fields_no_join = 2
field_not_found = 3
no_tables = 4
table_not_found = 5
expression_not_supported = 6
incorrect_expression = 7
illegal_kind = 8
area_not_found = 9
inconsistent_area = 10
kind_f_no_fields_left = 11
kind_f_no_fields = 12
too_many_fields = 13
dup_field = 14
field_no_type = 15
field_ill_type = 16
dup_event_field = 17
node_not_in_ldb = 18
area_no_field = 19
others = 20.
if sy-subrc <> 0.
* Implement suitable error handling here
endif.
concatenate 'Choose display fields for' lv_infoname into lv_title separated by space.
call function 'FREE_SELECTIONS_DIALOG'
exporting
selection_id = lv_selid
title = lv_title
tree_visible = ' '
importing
where_clauses = lv_where
number_of_active_fields = lv_actnum
tables
fields_tab = lt_fields
exceptions
internal_error = 1
no_action = 2
selid_not_found = 3
illegal_status = 4
others = 5.
if sy-subrc <> 0.
clear: lv_where.
endif.
ls_sel-infotype = lv_infotype.
ls_sel-whereclause = lv_where.
append ls_sel to lt_sel.
endif.
lv_infotype = lv_infotype + 1.
enddo.
data: lv_count type i.
loop at lt_sel into ls_sel where whereclause is not initial.
lv_count = lv_count + 1.
endloop.
p_selc = lv_count.
endform.
*&---------------------------------------------------------------------*
*& Form CHECK_OVERLAP
*&---------------------------------------------------------------------*
* See if the date ranges of the two table overlap
*----------------------------------------------------------------------*
form check_overlap changing p_overlapped.
clear p_overlapped.
if >= and
<= .
p_overlapped = abap_true.
exit.
endif.
if >= and
<= .
p_overlapped = abap_true.
exit.
endif.
if >= and
<= .
p_overlapped = abap_true.
exit.
endif.
if >= and
<= .
p_overlapped = abap_true.
exit.
endif.
endform.
*&---------------------------------------------------------------------*
*& Form GET_DATA
*&---------------------------------------------------------------------*
* Read the infotypes and fill the main table
*----------------------------------------------------------------------*
form get_data .
refresh lt_maincat.
lv_loop = 1.
lv_infotype = '0000'.
lv_cnt = 1.
do 999 times.
if lv_infotype in s_info.
concatenate 'PA' lv_infotype into lv_infoname.
select single tabname from dd03l into @data(lv_tabname)
where tabname = @lv_infoname.
check sy-subrc = 0.
refresh lt_cat.
clear lv_where.
"Dynamically create the table
loop at lt_disp into ls_disp where infotype = lv_infotype.
clear ls_cat.
ls_cat-tabname = lv_infoname.
ls_cat-fieldname = ls_disp-fieldname.
ls_cat-col_pos = lv_cnt.
lv_cnt = lv_cnt + 1.
ls_cat-ref_table = lv_infoname.
ls_cat-ref_field = ls_disp-fieldname.
append ls_cat to lt_cat.
concatenate ls_cat-fieldname lv_loop into ls_cat-fieldname.
append ls_cat to lt_maincat.
endloop.
call method cl_alv_table_create=>create_dynamic_table
exporting
it_fieldcatalog = lt_cat
importing
ep_table = lt_dyntab
exceptions
generate_subpool_dir_full = 1
others = 2.
if sy-subrc <> 0.
* Implement suitable error handling here
endif.
read table lt_sel into ls_sel with key infotype = lv_infotype.
if sy-subrc = 0 and ls_sel-whereclause is not initial.
read table ls_sel-whereclause into ls_where index 1.
lt_wheretab = ls_where-where_tab.
if lt_wheretab[] is not initial.
clear lv_where.
loop at lt_wheretab into ls_wheretab.
concatenate lv_where ls_wheretab-line into lv_where separated by space.
endloop.
endif.
endif.
case lv_loop.
when 1.
tablesel 01.
when 2.
tablesel 02.
when 3.
tablesel 03.
when 4.
tablesel 04.
when 5.
tablesel 05.
when 6.
tablesel 06.
when 7.
tablesel 07.
when 8.
tablesel 08.
when 9.
tablesel 09.
when 10.
tablesel 10.
when 11.
tablesel 11.
when 12.
tablesel 12.
when 13.
tablesel 13.
when 14.
tablesel 14.
when 15.
tablesel 15.
when 16.
tablesel 16.
when 17.
tablesel 17.
when 18.
tablesel 18.
when 19.
tablesel 19.
when 20.
tablesel 20.
when others.
message e000(38) with 'Maximum no. tables exceeded'.
endcase.
"Keep track of which loops handle which infotypes
ls_loop-loop = lv_loop.
ls_loop-infotype = lv_infotype.
append ls_loop to lt_loop.
lv_loop = lv_loop + 1.
endif.
lv_infotype = lv_infotype + 1.
enddo.
"Now build up the final table with all the data
call method cl_alv_table_create=>create_dynamic_table
exporting
it_fieldcatalog = lt_maincat
importing
ep_table = lt_dyntab
exceptions
generate_subpool_dir_full = 1
others = 2.
if sy-subrc <> 0.
* Implement suitable error handling here
endif.
assign lt_dyntab->* to .
call method cl_alv_table_create=>create_dynamic_table
exporting
it_fieldcatalog = lt_maincat
importing
ep_table = lt_dyntab
exceptions
generate_subpool_dir_full = 1
others = 2.
if sy-subrc <> 0.
* Implement suitable error handling here
endif.
assign lt_dyntab->* to .
"Create a work area for us to loop through
create data ls_dynwa like line of .
assign ls_dynwa->* to .
create data ls_dynwa like line of .
assign ls_dynwa->* to .
buildmain: 01, 02, 03, 04, 05, 06, 07, 08, 09, 10.
buildmain: 11, 12, 13, 14, 15, 16, 17, 18, 19, 20.
endform.
*&---------------------------------------------------------------------*
*& Form DISP_DATA
*&---------------------------------------------------------------------*
* Display the main table
*----------------------------------------------------------------------*
form disp_data .
data: lt_fcat type slis_t_fieldcat_alv,
ls_fcat type line of slis_t_fieldcat_alv,
ls_layout type slis_layout_alv,
lt_sort type slis_t_sortinfo_alv,
ls_sort type line of slis_t_sortinfo_alv.
loop at lt_maincat into ls_cat.
clear ls_fcat.
ls_fcat-fieldname = ls_cat-fieldname.
ls_fcat-ref_tabname = ls_cat-ref_table.
ls_fcat-ref_fieldname = ls_cat-ref_field.
"Hide subsequent PERNR, BEGDA, ENDDA fields to avoid clutter
if p_hide = abap_true.
if ls_fcat-fieldname cs 'PERNR' or
ls_fcat-fieldname cs 'BEGDA' or
ls_fcat-fieldname cs 'ENDDA'.
if ls_fcat-fieldname ns '01' and
ls_fcat-fieldname ns 'MAIN'. "Don't chop off the main pernr
ls_fcat-no_out = abap_true.
endif.
endif.
endif.
append ls_fcat to lt_fcat.
endloop.
refresh lt_sort.
ls_sort-fieldname = 'PERNR01'.
append ls_sort to lt_sort.
ls_sort-fieldname = 'BEGDA01'.
append ls_sort to lt_sort.
ls_sort-fieldname = 'ENDDA01'.
append ls_sort to lt_sort.
ls_layout-colwidth_optimize = abap_true.
ls_layout-zebra = abap_true.
call function 'REUSE_ALV_GRID_DISPLAY'
exporting
is_layout = ls_layout
it_sort = lt_sort
it_fieldcat = lt_fcat
tables
t_outtab =
exceptions
program_error = 1
others = 2.
if sy-subrc <> 0.
* Implement suitable error handling here
endif.
endform.
*&---------------------------------------------------------------------*
*& Form PRE_SELECT
*&---------------------------------------------------------------------*
* Go through all the selections and determine which PERNRs to select
* for all the tables
*----------------------------------------------------------------------*
form pre_select .
data: begin of pernrrec,
pernr like pa0000-pernr,
end of pernrrec.
data: lt_pernrs like standard table of pernrrec,
lt_small like standard table of pernrrec,
ls_pernr like pernrrec,
ls_old like pernrrec,
lv_small type i,
lv_pernrs type i,
lv_diff type i.
refresh: lt_pernrs, s_pernr.
loop at lt_sel into ls_sel where whereclause is not initial.
read table ls_sel-whereclause into ls_where index 1.
lt_wheretab = ls_where-where_tab.
if lt_wheretab[] is not initial.
clear lv_where.
loop at lt_wheretab into ls_wheretab.
concatenate lv_where ls_wheretab-line into lv_where separated by space.
endloop.
endif.
concatenate 'PA' ls_sel-infotype into lv_infoname.
if p_curr is initial.
select pernr from (lv_infoname) into table lt_pernrs
where (lv_where)
order by pernr.
else.
select pernr from (lv_infoname) into table lt_pernrs
where (lv_where)
and begda <= sy-datum
and endda >= sy-datum
order by pernr.
endif.
if lt_small is initial.
append lines of lt_pernrs to lt_small.
else.
"Only bring over the overlapping pernrs
loop at lt_small into ls_pernr.
read table lt_pernrs transporting no fields
with key pernr = ls_pernr-pernr
binary search.
check sy-subrc <> 0.
delete lt_small where pernr = ls_pernr-pernr.
endloop.
endif.
endloop.
sort lt_small.
delete adjacent duplicates from lt_small.
clear: ls_old, s_pernr.
loop at lt_small into ls_pernr.
lv_diff = ls_pernr - ls_old.
if lv_diff = 1 and ls_old is not initial.
s_pernr-option = 'BT'.
s_pernr-high = ls_pernr.
else.
if s_pernr is not initial.
append s_pernr.
clear s_pernr.
endif.
s_pernr-sign = 'I'.
s_pernr-option = 'EQ'.
s_pernr-low = ls_pernr.
endif.
ls_old = ls_pernr.
endloop.
if s_pernr is not initial.
append s_pernr.
endif.
endform.
*&---------------------------------------------------------------------*
*& Form GET_INFOTYPES
*&---------------------------------------------------------------------*
* Pull in table names and descriptions for each infotype
*----------------------------------------------------------------------*
form get_infotypes tables pt_infotypes structure infotyperec.
select tabname, ddtext from dd02t into table @data(lt_dd2)
where tabname like 'PA%'
and ddlanguage = @sy-langu.
lv_infotype = '0000'.
do 999 times.
concatenate 'PA' lv_infotype into lv_infoname.
read table lt_dd2 into data(ls_dd2) with key tabname = lv_infoname.
if sy-subrc = 0.
pt_infotypes-fieldname = lv_infotype.
pt_infotypes-desc = ls_dd2-ddtext.
append pt_infotypes.
endif.
lv_infotype = lv_infotype + 1.
enddo.
endform.
Subscribe to:
Posts (Atom)
Thursday, October 27, 2022
HR Infotype Joiner
Often times I need to look up data for multiple PERNRs across multiple infotypes. This can get a bit unwieldy if you're working with a large number of people or a large number of infotypes. So, I created ZZINFOTYPES which is a report that does all the heave lifting for me.
When you run the report you'll get a single ALV output with all the fields for all the matching people similar to the output shown below.
To get started, you choose all the infotypes you want to use.
Once you have all the infotypes selected, it's time to move onto the fields within each infotype. Note that you should select any field that you want to use in your selections or want in your final display. PERNR, start date, and end date are suppressed in the selections because they're always shown in the selection screen.
Each infotype will come up individually and you'll check off all the fields you want.
Once all the fields have been selected, it's time to move on to the selections.
Again, each infotype will present its own selections where normal selection screen actions can be used.
In this example, I chose all active employees from a particular company code and with the first name of Amy. Therefore it shows three selections as active.
At this point, you execute the report as usual and you get a final, single, ALV output with all the requested data that matches the selections.