What is reason why my second list for my ALV report not showing any info? - abap

I am trying to create a classical list. Everything until At line-selection works. The problem that I have is with At line-selection. First, I execute the program and it shows me the parameter s_matnr, I then enter the
values (e.g. 500-100 - 500-400) and it gets me to the first list. After that, I choose one field by checking and I double-click on it. It then shows me another window and when I try to get to the second list that I've created it just doesn't output any info on the screen.
What I have to do is to get two tables, ekko and ekpo, and to display the info in a list. For that, I have tried to create a inner join between the two tables and then loop through them and write the info. Also, I have to calculate the total quantity of each Purchase order.
Could you help me out? Thank you!
The list has to look like this :
My lines of code :
TOP-OF-PAGE.
WRITE: / 'User:',sy-uname, 29 'Programe Name: ', sy-cprog,
/ 'Date: ', sy-datum.
ULINE.
TABLES mara.
TYPES : BEGIN OF ty_mara,
chck TYPE char1,
matnr TYPE mara-matnr,
maktx TYPE makt-maktx,
ntgew TYPE mara-ntgew,
gewei TYPE mara-gewei,
spart TYPE mara-spart,
name TYPE string,
END OF ty_mara,
tt_mara TYPE STANDARD TABLE OF ty_mara.
TYPES: BEGIN OF ty_marc,
matnr TYPE marc-matnr,
werks TYPE marc-werks,
END OF ty_marc.
TYPES:BEGIN OF ty_ab,
ebeln TYPE ekpo-ebeln,
lifnr TYPE ekko-lifnr,
bedat TYPE ekko-bedat,
ekorg TYPE ekko-ekorg,
ekgrp TYPE ekko-ekgrp,
bukrs TYPE ekko-bukrs,
ebelp TYPE ekpo-ebelp,
aedat TYPE ekpo-aedat,
menge TYPE ekpo-menge,
meins TYPE ekpo-meins,
netpr TYPE ekpo-netpr,
END OF ty_ab.
DATA:
gt_ab TYPE TABLE OF ty_ab,
gs_ab TYPE ty_ab.
TYPES: BEGIN OF ty_name,
cbx TYPE c,
cmatnr TYPE mara-matnr,
END OF ty_name.
DATA:
gv_var1 TYPE string VALUE 'Purchase order',
gv_var2 TYPE string VALUE 'Vendor',
gv_var3 TYPE string VALUE 'Document Date',
gv_var4 TYPE string VALUE 'Purchasing Org.',
gv_var5 TYPE string VALUE 'Purchasing Group',
gv_var6 TYPE string VALUE 'Company Code',
gv_quantity TYPE ekpo-menge VALUE 0.
DATA:
gv_v1 TYPE string VALUE 'Item',
gv_v2 TYPE string VALUE 'Delivery Date',
gv_v3 TYPE string VALUE 'PO Quantity',
gv_v4 TYPE string VALUE 'Unit',
gv_v5 TYPE string VALUE 'Net Price'.
TYPES: BEGIN OF ty_ekko,
ebeln TYPE ekko-ebeln,
lifnr TYPE ekko-lifnr,
bedat TYPE ekko-bedat,
ekorg TYPE ekko-ekorg,
ekgrp TYPE ekko-ekgrp,
bukrs TYPE ekko-bukrs,
END OF ty_ekko.
TYPES:BEGIN OF ty_ekpo,
ebeln TYPE ekpo-ebeln,
ebelp TYPE ekpo-ebelp,
aedat TYPE ekpo-aedat,
menge TYPE ekpo-menge,
meins TYPE ekpo-meins,
netpr TYPE ekpo-netpr,
END OF ty_ekpo.
DATA: gt_mara TYPE TABLE OF ty_mara,
gs_mara TYPE ty_mara,
gt_marc TYPE TABLE OF ty_marc,
gs_marc TYPE ty_marc,
gt_popup TYPE ty_marc,
gv_string TYPE string,
gv_line TYPE i,
gs_name TYPE ty_name,
gt_name TYPE TABLE OF ty_name,
gt_ekko TYPE TABLE OF ty_ekko,
gs_ekko TYPE ty_ekko,
gt_ekpo TYPE TABLE OF ty_ekpo,
gs_ekpo TYPE ty_ekpo.
SELECT-OPTIONS s_matnr FOR mara-matnr.
START-OF-SELECTION.
SET PF-STATUS 'DIALOG'.
SELECT a~matnr, a~ntgew, a~gewei, a~spart, b~maktx
FROM mara AS a
INNER JOIN makt AS b
ON a~matnr = b~matnr
INTO CORRESPONDING FIELDS OF TABLE #gt_mara
WHERE a~matnr IN #s_matnr
AND b~spras = 'E'.
WRITE: AT 3 'Material', AT 30 'Material Description', AT 60 'Net Weight',
AT 80 'Unit', AT 85 'Division'.
LOOP AT gt_mara INTO gs_mara.
IF gs_mara-ntgew < 10.
WRITE: / gs_name-cbx AS CHECKBOX,
gs_mara-matnr COLOR 4,
gs_mara-maktx COLOR 4,
gs_mara-ntgew COLOR 4,
gs_mara-gewei COLOR 4,
gs_mara-spart COLOR 4.
ELSE.
WRITE: / gs_name-cbx AS CHECKBOX,
gs_mara-matnr COLOR COL_NEGATIVE,
gs_mara-maktx COLOR COL_NEGATIVE,
gs_mara-ntgew COLOR COL_NEGATIVE,
gs_mara-gewei COLOR COL_NEGATIVE,
gs_mara-spart COLOR COL_NEGATIVE.
ENDIF.
ENDLOOP.
AT USER-COMMAND.
CASE sy-ucomm.
WHEN'DISPLAY'.
SET PF-STATUS 'POP'.
SET TITLEBAR 'Titlu'.
WINDOW STARTING AT 5 3 ENDING AT 40 10.
CLEAR: gs_mara,gv_string.
DO .
READ LINE sy-index FIELD VALUE gs_name-cbx INTO gs_name-cbx.
IF sy-subrc = 0.
IF gs_name-cbx = 'X'.
READ LINE sy-index FIELD VALUE gs_mara-matnr INTO gs_name-cmatnr.
SELECT marc~matnr marc~werks
INTO CORRESPONDING FIELDS OF TABLE gt_marc
FROM marc
WHERE marc~matnr LIKE gs_name-cmatnr.
IF sy-subrc = 0.
LOOP AT gt_marc INTO gs_marc.
WRITE: / gs_marc-matnr, gs_marc-werks.
ENDLOOP.
ELSE .
MESSAGE e208(00) WITH 'No records found!'.
ENDIF.
ENDIF.
ELSE.
EXIT.
ENDIF.
ENDDO.
WRITE:/ '' .
ENDCASE.
AT LINE-SELECTION.
GET CURSOR LINE gv_line.
READ LINE gv_line FIELD VALUE gs_mara-matnr INTO gs_name-cmatnr.
SELECT
c~lifnr
c~bedat
c~ekorg
c~ekgrp
c~bukrs
c~ebeln
d~ebelp
d~aedat
d~menge
d~meins
d~netpr
FROM ekko AS c
INNER JOIN ekpo AS d
ON c~ebeln = d~ebeln
INTO CORRESPONDING FIELDS OF TABLE gt_ab
WHERE d~matnr = gs_name-cmatnr .
LOOP AT gt_ab INTO gs_ab.
IF sy-subrc = 0.
gv_quantity = 0.
ULINE.
WRITE:/
gs_ekko-ebeln UNDER gv_var1 COLOR 6,
gs_ekko-lifnr UNDER gv_var2 COLOR 6,
gs_ekko-bedat UNDER gv_var3 COLOR 6,
gs_ekko-ekorg UNDER gv_var4 COLOR 6,
gs_ekko-ekgrp UNDER gv_var5 COLOR 6,
gs_ekko-bukrs UNDER gv_var6 COLOR 6.
WRITE:/
gs_ekpo-ebelp UNDER gv_v1 ,
gs_ekpo-aedat UNDER gv_v2 ,
gs_ekpo-menge UNDER gv_v3 ,
gs_ekpo-meins UNDER gv_v4 ,
gs_ekpo-netpr UNDER gv_v5 .
gv_quantity = gv_quantity + gs_ekpo-menge.
WRITE:/ 'Total Quantity=' UNDER gv_v3 COLOR 3, gv_quantity COLOR 3.
ELSE.
MESSAGE e208(00) WITH 'Nu a fost gasit!'.
ENDIF.
ENDLOOP.

