I have an internal table itab which has some rows that one component of the rows matnr is empty. I want to check the palet column of the internal table and get matnr according to palet from the zlldet table, and then change the matnr column of internal table to new matnr value. Here is a summary;
itab table:
+-------+-------+-----------+
| palet | matnr | something |
+-------+-------+-----------+
| 1234 | null | abc |
| 1235 | null | saa |
| 1236 | null | ssd |
+-------+-------+-----------+
So, I will check the palet column from the zlldet table and find the matnr value of that row. The new itab values should be:
+-------+--------+-----------+
| palet | matnr | something |
+-------+--------+-----------+
| 1234 | 543213 | abc |
| 1235 | 988876 | saa |
| 1236 | 344545 | ssd |
+-------+--------+-----------+
What I've tried:
LOOP AT itab.
SELECT SINGLE matnr INTO itab-matnr
FROM zlldet WHERE palet = itab-palet.
ENDIF.
ENDLOOP.
I am trying to change the value in the second line. I know it is wrong, I should use some MODIFY statement but I'm not sure how.
Edit:
Here is the complete code:
REPORT zwps0510 MESSAGE-ID zc LINE-SIZE 255 NO STANDARD PAGE HEADING.
TABLES: zzllog, zzldet, marc, makt.
DATA: BEGIN OF itab OCCURS 0.
INCLUDE STRUCTURE zzllog.
DATA: END OF itab.
DATA: adet TYPE p.
*/ paket numaraları
SELECT-OPTIONS: spalet FOR zzllog-palet. "/paket no
SELECT-OPTIONS: spaleta FOR zzllog-paleta. "/paketnoa
SELECT-OPTIONS: spaletb FOR zzllog-paletb. "/paketnob
SELECTION-SCREEN SKIP 1.
*/ paketle ilgili bilgiler
SELECT-OPTIONS: sdispo FOR marc-dispo.
SELECT-OPTIONS: smatnr FOR zzllog-matnr.
SELECT-OPTIONS: sharkod FOR zzllog-harkod. "/logtaki işlem kodu
*SELECT-OPTIONS: stelf1 FOR zzllog-telf1.
SELECT-OPTIONS: starih FOR zzllog-tarih.
SELECT-OPTIONS: susr FOR zzllog-usr.
SELECT-OPTIONS: saufnr FOR zzllog-aufnr.
SELECTION-SCREEN SKIP 1.
*/ depo adres bilgileri
SELECT-OPTIONS: sflgnum FOR zzllog-flgnum. "/kaynak depo no
SELECT-OPTIONS: sflgtyp FOR zzllog-flgtyp. "/kaynak depo tipi
SELECT-OPTIONS: sflgpla FOR zzllog-flgpla. "/kaynak depo numarası
SELECT-OPTIONS: stlgnum FOR zzllog-tlgnum. "/hedef depo no
SELECT-OPTIONS: stlgtyp FOR zzllog-tlgtyp. "/hedef depo tipi
SELECT-OPTIONS: stlgpla FOR zzllog-tlgpla. "/hedef depo numarası
SELECTION-SCREEN SKIP 1.
*/ Çıktıda gelecek kolonların seçimi
SELECTION-SCREEN BEGIN OF BLOCK uc WITH FRAME TITLE text-001.
PARAMETERS : tarih AS CHECKBOX DEFAULT 'X',
saat AS CHECKBOX DEFAULT 'X',
usr AS CHECKBOX DEFAULT 'X',
palet AS CHECKBOX DEFAULT 'X',
paleta AS CHECKBOX DEFAULT 'X',
paletb AS CHECKBOX DEFAULT 'X',
harkod AS CHECKBOX DEFAULT 'X', "/ hareket kodu
matnr AS CHECKBOX DEFAULT 'X',
menge AS CHECKBOX DEFAULT 'X',
sebep AS CHECKBOX DEFAULT 'X', "/ sipariş/red
aufnr AS CHECKBOX DEFAULT 'X', "/sm.siparişi
ref2 AS CHECKBOX DEFAULT 'X',
paufnr AS CHECKBOX DEFAULT 'X', "/enj.siparişi
flgnum AS CHECKBOX DEFAULT 'X', "/from depo...
flgtyp AS CHECKBOX DEFAULT 'X',
flgpla AS CHECKBOX DEFAULT 'X',
tlgnum AS CHECKBOX DEFAULT 'X', "/ to depo...
tlgtyp AS CHECKBOX DEFAULT 'X',
tlgpla AS CHECKBOX DEFAULT 'X'.
SELECTION-SCREEN END OF BLOCK uc.
*
TOP-OF-PAGE.
PERFORM baslik.
*
START-OF-SELECTION.
PERFORM prepare_itab.
PERFORM write_itab.
**
FORM prepare_itab.
*/ Paketle ilgili tüm geçmiş hareketler log tablosundan okunur
SELECT * INTO CORRESPONDING FIELDS OF TABLE itab
FROM zzllog WHERE palet IN spalet
AND paleta IN spaleta
AND paletb IN spaletb
AND matnr IN smatnr
AND harkod IN sharkod
AND tarih IN starih
AND flgnum IN sflgnum
AND flgtyp IN sflgtyp
AND flgpla IN sflgpla
AND tlgnum IN stlgnum
AND tlgtyp IN stlgtyp
AND tlgpla IN stlgpla
AND aufnr IN saufnr
AND usr IN susr.
IF sdispo[] IS NOT INITIAL.
LOOP AT itab.
SELECT SINGLE dispo INTO marc-dispo
FROM marc WHERE matnr = itab-matnr
AND werks = '3001'
AND dispo IN sdispo.
IF sy-subrc <> 0.
DELETE itab.
ENDIF.
ENDLOOP.
ENDIF.
DESCRIBE TABLE itab LINES adet.
*/ tüm hareketler tarih ve saate göre sıralanır
SORT itab BY tarih saat.
WRITE:/ 'ADET: ', adet.
ULINE.
ENDFORM.
So, what I want to do is exactly: if sharkod includes D, zzldet should be checked for the matnr.
Instead of using MODIFY, use a field symbol:
DATA: lt_materials TYPE TABLE OF zzllog.
FIELD-SYMBOLS: <ls_line> TYPE zzllog.
* other code with strange comments :-)
LOOP AT lt_materials ASSIGNING <ls_line> WHERE matnr IS INITIAL.
SELECT SINGLE MATNR
FROM zlldet
INTO <ls_line>-matnr
WHERE palet = <ls_line>-palet.
ENDLOOP.
This is just an example for the correct syntax. It's not a good idea to do this in a real program because there's a fair chance thtat you'll be hitting the database with thousands of requests, and potentially draw quite a bit of performance. It'd be better to preselect the PALET numbers that have no MATNR into a separate table and then use FOR ALL ENTRIES IN to read all the MATNRs in a single query.
EDIT: Added type names. BTW, your way of declaring the internal table is somewhat outdated...
When you want to do it with modify and not with a field symbol, that would be the correct solution:
LOOP AT itab.
SELECT SINGLE matnr INTO itab-matnr
FROM zlldet WHERE palet = itab-palet.
MODIFY itab.
ENDLOOP.
You declared itab as a table with header line (which is deprecated, by the way). That means you have a table itab and a structure itab. Which one is used in which situation depends on context, and some commands, like LOOP AT and MODIFY, use both at the same time. This would be the code with a work area instead of a header line. It's more readable.
DATA itab TYPE TABLE OF [something].
DATA wa TYPE [something].
LOOP AT itab INTO wa. " copies each line into wa
SELECT SINGLE matnr INTO wa-matnr
FROM zlldet WHERE palet = itab-palet.
MODIFY itab FROM wa. " writes the changed line back to the table
ENDLOOP.
You can also use the solution with a field symbol vwegert described. A field symbol is a pointer to the line of the table. Any changes to the field symbol will be automatically written back to the table, so you don't need MODIFY in this case. It is also faster, especially with very wide tables, because no data needs to be copied.
You can also avoid the select statement every time inside the loop. Instead, you can try making use of Range tables and make use of select statement only once before the loop since it increases performance.
Define user defined structure and declare variables
types: begin of ty_p_m,
palet type zlldet-palet,
matnr type zlldet-matnr,
end of ty_p_m.
data: r_palet type range table of zlldet-palet,
r_line_palet like line of r_palet,
i_p_matnr type standard table of ty_p_m,
wa_p_m type ty_p_m.
field-symbols: <fs> type wa_p_m.
Fill the range table which is to be used in the select query in the next step.
r_line_palet-sign = 'I'.
r_line_palet-option = 'EQ'.
loop at itab into wa.
r_line_palet-low = wa-palet.
append r_line_palet to r_palet.
endloop.
now use the select statement by referring the range table and get the data inside the declared internal table.
select palet matnr from zlldet into i_p_matnr
where palet in r_palet.
Now loop on declared internal table. Inside that read your internal table
with incoming values and modify the table there itself using field symbols instead of modify statement.
loop at i_p_matnr into wa_p_matnr.
read table itab with key palet = wa_p_matnr-palet assigning <fs>.
if sy-subrc = 0.
<fs>-matnr = wa_p_matnr-matnr.
endif.
clear wa_p_matnr.
endloop.
Related
I have a dynpro screen with two input fields:
The sales order n°
The sales order line n° (in a dropdown list)
My problem is that the sales order line isn't refreshed after a different sales order n° is input. However the other output fields relating to the sales order line are properly refreshed with the expected data.
Program behavior:
"Document vente" is "Sales order". "Poste" is "Line number".
From this screen, If I request sales order number 1, the order line 10 remains active and shows up in the dropdown list, despite order number 1 not having a line number 10. The other output fields are updated with the data of line 20. If I pick line orders 20, 30 or 70, the value 10 disappears from the list.
The dynpro screen fields are named as their corresponding fields from the VBAK and VBAP tables, so that their values are copied automatically from one to another.
The code followed by the comment "Set order line to first one in the order" doesn't seem to work. I expect it to replace the value of the line number field with the first line number in the new order.
The code:
MODULE REFRESH_ALL_FIELDS INPUT.
DATA temp_vbeln TYPE VBAK-VBELN.
temp_vbeln = VBAK-VBELN.
CLEAR: VBAK, VBAP.
SELECT VBELN KUNNR BSTNK NETWR WAERK
FROM VBAK
INTO CORRESPONDING FIELDS OF VBAK
WHERE VBAK~VBELN = temp_vbeln.
ENDSELECT.
" Fill dropdown list with order line numbers.
TYPE-POOLS VRM.
DATA it_posnr TYPE VRM_VALUES.
REFRESH it_posnr.
SELECT POSNR
FROM VBAP
INTO TABLE it_posnr
WHERE VBAP~VBELN = VBAK-VBELN.
CALL FUNCTION 'VRM_SET_VALUES'
EXPORTING
ID = 'VBAP-POSNR'
VALUES = it_posnr
* EXCEPTIONS
* ID_ILLEGAL_NAME = 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.
" Set order line number as first in the order.
SELECT SINGLE POSNR
FROM VBAP
INTO VBAP-POSNR
WHERE VBAP~VBELN = VBAK-VBELN.
PERFORM REFRESH_ITEM_FIELDS.
ENDMODULE. " REFRESH_ALL_FIELDS INPUT
MODULE REFRESH_ITEM_FIELDS INPUT.
PERFORM REFRESH_ITEM_FIELDS.
ENDMODULE. " REFRESH_ITEM_FIELDS INPUT
FORM REFRESH_ITEM_FIELDS .
SELECT SINGLE MATNR ARKTX KWMENG
FROM VBAP
INTO CORRESPONDING FIELDS OF VBAP
WHERE VBAP~VBELN = VBAK-VBELN
AND VBAP~POSNR = VBAP-POSNR.
ENDFORM. " REFRESH_ITEM_FIELDS
Flow logic:
PROCESS BEFORE OUTPUT.
PROCESS AFTER INPUT.
FIELD VBAK-VBELN MODULE REFRESH_ALL_FIELDS ON REQUEST.
FIELD VBAP-POSNR MODULE REFRESH_ITEM_FIELDS ON REQUEST.
How can I fix this ?
The dynpro flow logic statement FIELD vbak-vbeln MODULE ... ON REQUEST permits only to change "easily" the value of the screen field VBAK-VBELN, i.e. the value of the global variable VBAK-VBELN will be "transported" in both directions, from the screen to the ABAP program, and vice versa.
If you want to change another screen field, like VBAP-POSNR, you must call the function module DYNP_VALUES_UPDATE:
TYPES tt_dynpread TYPE STANDARD TABLE OF dynpread WITH DEFAULT KEY.
DATA(dynpfields) = VALUE ty_dynpread_s(
( fieldname = 'VBAP-POSNR'
fieldvalue = vbap-posnr ) ).
CALL FUNCTION 'DYNP_VALUES_UPDATE'
EXPORTING
dyname = sy-repid
dynumb = sy-dynnr
TABLES
dynpfields = dynpfields
EXCEPTIONS
OTHERS = 8.
Another solution is to declare a "chain" of fields, you may then change those fields directly inside the module without calling DYNP_VALUES_UPDATE:
CHAIN.
FIELD: vbak-vbeln, vbap-posnr.
MODULE ... ON REQUEST.
ENDCHAIN.
But that would require to execute the same code for both fields.
Here is the way how you can do it without creating a dynpro, just with pure selection screen:
TYPES: BEGIN OF ty_order,
vbeln TYPE vbak-vbeln,
erdat TYPE vbak-erdat,
netwr TYPE vbak-netwr,
kunnr TYPE vbak-kunnr,
END OF ty_order,
BEGIN OF ty_pos,
vbeln TYPE vbap-vbeln,
posnr TYPE vbap-posnr,
matnr TYPE vbap-matnr,
arktx TYPE vbap-arktx,
kwmeng TYPE vbap-kwmeng,
END OF ty_pos.
DATA: i_order TYPE TABLE OF ty_order WITH EMPTY KEY,
i_pos TYPE TABLE OF ty_pos WITH EMPTY KEY,
i_aux TYPE TABLE OF ty_pos WITH EMPTY KEY,
list TYPE vrm_values.
PARAMETERS: order TYPE vbak-vbeln AS LISTBOX VISIBLE LENGTH 80 USER-COMMAND ord,
position TYPE vbap-posnr AS LISTBOX VISIBLE LENGTH 80 USER-COMMAND art.
INITIALIZATION.
SELECT vbeln erdat netwr kunnr
FROM vbak AS ak
INTO TABLE i_order
WHERE vbeln = ANY ( SELECT vbeln FROM vbap WHERE vbeln = ak~vbeln GROUP BY vbeln HAVING COUNT( * ) > 1 ).
IF i_order IS NOT INITIAL.
SELECT vbeln posnr matnr arktx kwmeng
FROM vbap
INTO TABLE i_pos
FOR ALL ENTRIES IN i_order
WHERE vbeln = i_order-vbeln.
ENDIF.
LOOP AT i_order INTO DATA(wa).
APPEND VALUE vrm_value( key = |{ wa-vbeln ALPHA = OUT }| text = |{ wa-erdat DATE = USER }| ) TO list.
ENDLOOP.
CALL FUNCTION 'VRM_SET_VALUES'
EXPORTING
id = 'order'
values = list.
CLEAR list.
AT SELECTION-SCREEN.
CHECK sy-ucomm = 'ORD'.
CLEAR position.
CALL FUNCTION 'VRM_SET_VALUES'
EXPORTING
id = 'position'
values = list.
CLEAR list.
AT SELECTION-SCREEN ON order.
CHECK sy-ucomm = 'ORD' AND order IS NOT INITIAL.
i_aux = VALUE #( FOR pos IN i_pos WHERE ( vbeln = |{ order ALPHA = IN }| ) ( pos ) ).
LOOP AT i_aux INTO DATA(aux).
APPEND VALUE vrm_value( key = |{ aux-posnr ALPHA = OUT }| text = |{ aux-matnr ALPHA = OUT }| ) TO list.
ENDLOOP.
CALL FUNCTION 'VRM_SET_VALUES'
EXPORTING
id = 'position'
values = list.
After each selection in order dropdown all the order-related data will be collected to i_aux table which you can use for populating output fields.
The closest solution was to update a working area in the PAI, and update the actual screen fields in the PBO, from the values of the WA.
I'm trying to display table in alv from an internal table where rows are added form a table stored in the database. Without a where condition I see rows displayed in alv but with a where condition in the select statement no rows are returned.
Here is the code:
REPORT ZSAM.
DATA: IT_1 TYPE STANDARD TABLE OF VBAK.
select vbeln audat netwr waerk vkorg vtweg
from VBAK
into corresponding fields of Table IT_1
where vbeln > 4500
and vbeln < 6000.
Any idea why using where condition makes it not return any rows and how to fix?
vbeln is a field with ten positions and uses ALPHA conversion routine (see the domain behind the data element). This means the value is filled with leading zeros (as long as it does contain numbers only). As this is a character type field, you also have to use apostrophes for the comparison. So, the WHERE condition has to be like this:
WHERE vbeln GT '0000004500'
AND vbeln LT '0000006000'
You can try to use range;
First usage;
DATA: r_vbeln TYPE RANGE OF vbeln.
DATA: s_vbeln LIKE LINE OF r_vbeln.
s_vbeln-option = 'BT'.
s_vbeln-sign = 'I'.
s_vbeln-low = '0000004501'.
s_vbeln-high = '0000005999'.
APPEND s_vbeln TO r_vbeln.
SELECT condition; WHERE vbeln IN r_vbeln.
Second usage;
DATA: r_vbeln TYPE RANGE OF vbeln.
DATA: s_vbeln LIKE LINE OF r_vbeln.
s_vbeln-option = 'GT'.
s_vbeln-sign = 'I'.
s_vbeln-low = '0000004500'.
APPEND s_vbeln TO r_vbeln.
s_vbeln-option = 'LT'.
s_vbeln-sign = 'I'.
s_vbeln-low = '0000006000'.
APPEND s_vbeln TO r_vbeln.
SELECT condition; WHERE vbeln IN r_vbeln.
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.
I have a selection screen with select-options where I want to enter several information about materials, for example: material number etc.
The user is also able to enter a language which the output should be in.
If the user chooses english the program shall display an internal table with material number, language, material name in english. If the user enters spanish, I want the output to be in spanish.
What do I have to do in order to define a dynamic structure / table which shows the respective columns dependent on the chosen language?
Thanks for your help
It's highly-dependent on the data structure you are going to show to user, but usually you don't need dynamic structure for this, but rather need to populate data dynamically, i.e. depending on current user language.
For example, material texts are stored in MAKT text table, where texts are stored along with language keys by which they are usually retrieved:
SELECT
a~matnr
a~werks
b~maktx FROM ekpo AS a
INNER JOIN makt AS b
ON b~matnr = a~matnr
AND b~spras = sy-langu
INTO CORRESPONDING FIELDS OF TABLE int_out
WHERE
a~matnr IN s_matnr and
a~werks IN s_werks.
Other descriptions in SAP are usually stored in text tables as well.
More about sy-langu and other system fields is here.
UPDATE: If you really want a dynamic structure with all the languages, see this sample:
DATA: lang TYPE SPRAS.
* language selection
SELECT-OPTIONS: s_lang FOR lang.
SELECT a~matnr, a~werks, b~maktx, b~spras UP TO 5000 ROWS
FROM ekpo AS a
JOIN makt AS b
ON b~matnr = a~matnr
INTO TABLE #DATA(int_out)
WHERE a~werks LIKE '3%'
AND a~matnr LIKE '1%'
AND b~spras IN #s_lang.
*finding unique languages
DATA lt_langs TYPE TABLE OF spras.
lt_langs = VALUE #( ( '' ) ).
LOOP AT int_out ASSIGNING FIELD-SYMBOL(<fs_out>)
GROUP BY ( lang = to_upper( val = <fs_out>-spras ) ) ASCENDING
WITHOUT MEMBERS
ASSIGNING FIELD-SYMBOL(<ls_lang>).
APPEND <ls_lang>-lang TO lt_langs.
ENDLOOP.
DATA :
ls_component TYPE cl_abap_structdescr=>component,
gt_components TYPE cl_abap_structdescr=>component_table.
*adding MATNR column
ls_component-name = 'MATNR'.
ls_component-type ?= cl_abap_datadescr=>describe_by_name( 'matnr' ).
APPEND ls_component TO gt_components.
*Creating dynamic structure with column for every lang
LOOP AT lt_langs ASSIGNING FIELD-SYMBOL(<fs_lang>).
CONDENSE <fs_lang>.
IF <fs_lang> IS NOT INITIAL.
ls_component-name = 'makt_' && <fs_lang>.
ls_component-type ?= cl_abap_datadescr=>describe_by_name( 'maktx' ).
APPEND ls_component TO gt_components.
ENDIF.
ENDLOOP.
* constructing dynamic structure
DATA: gr_struct_typ TYPE REF TO cl_abap_datadescr.
gr_struct_typ ?= cl_abap_structdescr=>create( p_components = gt_components ).
* constructing table from structure
DATA: gr_dyntable_typ TYPE REF TO cl_abap_tabledescr.
gr_dyntable_typ = cl_abap_tabledescr=>create( p_line_type = gr_struct_typ ).
DATA: gt_dyn_table TYPE REF TO data,
gw_dyn_line TYPE REF TO data.
FIELD-SYMBOLS: <gfs_line>,<gfs_line1>,<fs1>,
<gfs_dyn_table> TYPE STANDARD TABLE.
CREATE DATA: gt_dyn_table TYPE HANDLE gr_dyntable_typ,
gt_dyn_table TYPE HANDLE gr_dyntable_typ,
gw_dyn_line TYPE HANDLE gr_struct_typ.
ASSIGN gt_dyn_table->* TO <gfs_dyn_table>.
ASSIGN gw_dyn_line->* TO <gfs_line>.
LOOP AT int_out ASSIGNING <fs_out>.
* checking for duplicated
READ TABLE <gfs_dyn_table> ASSIGNING <gfs_line1> WITH KEY ('MATNR') = <fs_out>-matnr.
IF sy-subrc = 0.
CONTINUE.
ENDIF.
* assigning material number
LOOP AT gt_components ASSIGNING FIELD-SYMBOL(<fs_component>).
IF <fs_component>-name = 'MATNR'.
ASSIGN COMPONENT <fs_component>-name OF STRUCTURE <gfs_line> TO <fs1>.
IF <fs1> IS ASSIGNED.
<fs1> = <fs_out>-matnr.
UNASSIGN <fs1>.
ENDIF.
ENDIF.
* assigning languge-dependent names
READ TABLE int_out WITH KEY matnr = <fs_out>-matnr
spras = <fs_component>-name+5
ASSIGNING FIELD-SYMBOL(<fs_spras>).
IF sy-subrc = 0.
ASSIGN COMPONENT <fs_component>-name OF STRUCTURE <gfs_line> TO <fs1>.
IF <fs1> IS ASSIGNED.
<fs1> = <fs_spras>-maktx.
UNASSIGN <fs1>.
ENDIF.
ENDIF.
ENDLOOP.
APPEND <gfs_line> TO <gfs_dyn_table>.
CLEAR: <gfs_line>.
ENDLOOP.
DATA: l_lang TYPE spras VALUE 'E'.
* showing values in proper language depending on user input
LOOP AT <gfs_dyn_table> ASSIGNING <gfs_line>.
ASSIGN COMPONENT 'makt_' && l_lang OF STRUCTURE <gfs_line> TO <fs1>.
IF <fs1> IS ASSIGNED.
WRITE / <fs1>.
UNASSIGN <fs1>.
ENDIF.
ENDLOOP.
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.