I have a code like this:
i_mahn is a itab.
Data: gt_mahn type table of i_mahn,
gs_result type i_mahn.
LOOP AT gt_mahn into gs_result
SELECT * FROM mhnd
INTO gs_mhnd
WHERE laufd EQ gs_result-laufd
AND laufi EQ gs_result-laufi
AND cpdky EQ gs_result-cpdky
MOVE-CORRESPONDING gs_mhnd TO gs_result.
ENDSELECT.
ENDLOOP.
and I want to change it to a loop with a field symbol but how? I know that the field-symbol only contains the positions of where the information have been but I dont know how to use the field symbol withe the select in this case....
field-symbols: <gs_mahn> like line of gt_mahn
LOOP AT gt_mahn appending <gs_mahn>
SELECT * FROM mhnd
INTO ???
WHERE laufd EQ <gs_mahn>-laufd
AND laufi EQ <gs_mahn>-laufi
AND cpdky EQ <gs_mahn>-cpdky
MOVE-CORRESPONDING ??? TO ???.
ENDSELECT.
ENDLOOP.
field-symbols: <gs_mahn> like line of gt_mahn.
LOOP AT gt_mahn ASSIGNING <gs_mahn>.
SELECT * FROM mhnd INTO gt_mahn
WHERE laufd EQ <gs_mahn>-laufd
AND laufi EQ <gs_mahn>-laufi
AND cpdky EQ <gs_mahn>-cpdky
MOVE-CORRESPONDING <gs_mahn> TO <whatever>.
ENDSELECT.
ENDLOOP.
I really don't know what you are doing, but in my example you can see how to use field-symbols... google might have also known this easily ... https://help.sap.com/doc/abapdocu_750_index_htm/7.50/en-US/abenfield-symbol_inline.htm
Related
Let's say I have a table quants and want to find out if any line exists, where the field lenum is not initial. The table is declared inline using a select statement, so I do not have a key available.
Because I don't have a key, the following solution does not work:
line_exists( VALUE #( FOR wa IN quants WHERE ( lenum IS NOT INITIAL ) ( wa ) ) )
Since I want to check for inequality, a table expression does not work:
line_exists( quants[ lenum NE '' ] )
The only solution that I have come up with so far is the following:
abap_true EQ REDUCE abap_bool( INIT bool = abap_false FOR quant IN quants WHERE ( lenum IS NOT INITIAL ) NEXT bool = abap_true )
Obviously there are "old fashioned" solutions, but is there any newer-style?
By "old fashioned" I mean solutions like this:
LOOP AT quants INTO DATA(wa).
IF wa-lenum IS INITIAL.
DATA(found) = abap_true.
ENDIF.
ENDLOOP.
IF found EQ abap_true.
...
ENDIF.
The only thin in "new fashion" would be SELECT, FROM #itab.
DATA(lv_exists) = abap_false.
SELECT SINGLE #abap_true FROM #lt_quant AS quant WHERE quant~lenum IS NOT INITIAL INTO #lv_exists.
See documentation link for performance impact (best case is handled like a table in the table buffer) and limitations (e.g. no string column).
The most performant and less restrictions would be this:
LOOP AT lt_quant TRANSPORTING NO FIELDS WHERE lenum IS NOT INITIAL.
EXIT.
ENDLOOP.
DATA(lv_exists) = xsdbool( sy-subrc = 0 ).
I have a SELECT query with the aggregate function group by. But my program shows only the last line items. I want to show all the line items.
Example of expected result:
{"numOfRec":"50",
"shipmentsDetails":[
{"orderNum":"1000101730",
"deliveryOrderNum":"0085099852",
"prodCode":"OE8002L18",
"batchCode":"0000029927",
"qty":"108.000" } ,
{"orderNum":"1000101730",
"deliveryOrderNum":"0085099852",
"prodCode":"OE8407L18",
"batchCode":"0000029928",
"qty":"36.000" } ,
{"orderNum":"1000101730",
"deliveryOrderNum":"0085099852",
"prodCode":"SUE9433G1",
"batchCode":"0000029923",
"qty":"180.000" }]}
Example of actual result (in i_output):
{"numOfRec":"1",
"shipmentsDetails":[
{"orderNum":"1000101760",
"deliveryOrderNum":"0085099889",
"prodCode":"UE9101G5",
"batchCode":"20200101E",
"qty":"10.000" }]}
(although there are many line items, only the last line item is showing)
Here's my code:
IF NOT i_vttk IS INITIAL.
SELECT tknum
tpnum
vbeln
FROM vttp
INTO TABLE i_vttp
FOR ALL ENTRIES IN i_vttk
WHERE tknum = i_vttk-tknum.
IF sy-subrc EQ 0.
SORT i_vttp BY tknum tpnum.
ENDIF.
IF NOT i_vttp is INITIAL.
LOOP AT i_vttp INTO wa_vttp.
SELECT vbeln
matnr
charg
SUM( lgmng ) as lgmng
meins
FROM lips
INTO TABLE i_lips
WHERE vbeln = wa_vttp-vbeln
AND aedat LE sy-datum
AND lfimg <> 0
GROUP BY vbeln matnr charg meins.
IF sy-subrc EQ 0.
"APPEND i_lips.
"CLEAR i_lips.
SORT i_lips BY vbeln matnr.
ENDIF.
ENDLOOP.
ENDIF.
LOOP AT i_lips INTO wa_lips.
READ TABLE i_vttp
INTO wa_vttp
WITH KEY vbeln = wa_lips-vbeln.
IF sy-subrc = 0.
wa_output-tknum = wa_vttp-tknum.
wa_output-vbeln = wa_lips-vbeln. " Added Delivery
wa_output-matnr = wa_lips-matnr.
wa_output-charg = wa_lips-charg.
wa_output-lgmng = wa_lips-lgmng.
ENDIF.
APPEND wa_output TO i_output.
CLEAR: wa_vttp, wa_lips, wa_output.
l_count = l_count + 1.
ENDLOOP.
Note that ideally, I would like to do the following query to sum up the total quantity (field lgmng), but ABAP doesn't allow to use group by with for all entries:
SELECT vbeln matnr charg SUM( lgmng ) as lgmng meins
FROM lips
INTO TABLE i_lips
FOR ALL ENTRIES IN i_vttp
WHERE vbeln = i_vttp-vbeln
AND aedat LE sy-datum
AND lfimg <> 0
GROUP BY vbeln matnr charg meins.
Any help would be appreciated. Thank you.
There are several problems with your code:
A select in a loop is generally a bad idea since it increases database accesses(which you really don't want ) . Consider other options like joins.
The reason why you get only the last line is that in every loop pass( in the loop where you do a select ) the internal table i_lips gets overwritten and hence on exiting the loop, you get only the last selected entries. To solve this you could modify your select query as follows:
SELECT vbeln
matnr
charg
SUM( lgmng ) as lgmng
meins
FROM lips
APPENDING TABLE i_lips
WHERE vbeln = wa_vttp-vbeln
AND aedat LE sy-datum
AND lfimg <> 0
GROUP BY vbeln, matnr, charg, meins.
I concatenated values of select-options and a parameter. The condition of that query is based on the concatenated data. I can get all the data i need.
here's my code:
TABLES: bkpf.
SELECT-OPTIONS: s_belnr FOR bkpf-belnr NO-EXTENSION OBLIGATORY .
PARAMETERS: p_ghjahr LIKE bkpf-gjahr DEFAULT sy-datum(4) OBLIGATORY. "Fiscal
DATA: it_con TYPE TABLE OF BKPF,
ls_con TYPE bkpf-AWKEY,
lv_belnr LIKE bkpf-belnr,
IT TYPE STANDARD TABLE OF BKPF,
WA TYPE BKPF.
IF s_belnr-high IS INITIAL.
CONCATENATE s_belnr-low p_ghjahr INTO ls_con.
APPEND ls_con TO it_con.
ELSE.
lv_belnr = s_belnr-low.
WHILE lv_belnr LE s_belnr-high.
CONCATENATE lv_belnr p_ghjahr INTO ls_con.
APPEND ls_con TO it_con.
ADD 1 TO lv_belnr.
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
EXPORTING
input = lv_belnr
IMPORTING
output = lv_belnr.
ENDWHILE.
ENDIF.
LOOP AT it_concats INTO ls_concats.
SELECT BELNR
FROM BKPF
INTO CORRESPONDING FIELDS OF TABLE IT
FOR ALL ENTRIES IN IT_CONCATS
WHERE AWKEY EQ IT_CONCATS-AWKEY.
ENDLOOP.
LOOP AT IT INTO WA.
WRITE: / WA-BELNR.
ENDLOOP.
Ignoring (because your question is too vague), the type of document you are looking for, I'll suggest something like
(WARNING, I do NOT provide full answers, just code snipets who you must tune to make it work; if someone wants to improve my answer, feel free to do it, and I'll gladly will vote the new one as the good one... if it is)
data: awkey_range type range of bkpf-awkey,
awkey_line like line of awkey_range.
* Fill the awkey_range with something like
awkey_line-sign = 'I'.
awkey_line-option = 'EQ'.
* loop at bkpf_table into bkpf_line.
* concatenate bkpf_line-belnr bkpf_line-ghjahr into awkey_line-low.
* append awkey_line to awkey_range.
* endloop.
* And then a single SQL
select *
from bkpf
into table IT "Ouch, what a name
where awkey in awkey_range.
And it should work, if I'm not missing something.
Hi ABAP users I would like to ask if what process I can make to COLLECT the data on the same field? all I want to do is to sum up or collect the data in dmbtr that belongs to same date, (date field monat) (werks to plant codes)
it_zfi_vbrp_bseg_1-num3 = it_zfi_vbrp_bseg_1-werks.
it_zfi_vbrp_bseg_1-num2 = it_zfi_vbrp_bseg_1-dmbtr.
COLLECT it_zfi_vbrp_bseg_1.
DELETE ADJACENT DUPLICATES FROM it_zfi_vbrp_bseg_1 COMPARING ALL FIELDS.
Sort it_zfi_vbrp_bseg_1 by werks.
LOOP AT it_zfi_vbrp_bseg_1 into wa_zfi_vbrp_bseg_1 WHERE monat = '01'.
IF wa_zfi_vbrp_bseg_1-werks EQ '4030'.
WRITE:/, AT pos wa_zfi_vbrp_bseg_1-dmbtr.
ENDIF.
ENDLOOP.
Any configuration in my codes guys?
Suppose, you already extended standard bseg table with monat field, then you should do like this:
TYPES: BEGIN OF ty_zfi_vbrp_bseg_1,
werks TYPE bseg-werks,
monat TYPE monat,
dmbtr TYPE bseg-dmbtr,
END OF ty_zfi_vbrp_bseg_1.
DATA: it_zfi_vbrp_bseg_1 TYPE TABLE OF ty_zfi_vbrp_bseg_1,
is_zfi_vbrp_bseg_1 TYPE ty_zfi_vbrp_bseg_1.
SELECT werks, monat, dmbtr
INTO TABLE #DATA(lt_bseg)
FROM bseg
WHERE werks = '4030'.
* summation of months
LOOP AT lt_bseg ASSIGNING FIELD-SYMBOL(<fs_line>).
CLEAR: is_zfi_vbrp_bseg_1.
MOVE-CORRESPONDING <fs_line> TO is_zfi_vbrp_bseg_1.
COLLECT is_zfi_vbrp_bseg_1 INTO it_zfi_vbrp_bseg_1.
ENDLOOP.
* output the results
LOOP AT it_zfi_vbrp_bseg_1 ASSIGNING FIELD-SYMBOL(<zfi_line>).
IF <zfi_line>-werks EQ '4030'.
WRITE: / <zfi_line>-werks, <zfi_line>-monat, <zfi_line>-dmbtr.
ENDIF.
ENDLOOP.
Couple of notes to your incorrect code:
COLLECT doesn't work like single statement and should be executed in loop.
To sum with COLLECT statement you should declare work area so that all non-key fields would be numeric. Key fields (even if it is implicit key) can be of any type, as opposed to what Ray said. N type is also OK.
DELETE ADJACENT DUPLICATES is redundant here, because after COLLECT (which makes summation by primary key) you won't have any dups.
This all comes down to how you define your internal table it_zfi_vbrp_bseg_1
For COLLECT to work, you need to define it with character type keys followed by packed field types:
data: begin of it_zfi_vbrp_bseg_1 occurs 0,
werks type werks,
month(2) type c,
dmbtr type dmbtr,
end of it_zfi_vbrp_bseg_1.
That will work.
This will not:
data: begin of it_zfi_vbrp_bseg_1 occurs 0.
include structure vbrp.
data: monat type monat,
dmbtr type dmbtr,
end of it_zfi_vbrp_bseg.
Read the help on COLLECT and define your summary table accordingly.
I have a database table named zrswheel .I entered 3 datas and want to show them on screen.Here s my code
REPORT ZRS_WHEEL.
TYPES:
BEGIN OF ty_zrswheel,
lv_brand TYPE c,
lv_dimension TYPE i,
lv_pressure TYPE i,
END OF ty_zrswheel.
DATA:
wa_zrswheel TYPE ty_zrswheel,
it_zrswheel TYPE TABLE of ty_zrswheel.
SELECT dimension pressure brand
FROM zrswheel
INTO TABLE it_zrswheel.
*WHERE ID=''.
IF sy-subrc NE 0.
write: 'There is an Error in retrieving data.'.
ELSE.
LOOP AT it_zrswheel INTO wa_zrswheel.
WRITE: wa_zrswheel-lv_dimension,wa_zrswheel-lv_brand,wa_zrswheel-lv_pressure.
NEW-LINE.
ENDLOOP.
ENDIF.
When I execute I get this error:
Runtime Errors : DBIF_RSQL_INVALID_RSQL
Except. CX_SY_OPEN_SQL_DB
What is the structure of your zrswheel?
Does it fit to your internal structure ty_zrswheel?
Without knowing the structure of zrswheel, nobody can help you.
The following is just a guess from my side.
It is very unusual to call fields in a structure like lv_.
So I think your zrswheel is defined as:
dimension type c,
brand type i
pressure type i
I think your report should look like:
REPORT ZRS_WHEEL.
DATA:
wa_zrswheel TYPE zrswheel,
it_zrswheel TYPE TABLE of zrswheel.
SELECT * FROM zrswheel INTO TABLE it_zrswheel.
LOOP AT it_zrswheel INTO wa_zrswheel.
WRITE: / wa_zrswheel-dimension,wa_zrswheel-brand,wa_zrswheel-pressure.
ENDLOOP.
IF sy-subrc NE 0.
write: 'Nothing found'.
ENDIF.
If you want only select an extract of zrswheel, then try:
REPORT ZRS_WHEEL.
TYPES:
BEGIN OF ty_zrswheel,
brand LIKE zrswheel-brand, "or lv_brand?
dimension LIKE zrswheel-dimension, "or lv_dimension?,
pressure LIKE zrswheel-pressure, "or lv_pressure?,
END OF ty_zrswheel.
DATA:
wa_zrswheel TYPE ty_zrswheel,
it_zrswheel TYPE TABLE of ty_zrswheel.
SELECT *FROM zrswheel
INTO corresponding fields of TABLE it_zrswheel.
LOOP AT it_zrswheel INTO wa_zrswheel.
WRITE: / wa_zrswheel-dimension,wa_zrswheel-brand,wa_zrswheel-pressure.
ENDLOOP.
IF sy-subrc NE 0.
write: 'There is an Error in retrieving data.'.
ENDIF.
Remark:
I'm not sure about the correct syntax of INTO CORRESPONDING FIELDS - please check the online help or wait for my update when I have a SAP-system to check the syntax)
Check your order of fields in the structure and in the select statement. Ensure the data types and length match for the fields .