I guess you need to debug your code to check what's going on, what the exact issue is.
Here is a Minimal Reproducible Example, which demonstrates that there's basically no issue from the different list levels:
REPORT.
TYPES ty_matnr TYPE c LENGTH 10.
DATA matnr TYPE ty_matnr.
SELECT-OPTIONS s_matnr FOR matnr.
TOP-OF-PAGE.
WRITE: / 'User:',sy-uname, 29 'Programe Name: ', sy-cprog,
/ 'Date: ', sy-datum.
ULINE.
START-OF-SELECTION.
WRITE / 'Enter DISPLAY in the Command Field and press Enter'.
AT USER-COMMAND.
CASE sy-ucomm.
WHEN'DISPLAY'.
WINDOW STARTING AT 5 3 ENDING AT 40 10.
matnr = '500-100'.
WRITE / matnr.
matnr = '500-400'.
WRITE / matnr.
matnr = '700-220'.
WRITE / matnr.
ENDCASE.
AT LINE-SELECTION.
DATA gv_line TYPE i.
GET CURSOR LINE gv_line.
DATA matnr2 TYPE ty_matnr.
READ LINE gv_line FIELD VALUE matnr INTO matnr2.
WRITE : / 'Second list. Selected line is', matnr2.

Related

Enhance performance of ABAP report when using OpenSQL query and function call

