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.
Related
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.
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.
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.
In ABAP, I have a pretty large internal table, say 31,000 rows. What's the shortest and most efficient way to split that into multiple smaller tables of fixed size, say 1,000 rows each?
Naive way would be:
DATA lt_next_package TYPE tt_table_type.
LOOP AT it_large_table INTO DATA(ls_row).
INSERT ls_row INTO TABLE lt_next_package.
IF lines( lt_next_package ) >= lc_package_size.
INSERT lt_next_package INTO TABLE rt_result.
CLEAR lt_next_package.
ENDIF.
ENDLOOP.
IF lt_next_package IS NOT INITIAL.
INSERT lt_next_packge INTO TABLE rt_result.
ENDIF.
That works and is rather efficient, but looks cumbersome, esp. the don't-forget-the-last-package section at the very end. I believe there must be a better way to do this with the newer ABAP mesh paths and table expressions, but so far couldn't come up with one.
I am not sure if, there is a right way to do it (sure, there are several ways to do it), but you can try this to overcome the last package problem:
WHILE it_large_table IS NOT INITIAL.
LOOP AT it_large_table ASSIGNING FIELD-SYMBOL(<ls_line>) FROM 1 TO 1000.
INSERT <ls_line> INTO TABLE lt_next_package.
ENDLOOP.
DELETE it_large_table FROM 1 TO 1000.
INSERT lt_next_package INTO TABLE rt_table.
CLEAR: lt_next_package.
ENDWHILE.
Based on JozsefSzikszai's answer, devised another option:
rt_result = VALUE #( FOR i = 1
UNTIL i > round( val = lines( it_large_table) / lc_package_size
dec = 0
mode = cl_abap_math=>round_up )
LET lv_end = i * lc_package_size
lv_start = lv_end - lc_package_size + 1 IN
( VALUE <result-type>(
( LINES OF it_large_table FROM lv_start TO lv_end ) ) ) ).
Somewhat reinvention of both Florian and Jozsef approaches.
Prerequisits:
TYPES:
BEGIN OF line,
rows TYPE string,
slice TYPE bseg_t,
END OF line,
itab TYPE STANDARD TABLE OF line WITH EMPTY KEY,
bseg_t TYPE STANDARD TABLE OF bseg WITH EMPTY KEY.
DATA: result TYPE itab.
Filling large table:
SELECT * UP TO 31000 ROWS
INTO TABLE #DATA(lt_bseg)
FROM bseg.
Here we costruct table of tables which contains slices of the main table by 1000 rows each.
WHILE lt_bseg IS NOT INITIAL.
result = VALUE itab( BASE result
(
rows = | { sy-index * 1000 }-{ sy-index * 1000 + 1000} |
slice = VALUE bseg_t( FOR wa IN lt_bseg INDEX INTO i FROM i + 1 TO i + 1
( LINES OF lt_bseg from i TO i + 999 ) )
)
).
DELETE lt_bseg FROM 1 TO 1000.
ENDWHILE.
Looks somewhat as our requirement, no?
Here are two ways to build a table of subtables AKA pagination:
METHOD prepare_data.
TYPES:
BEGIN OF line,
name TYPE string,
subset TYPE salv_t_row,
END OF line,
itab TYPE STANDARD TABLE OF line WITH EMPTY KEY.
CONSTANTS: lc_package_size TYPE i VALUE 3.
DATA: result TYPE itab,
it_rows TYPE salv_t_row.
DO round( val = lines( it_rows ) / lc_package_size
dec = 0
mode = cl_abap_math=>round_up ) TIMES.
DATA(lv_end) = sy-index * lc_package_size.
DATA(lv_start) = lv_end - lc_package_size + 1.
APPEND INITIAL LINE TO result ASSIGNING FIELD-SYMBOL(<subset>).
<subset>-name = | Subset { sy-index } |.
<subset>-subset = VALUE #( ( LINES OF it_rows FROM lv_start TO lv_end ) ).
ENDDO.
clear result.
result = VALUE itab( FOR i = 1
UNTIL i > round( val = lines( it_rows ) / lc_package_size
dec = 0
mode = cl_abap_math=>round_up )
LET k = 1 IN
(
name = | Subset { i } |
subset = VALUE salv_t_row(
LET
end = i * lc_package_size
start = end - lc_package_size + 1
IN
( LINES OF it_rows from start to end )
)
)
).
Hope this helps. The code here is tested and works. Just copy-paste (and generate some data).
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.