I have an issue with my ABAP report for it being very slow and taking a long time to complete.
My original report had a query to MARA to get all materials into an iTab, loop over it and then query additional tables for each material and store the necessary data and a function call to READ_TEXT in an output iTab.
Since this process takes very long to compete I changed the code to rely more on the database to handle data access instead of making queries for additionoal data each at a time. But still the time to complete is very long for the amount of data to be fetched.
Current code looks like this
report z_test_report.
types:
begin of _output,
matnr type mara-matnr,
text01 type c length 40,
text02 type c length 40,
ntgew type mara-ntgew,
matkl type mara-matkl,
ean11 type mara-ean11,
preis type p length 6 decimals 2,
bstd type mbew-lbkum,
laeng type marm-laeng,
breit type marm-breit,
hoehe type marm-hoehe,
volum type marm-volum,
end of _output,
t_output type _output.
data:
gt_output type table of t_output,
gs_output like line of gt_output,
gr_table type ref to cl_salv_table,
gr_funct type ref to cl_salv_functions,
gr_columns type ref to cl_salv_columns_table,
gr_column type ref to cl_salv_column.
selection-screen begin of block b01 with frame.
parameters: pa_date type d obligatory.
parameters: pa_kschl type t685-kschl obligatory.
parameters: pa_pltyp type t189-pltyp obligatory.
selection-screen end of block b01.
start-of-selection.
select
m~matnr,
m~ntgew,
m~matkl,
m~ean11,
t~maktx,
b~lbkum,
l~laeng,
l~breit,
l~hoehe,
l~volum
from
mara as m
left join
makt as t
on
m~matnr = t~matnr
and
t~spras = 'D'
left join
mbew as b
on
b~matnr = m~matnr
and
b~bwkey = '1100'
left join
marm as l
on
l~matnr = m~matnr
and
l~meinh = m~meins
into
#data(wa_daten)
order by
m~matnr.
gs_output = corresponding #( wa_daten ).
select single
*
from
a908
where
a908~kappl = 'V'
and
a908~kschl = #pa_kschl
and
a908~vkorg = '1100'
and
a908~pltyp = #pa_pltyp
and
a908~matnr = #wa_daten-matnr
and
a908~datab < #sy-datum
and
a908~datbi > #sy-datum
into
#data(gs_a908).
if ( sy-subrc = 0 ).
select single
*
from
konp
where
konp~knumh = #gs_a908-knumh
into
#data(gs_knop).
if ( sy-subrc = 0 ).
gs_output-preis = gs_knop-kbetr.
endif.
endif.
data:
material_name like stxh-tdname,
textlines like tline occurs 0,
textline like line of textlines.
material_name = gs_output-matnr.
call function 'READ_TEXT'
exporting
id = 'GRUN'
language = 'D'
name = material_name
object = 'MATERIAL'
tables
lines = textlines
exceptions
id = 1
language = 2
name = 3
not_found = 4
object = 5
reference_check = 6
wrong_access_to_archive = 7
others = 8.
if ( sy-subrc = 0 ).
loop at textlines into textline.
concatenate gs_output-text02 textline-tdline into gs_output-text02.
endloop.
endif.
condense gs_output-text02.
append gs_output to gt_output.
endselect.
try.
cl_salv_table=>factory(
exporting
list_display = if_salv_c_bool_sap=>false
importing
r_salv_table = gr_table
changing
t_table = gt_output
).
catch cx_salv_msg.
endtry.
gr_funct = gr_table->get_functions( ).
gr_funct->set_all( abap_true ).
gr_table->display( ).
I think this code can be improved since reading 17k entries from MARA and joining them with the other tables should not be the bottle neck. Changing the old code to the current one reduced the runtime from about 45s down to 30s, removing the READ_TEXT only made the report take about 5s less.
If anyone has an idea it would be really appreciated. Or if anyone knows a tool to measure report performance to find out about bottle necks.

Checkbox multiple selection filter

I want to filter the data into my program depending what checkbox is selected or not.
parameters: p_z1 as checkbox DEFAULT 'X' ,
p_z2 as checkbox.
selection-screen end of block b4.
So if one of these two is selected or if both are selected how can I filter my data?
select single * from mara where matnr = pv_matnr
and "if checkbox one is selected" where matkl = t023-matkl.
"if checkbox two is selected" where matkl = v023-matkl.
You can prepare dynamic where clause -
DATA : lv_query TYPE string.
CONCATENATE 'MATNR = PV_MATNR' lv_query INTO lv_query.
IF p_z1 = 'X'.
CONCATENATE lv_query 'AND MATKL = T023-MATKL' INTO lv_query SEPARATED BY space.
ENDIF.
IF p_z2 = 'X'.
CONCATENATE lv_query 'AND MATKL = V023-MATKL' INTO lv_query SEPARATED BY space.
ENDIF.
SELECT SINGLE * FROM mara WHERE (lv_query).
"Dynamic" queries are to be avoided as far as possible, just to make it easier to check the code against possible SQL injection attacks (with SELECT … WHERE (lv_query), there could be a Denial-of-Service attack with an empty lv_query empty). So I would write the code by divScorp as follows:
parameters: p_z1 as checkbox DEFAULT 'X' ,
p_z2 as checkbox,
pv_matnr TYPE mara-matnr.
DATA: t023 TYPE t023, v023 TYPE v023, mara TYPE mara.
DATA range_matkl TYPE RANGE OF mara-matkl.
CLEAR range_matkl.
IF p_z1 = 'X'.
APPEND VALUE #( sign = 'I' option = 'EQ' low = t023-matkl ) TO range_matkl.
ENDIF.
IF p_z2 = 'X'.
APPEND VALUE #( sign = 'I' option = 'EQ' low = v023-matkl ) TO range_matkl.
ENDIF.
SELECT SINGLE * FROM mara WHERE MATNR = PV_MATNR and matkl IN range_matkl.
PS: my code (and the one of divScorp) is non-sense because pureAbap algorithm is incorrect : in case p_z1 and p_z2 are both 'X', then there's the risk that the SELECT returns nothing if t023-matkl is different from v023-matkl. Maybe p_z1 and p_z2 should be converted into radio buttons? (only one of the two can be selected?)
You can always use:
IF chck1 = 'X' and chck2 = 'X'.
SELECT ... WHERE both.
ELSEIF chck1 = 'X'.
SELECT ... WHERE ...
ELSEIF chck2 = 'X'.
SELECT ... WHERE ...
ENDIF.
But I guess that's not what you wanted to do. Not the most elegant way but hey - it works.

from which table to take base quantity for production orders?

Does anybody know from which table to take base quantity for production orders? I think is in AFVV-MGVRG but I am not sure.
I need it in the structure below:
TYPES: BEGIN OF tables_fields,
AUFNR TYPE AUFK-AUFNR, "Nr comanda productie
* AUFNR TYPE AUFM-AUFNR, "Nr comanda productie
* MAKTX TYPE MAKT-MAKTX, "Descriere material
AUART TYPE AUFK-AUART, "Tip comanda /Sectie
WERKS TYPE AUFK-WERKS, "Unitate logistica
TXT TYPE T003P-TXT, "Nume sectie
"MENGE TYPE AUFM-MENGE, "Cantitate buc predata
GAMNG TYPE AFKO-GAMNG, "Cantitatea totala vrac
GMEIN TYPE AFKO-GMEIN, "Unitatea de masura kg cantitate totala
"WEMNG TYPE AFPO-WEMNG, "Cantitatea totala livrata
ERFMG TYPE AUFM-ERFMG, "Cantitatea totala livrata defalcata
GSTRP Type AFKO-GSTRP, "Data lansarii comenzii
GLTRP TYPE AFKO-GLTRP, "Data estimativa a finalizarii comenzii
BLDAT TYPE AUFM-BLDAT, "Data finalizarii comenzii
MGVRG TYPE AFVV-MGVRG, "Bucati pe comanda-cant de baza
"MEINS TYPE AUFM-MEINS,"Unitate bucati pe comanda-rectificat
MEINH TYPE AFVV-MEINH, "Unitate de masura bucati pe comanda
MENGE TYPE AUFM-MENGE, "Cantitate buc predata
* BMENG TYPE STKO-BMENG, "Cantitatea de baza estimata
* BMEIN TYPE STKO-BMEIN, "Unitatea de masura cantitatea de baza estimata
MATNR TYPE AUFM-MATNR, "Cod material
"PLNBEZ TYPE AFKO-PLNBEZ,"Cod material
MAKTX TYPE MAKT-MAKTX, "Descriere material
MBLNR TYPE AUFM-MBLNR,
ZEILE TYPE AUFM-ZEILE,
BMSCH TYPE AFVV-BMSCH,
SPRAS TYPE T003P-SPRAS,"Restrictionare limba
ZILEDEP TYPE I,"AFKO-GLTRP, "Filtru date intre care s-au realizat comenzi
COMDEP(10) TYPE C,"Nr zile comanda depasita
COMINTRE TYPE AFKO-GSTRP,"Data comenzi termen depasit
* ERDAT TYPE AUFK-ERDAT, "Data lansarii comenzii - campul vechi
* LTRMI TYPE AFPO-LTRMI, "Data finalizarii comenzii noul camp
"ISTAT TYPE TJ02T-ISTAT,
"TXT04 type TJ02T-TXT04, "Text scurt stare comanda
"TXT30 TYPE TJ02T-TXT30, "Text lung stare comanda
line_color(4) TYPE c,
END OF tables_fields.
So you want to convert a quantity in its base unit.
if lf_afpo_umren > 0. "if 0 division by zero dump
try.
lf_afpo_psmng_basme = lf_afpo_psmng * lf_afpo_umrez / lf_afpo_umren
catch cx_sy_arithmetic_overflow.
"do somethin, e.g. call function 'maximal_value_get'
catch cx_sy_arithmetic_error.
"do something, e.g. clear lf_afpo_psmng_basme.
else.
"try it manually with table MARA/MARM
"or try function module
CALL FUNCTION 'MD_CONVERT_MATERIAL_UNIT'
EXPORTING
i_matnr = lf_matnr
i_in_me = lf_afpo_amein
i_out_me = lf_mara_meins
i_menge = lf_afpo_psmng
IMPORTING
e_menge = lf_afpo_psmng_basme
EXCEPTIONS
error_in_application = 1
error = 2
OTHERS = 3.
if sy-subrc <> 0.
"do something, clear lf_quantity_basme
endif.
it seems that the base quantity is calculated by AFPO-PSMNG / AFPO-UMREN. in this case the result is same as base quantity.

How to transpose an internal table rows into columns?

I want to transpose my internal table rows into column and i want to fix the first column,i am trying to do it with the following code but i am not getting the expected result....it is not converting all the rows into columns
*Types Declaration
Types: BEGIN OF ty_t001w,
ekorg TYPE t001w-ekorg,
werks TYPE t001w-werks,
name1 TYPE t001w-name1,
END OF ty_t001w.
**Field Symbols Declaration
FIELD-SYMBOLS: <fs1> TYPE any,
<fs2> TYPE any.
**Internal table and work area declaration
DATA: it1_col_row TYPE STANDARD TABLE OF ty_t001w,
wa1_col_row TYPE ty_t001w,
it2_col_row TYPE STANDARD TABLE OF ty_t001w,
wa2_col_row TYPE ty_t001w,
cline TYPE sy-tabix.
**Filling internal table with data
Select *
from t001w into corresponding fields of table it1_col_row
where ekorg = p_ekorg
and fabkl = p_fabkl.
**Looping Internal table to display data
LOOP AT it1_col_row INTO wa1_col_row.
WRITE: / wa1_col_row-ekorg, wa1_col_row-werks,wa1_col_row-name1.
ENDLOOP.
WRITE: /.
**Looping internal table to change rows into columns
LOOP AT it1_col_row INTO wa1_col_row.
CLEAR wa2_col_row.
ASSIGN COMPONENT sy-tabix OF STRUCTURE wa2_col_row TO <fs1>.
cline = sy-tabix.
DO.
ASSIGN COMPONENT sy-index OF STRUCTURE wa1_col_row TO <fs2>.
IF sy-subrc NE 0.
EXIT.
ENDIF.
IF cline = 1.
<fs1> = <fs2>.
APPEND wa2_col_row TO it2_col_row.
ELSE.
READ TABLE it2_col_row INTO wa2_col_row INDEX sy-index.
<fs1> = <fs2>.
MODIFY it2_col_row FROM wa2_col_row INDEX sy-index.
ENDIF.
ENDDO.
ENDLOOP.
*
**Looping internal table to display
LOOP AT it2_col_row INTO wa2_col_row.
WRITE: / wa2_col_row-ekorg,wa2_col_row-werks, wa2_col_row-name1.
ENDLOOP.
Notice that the field types of your ty_t001w have different length:
ekorg TYPE t001w-ekorg has CHAR 4
werks TYPE t001w-werks has also CHAR 4, but
name1 TYPE t001w-name1 has CHAR 30
You are using this same type ty_t001w for your source table (it1_col_row) as well as your target table (it2_col_row). So when you are mapping your source rows table to the target columns table then the 30 character field name1 is mapped to the 4 character field ekorg. When I executed your program in my system I had the following output (dependent on the contents of my DB table t001w):
0001 0001 Werk 0001
0001 0002 Werk 0002
0001 0003 Werk 0003
0001 RAD1 Werk RAD1
0001 0001 0001
0001 0002 RAD1
Werk Werk Werk RAD1
At first glance this looks like "it is not converting all the rows into columns". But in the debugger I noticed that "Werk 0001" is actually one value, not two! However the value is truncated to only "Werk" because it is mapped from a 30 character field to the 4 character field. This happens to the bottom value of column 1 ("Werk 0002") and 2 ("Werk 0003"). The bottom value of column 3 ("Werk RAD1") is mapped correctly because here it's mapped from the 30 character field to the 30 character field.
To correct this issue I have created an extra TYPES definition ty_t001w_col for the target table it2_col_row. In this TYPE all fields have the maximum length of 30 characters ensuring no truncation may occur (see abap code below). It generates the following output:
0001 0001 Werk 0001
0001 0002 Werk 0002
0001 0003 Werk 0003
0001 RAD1 Werk RAD1
0001 0001 0001
0001 0002 RAD1
Werk 0001 Werk 0002 Werk RAD1
The corrected report:
REPORT zhd_stackoverflow_q27163908.
PERFORM function
USING '0001'
'01'.
FORM function
USING p_ekorg TYPE ekorg
p_fabkl TYPE fabkl.
Types Declaration
TYPES: BEGIN OF ty_t001w,
ekorg TYPE t001w-ekorg,
werks TYPE t001w-werks,
name1 TYPE t001w-name1,
END OF ty_t001w.
TYPES: BEGIN OF ty_t001w_col,
ekorg TYPE t001w-name1,
werks TYPE t001w-name1,
name1 TYPE t001w-name1,
END OF ty_t001w_col.
*Field Symbols Declaration
FIELD-SYMBOLS: <fs1> TYPE any,
<fs2> TYPE any.
*Internal table and work area declaration
DATA: it1_col_row TYPE STANDARD TABLE OF ty_t001w,
wa1_col_row TYPE ty_t001w,
it2_col_row TYPE STANDARD TABLE OF ty_t001w_col,
wa2_col_row TYPE ty_t001w_col,
cline TYPE sy-tabix.
*Filling internal table with data
SELECT *
FROM t001w INTO CORRESPONDING FIELDS OF TABLE it1_col_row
WHERE ekorg = p_ekorg
AND fabkl = p_fabkl.
*Looping Internal table to display data
LOOP AT it1_col_row INTO wa1_col_row.
WRITE: / wa1_col_row-ekorg, wa1_col_row-werks,wa1_col_row-name1.
ENDLOOP.
WRITE: /.
*Looping internal table to change rows into columns
LOOP AT it1_col_row INTO wa1_col_row.
CLEAR wa2_col_row.
ASSIGN COMPONENT sy-tabix OF STRUCTURE wa2_col_row TO <fs1>.
cline = sy-tabix.
DO.
ASSIGN COMPONENT sy-index OF STRUCTURE wa1_col_row TO <fs2>.
IF sy-subrc NE 0.
EXIT.
ENDIF.
IF cline = 1.
<fs1> = <fs2>.
APPEND wa2_col_row TO it2_col_row.
ELSE.
READ TABLE it2_col_row INTO wa2_col_row INDEX sy-index.
<fs1> = <fs2>.
MODIFY it2_col_row FROM wa2_col_row INDEX sy-index.
ENDIF.
ENDDO.
ENDLOOP.
*Looping internal table to display
LOOP AT it2_col_row INTO wa2_col_row.
WRITE: / wa2_col_row-ekorg,wa2_col_row-werks, wa2_col_row-name1.
ENDLOOP.
ENDFORM.

Group invoices by entity, with LOOP AT

My program outputs a list with some invoice and details and I want them to appear by entity.
The list shows the entity number and name repeating in every line of the list, but I want it to appear grouped by.
e.g. there are 4 invoices: two from each entity, how to show the entity and all of the respective invoices and then the other entity, and so on?
The code I have is this one:
FORM select_data3 CHANGING lt_data LIKE gt_map1.
FIELD-SYMBOLS: <fs_main> TYPE zimposto_consumo.
SELECT a~belnr d~spart a~bldat a~waers c~wrbtr a~hwaer c~dmbtr
INTO CORRESPONDING FIELDS OF TABLE lt_data
FROM ( ( bkpf AS a
INNER JOIN bsis AS c ON c~belnr = a~belnr
AND buzei = 1 )
INNER JOIN vbrk AS d ON d~xblnr = c~belnr )
WHERE a~gjahr in gjahr.
LOOP AT lt_data ASSIGNING <fs_main>.
clear <fs_main>-kbetr.
clear <fs_main>-fwste.
clear <fs_main>-hwste.
SELECT SINGLE kbetr fwste hwste FROM bset
INTO (<fs_main>-kbetr, <fs_main>-fwste, <fs_main>-hwste)
WHERE belnr = <fs_main>-belnr.
clear <fs_main>-koart.
SELECT SINGLE koart kunnr FROM bseg
INTO (<fs_main>-koart, wa_bseg-kunnr)
WHERE belnr = <fs_main>-belnr.
IF <fs_main>-koart = 'D'.
SELECT SINGLE name1 FROM kna1
INTO (wa_bseg-name1)
WHERE kunnr = wa_bseg-kunnr.
IF sy-subrc = 0.
FORMAT COLOR COL_TOTAL INTENSIFIED ON.
WRITE:/ sy-uline(137), / sy-vline NO-GAP,
2 'Entidade: ', wa_bseg-kunnr, wa_bseg-name1,
137 sy-vline NO-GAP, / sy-uline(137).
FORMAT COLOR COL_NORMAL INTENSIFIED OFF.
WRITE:/
sy-vline NO-GAP,
(16) <fs_main>-belnr NO-GAP,
sy-vline NO-GAP,
(16) <fs_main>-spart NO-GAP,
sy-vline NO-GAP,
(10) <fs_main>-bldat NO-GAP,
sy-vline NO-GAP.
perc = <fs_main>-kbetr / 10.
...
ENDIF.
ENDIF.
ENDLOOP.
ENDFORM.
I used a block AT NEW ... ENDAT inside the block LOOP AT ... ENDLOOP.