Selection screen parameter with a dynamic matchcode - abap

I have a serie of entry parameters where there a match code, I need that this field (matchcode) will be dependent of a text parameter. For example, something like that :
SELECTION-SCREEN BEGIN OF BLOCK block02 WITH FRAME TITLE text-002.
PARAMETERS:
p_mona TYPE ZTIPOSOL GROUP rad1 MATCHCODE OBJECT ZFIMC002,
p_fcomp TYPE SY-DATUM MODIF ID A OBLIGATORY.
SELECTION-SCREEN END OF BLOCK block02
ABAP Development

No, you cannot. However, you can populate search help values dynamically in AT SELECTION-SCREEN ON VALUE-REQUEST event:
DATA: LT_VBAK TYPE STANDARD TABLE OF VBAK.
PARAMETER P_VBELN TYPE VBELN.
AT SELECTION-SCREEN ON VALUE-REQUEST FOR P_VBELN.
CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST'
EXPORTING
RETFIELD = 'VBELN'
DYNPPROG = SY-REPID
DYNPNR = SY-DYNNR
DYNPROFIELD = 'P_VBELN'
VALUE_ORG = 'S'
TABLES
VALUE_TAB = LT_VBAK
EXCEPTIONS
PARAMETER_ERROR = 1
NO_VALUES_FOUND = 2
OTHERS = 3.
IF SY-SUBRC <> 0.
MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
where LT_VBAK is a internal table you need to populate with values.
If your values are dependent on another selection screen parameter, use DYNP_VALUES_READ FM to read them from screen.
Another approach is not to dynamically fill values but to create a single Search Help in DDIC and create Search Help exit which will control SHELP behavior depending on some conditions.

Related

Value in dropdown box isn't refreshed

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.

Why a given block of code is not reached at all in my report program?

I am working on a project in which there are two options in the selection screen.
Block Title - Search
Flight Information
Customer ID
On choosing the first radio button, the following fields may be entered:
CARRID, CONNID, FLDATE (A, B, C)
which gives the first report, and on choosing the second radio button, the following fields may be entered:
CUSTOMER ID (D)
which should give the second report.
With the first radio button some lines are correctly output, but with the second one the program does not even go up to the line IF rad2 = 'X' and so nothing is output.
Does someone know why this block of code is not executed?
Code:
TABLES : sbook.
DATA : it_final TYPE TABLE OF sbook,
wa_final LIKE LINE OF it_final,
it_rad2final TYPE TABLE OF sbook,
wa_rad2final LIKE LINE OF it_rad2final.
PARAMETERS rad1 RADIOBUTTON GROUP rad USER-COMMAND abc DEFAULT 'X'.
SELECT-OPTIONS :
a FOR sbook-carrid MODIF ID ra,
b FOR sbook-connid MODIF ID ra,
c FOR sbook-fldate MODIF ID ra.
PARAMETERS rad2 RADIOBUTTON GROUP rad.
SELECT-OPTIONS d FOR sbook-customid MODIF ID rb.
START-OF-SELECTION.
IF rad1 = 'X'.
SELECT * FROM sbook INTO TABLE it_final
WHERE carrid IN a AND connid IN b AND fldate IN c.
ELSEIF rad2 = 'X'.
SELECT * FROM sbook INTO TABLE it_rad2final WHERE customid IN d.
ENDIF.
IF rad1 = 'X'.
LOOP AT it_final INTO wa_final.
WRITE : / wa_final-fldate , wa_final-passname ,wa_final-luggweight COLOR 6.
HIDE wa_final-customid.
ENDLOOP.
ENDIF.
AT LINE-SELECTION.
CALL FUNCTION 'ZKJ_FNMODMINI' EXPORTING custid = wa_final-customid.
IF rad2 = 'X'. " <=== NO BREAK-POINT STOP, LINE NOT REACHED !
LOOP AT it_rad2final INTO wa_rad2final.
WRITE :/ wa_rad2final-connid , wa_rad2final-fldate , wa_rad2final-bookid.
ENDLOOP.
ENDIF.
The statement AT LINE-SELECTION defines an event block for the function code PICK. Everything following this statement will be executed when this event is triggered (unless other event statements or similar follow).
What you need to do is to move the statements of the block IF rad2 = 'X' below the START-OF-SELECTION event block.

How to update Z fields with BAPI_OUTB_DELIVERY_CHANGE parameter EXTENSION2?

How to update Z fields with BAPI_OUTB_DELIVERY_CHANGE using EXTENSION2?
I tried to update some Z fields in LIKP table using the BAPI to update deliveries but after call it any changes wasn't made.
Any suggestions?
I found the BAdI - SMOD_V50B0001. I made an enhancement implementaction and in the method EXIT_SAPLV50I_010 (User Exit BAPI for Changes to Outbound Delivery) set the follow code.
METHOD if_ex_smod_v50b0001~exit_saplv50i_010.
CONSTANTS: lc_vbkok TYPE char5 VALUE 'VBKOK', "Enhance the structure for more z fields in LIKP
lc_vbpok TYPE char5 VALUE 'VBPOK', "Enhance the structure for more z fields in LIPS
lc_cs_vbkok TYPE char8 VALUE 'CS_VBKOK'.
DATA: lv_item TYPE posnr_vl.
FIELD-SYMBOLS: <lfs_fieldname> TYPE any.
LOOP AT extension2 INTO DATA(lw_extension2).
CASE lw_extension2-param.
"As a structure in row 0
WHEN lc_vbkok. "Fields for LIKP
ASSIGN (lc_cs_vbkok) TO FIELD-SYMBOL(<lfs_vbkok>).
IF <lfs_vbkok> IS ASSIGNED.
ASSIGN COMPONENT lw_extension2-field OF STRUCTURE <lfs_vbkok> TO <lfs_fieldname>.
IF <lfs_fieldname> IS ASSIGNED.
<lfs_fieldname> = lw_extension2-value.
ENDIF.
ENDIF.
"As a table from row 1 to n
WHEN lc_vbpok. "Fields for LIPS
MOVE lw_extension2-row TO lv_item.
READ TABLE ct_vbpok ASSIGNING FIELD-SYMBOL(<lfs_vbpok>) WITH KEY posnr_vl = lv_item.
IF sy-subrc = 0.
ASSIGN COMPONENT lw_extension2-field OF STRUCTURE <lfs_vbpok> TO <lfs_fieldname>.
IF <lfs_fieldname> IS ASSIGNED.
<lfs_fieldname> = lw_extension2-value.
ENDIF.
ENDIF.
ENDCASE.
ENDLOOP.
ENDMETHOD.
Enhace the structures VBKOK as well LIKP with appen structures to add new z fields and enhance the structure VBPOK as well LIPS for the same purpose.
Also take a look to the program LV50LF01 and would need to implement an additional enhancement point to keep the values.
After this a think that I got it.
METHOD m_update_delivery.
DATA: lw_header_data TYPE bapiobdlvhdrchg,
lw_header_control TYPE bapiobdlvhdrctrlchg,
lw_extension2 TYPE bapiext.
DATA: li_extension2 TYPE TABLE OF bapiext,
li_return TYPE TABLE OF bapiret2.
DATA: lv_delivery TYPE bapiobdlvhdrchg-deliv_numb.
lw_header_data-deliv_numb = p_w_output-delivery.
lw_header_control-deliv_numb = p_w_output-delivery.
lv_delivery = p_w_output-delivery.
lw_extension2-param = 'VBKOK'.
lw_extension2-field = 'ZZEXIDV'.
lw_extension2-value = p_w_output-value.
APPEND lw_extension2 TO li_extension2.
" Call BAPI to update delivery
CALL FUNCTION 'BAPI_OUTB_DELIVERY_CHANGE'
EXPORTING
header_data = lw_header_data
header_control = lw_header_control
delivery = lv_delivery
TABLES
extension2 = li_extension2
return = li_return.
READ TABLE li_return INTO DATA(lw_return)
WITH KEY type = c_e.
IF sy-subrc <> 0.
COMMIT WORK AND WAIT.
ENDIF.
ENDMETHOD.
You need to add BAPI_COMMIT after your BAPI function module.

How to use REUSE_ALV_FIELDCATALOG_MERGE function module?

I'm trying to use the function module REUSE_ALV_FIELDCATALOG_MERGE to pass the field label in ddic to display in the column header of the alv report.
But, that didn't work.
If I comment the I_STRUCTURE_NAME = 'TY_YNAH_CUS_OBJ_REQ' line, it give me runtime error state
The ABAP program lines are wider than the internal table.
But if I uncomment it ,the program still did not work
REPORT YALV_TEST.
tables sscrfields.
type-pools : slis.
"CREATE STRUCTURE -1
TYPES: BEGIN OF TY_YNAH_CUS_OBJ_REQ,
REQID TYPE YNAH_REQ_ID,
REQUESTOR TYPE YNAH_REQUESTOR,
BUSINESS_OWNER TYPE YNAH_BUS_OWN,
FUNCTIONAL_OWNER TYPE YNAH_FUNC_OWN,
REQNUM TYPE YNAH_SERVICE_REQ_NUM,
PROJECT_ID TYPE YNAH_PRO_ID,
SYSTEM_ID TYPE YNAH_SYS_ID,
FUNCTIONAL_AREA TYPE YNAH_FUNC_AREA,
REQUEST_DATE TYPE YNAH_REQ_DATE,
REQUEST_TIME TYPE YNAH_REQ_TIME,
END OF TY_YNAH_CUS_OBJ_REQ.
"defining internal table -2
DATA: IT_YNAH_CUS_OBJ_REQ type TABLE OF TY_YNAH_CUS_OBJ_REQ
* WA_YNAH_CUS_OBJ_REQ type TY_YNAH_CUS_OBJ_REQ.
DATA: it_fcat TYPE slis_t_fieldcat_alv ,
wa_fcat TYPE slis_fieldcat_alv,
gd_layout TYPE slis_layout_alv.
SELECTION-SCREEN BEGIN OF BLOCK menu WITH FRAME TITLE text-001.
SELECT-OPTIONS: s_proid FOR IT_YNAH_CUS_OBJ_REQ-PROJECT_ID.
PARAMETER p_sysid type TY_YNAH_CUS_OBJ_REQ-SYSTEM_ID.
SELECTION-SCREEN: BEGIN OF LINE,
pushbutton 33(8) BUT user-command search.
SELECTION-SCREEN END OF LINE.
SELECTION-SCREEN END OF BLOCK menu.
initialization.
BUT = 'SEARCH'. END-OF-SELECTION.
"execute search function when user click search button
at selection-screen. "after processing user input
case SSCRFIELDS.
when 'SEARCH'.
SSCRFIELDS-UCOMM = 'ONLI'.
endcase.
"fetch data using select-4 START-OF-SELECTION.
SELECT *
FROM YNAH_CUS_OBJ_REQ "Database
INTO CORRESPONDING FIELDS OF TABLE IT_YNAH_CUS_OBJ_REQ "Into internal table
WHERE
PROJECT_ID in s_proid and
SYSTEM_ID eq p_sysid.
CALL FUNCTION 'REUSE_ALV_FIELDCATALOG_MERGE'
EXPORTING
I_PROGRAM_NAME = sy-repid
I_INTERNAL_TABNAME ='TY_YNAH_CUS_OBJ_REQ'
* I_STRUCTURE_NAME = 'TY_YNAH_CUS_OBJ_REQ'
* I_CLIENT_NEVER_DISPLAY = 'X'
I_INCLNAME = sy-repid
* I_BYPASSING_BUFFER = 'X'
* I_BUFFER_ACTIVE = CHANGING CT_FIELDCAT = it_fcat.
* EXCEPTIONS
* INCONSISTENT_INTERFACE = 1
* PROGRAM_ERROR = 2
* OTHERS = 3
* .
IF SY-SUBRC <> 0.
** Implement suitable error handling here
ENDIF.
The REUSE_*ALV* function modules are unsupported. I'd suggest switching to the CL_SALV_* classes. The documentation is better, there are more sample programs (DEMO_SALV_*) and you get support.
You need a dictionary structure if you want to get dictionary-based field descriptions (duh). If you assemble a structure type on the ABAP level using TYPE ... BEGIN OF ... END OF ..., as far as I know, the dictionary types for the individual fields are converted to ABAP types first and only then assembled into a structure type. Anyway, the dictionary reference of the original fields is lost. Instead of defining the structure of the output table in your code, use a dictionary structure.
You have some mistakes you might have not known (SAP is very confusing sometimes
and not transparent with error-messages). I got for you a working example of mine, have a look on it, especially on the comments.
First, data definition:
TYPE-POOLS slis. "import you need for REUSE_ALV_FIELDCATALOG_MERGE
DATA:
lt_fieldcat TYPE slis_t_fieldcat_alv,
BEGIN OF G_IT_MATERIAL occurs 0,
MATNR LIKE MARA-MATNR,
MTART LIKE MARA-MTART,
MAKTX_DE LIKE MAKT-MAKTX,
MAKTX_FR LIKE MAKT-MAKTX,
MAKTX_IT LIKE MAKT-MAKTX,
ERNAM LIKE MARA-ERNAM,
ERSDA LIKE MARA-ERSDA,
LAEDA LIKE MARA-LAEDA,
END OF G_IT_MATERIAL.
It is absolutely necessary that you define your local structure directly with LIKE, otherwise the parser from REUSE_ALV_FIELDCATALOG_MERGE will not find it.
Select your stuff:
SELECT ma~matnr ma~mtart ma~ernam ma~ersda ma~laeda
de~maktx as maktx_de fr~maktx as maktx_fr it~maktx as maktx_it
FROM mara as ma
LEFT JOIN MAKT as de ON de~matnr = ma~matnr AND de~spras = 'DE'
LEFT JOIN MAKT as fr ON fr~matnr = ma~matnr AND fr~spras = 'FR'
LEFT JOIN MAKT as it ON it~matnr = ma~matnr AND it~spras = 'IT'
INTO CORRESPONDING FIELDS OF TABLE g_it_material
WHERE ...
Create a field catalog dynamically:
CALL FUNCTION 'REUSE_ALV_FIELDCATALOG_MERGE'
EXPORTING
I_PROGRAM_NAME = sy-repid
I_INTERNAL_TABNAME = 'G_IT_MATERIAL'
I_INCLNAME = sy-repid
CHANGING
ct_fieldcat = lt_fieldcat
EXCEPTIONS
inconsistent_interface = 1
program_error = 2
OTHERS = 3.
IF sy-subrc <> 0.
* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
* WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
ENDIF.
Now display the ALV grid:
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
it_fieldcat = lt_fieldcat "you could also give a structure
"i_structure_name = 'ZMM_SMATERIAL' "here instead of the fieldcat
TABLES
t_outtab = g_it_material
EXCEPTIONS
program_error = 1
OTHERS = 2.
Note that the parser also needs a max linesize of 72 chars.
There are several different text components provided by structure slis_fieldcat_alv that are used as column labels. The chosen text depends on the current column width (which itself usually depends on the length of the data displayed). Make sure that you change them all accordingly!
The usual technique is: By passing the I_STRUCTURE_NAME, you get a field catalog corresponding to this DDIC structure (the changing parameter ct_fieldcat). You then modify this internal table according to your needs and pass that modified table to the REUSE_ALV_GRID_DISPLAY.
In cases where I don't distinguish the different-sized text versions, I use the following macros to set all the text fields to the same value. The macros require a local work area ls_fieldcat (with the linetype of ct_fieldcat) and a local string variablelv_text` in order to work.
define set_field.
* Feld &1 für Anzeigefeld &2 den Wert &3 zuweisen
ls_fieldcat-&1 = &3.
modify ct_fieldcat from ls_fieldcat
transporting &1
where fieldname cp '&2'.
end-of-definition.
define set_text_direct.
lv_text = &2.
set_field seltext_s &1 lv_text.
lv_text = &2.
set_field seltext_m &1 lv_text.
lv_text = &2.
set_field seltext_l &1 lv_text.
end-of-definition.

What is the difference between OCCURS 0 and TYPE STANDARD TABLE

I am new to ABAP, and I am creating ALV using FM 'REUSE_ALV_FIELDCATALOG_MERGE' and 'REUSE_ALV_GRID_DISPLAY'.
It is working when I defined internal table IT_MARD using obsolete occurs 0 definition. But I am getting Exception condition "NO_FIELDCATALOG_AVAILABLE" raised, when I defined internal table using type standard table. Could you please explain difference between these two definition and why it is not working in the latter case. The following is the code.
REPORT ztest_fieldcatalog3.
TYPE-POOLS:slis.
*Semi Automatic Fieldcatalog Generation.
*DATA: BEGIN OF IT_MARD OCCURS 0,
* MATNR LIKE MARD-MATNR,
* WERKS LIKE MARD-WERKS, ""
* LGORT LIKE MARD-LGORT,
* PSTAT LIKE MARD-PSTAT,
* END OF IT_MARD.
TYPES: BEGIN OF ty_mard,
matnr type mard-matnr,
werks type mard-werks,
lgort type mard-lgort,
pstat type mard-pstat,
END OF ty_mard.
DATA: IT_MARD TYPE STANDARD TABLE OF ty_mard.
"Use function module create Fieldcat.
DATA:l_program TYPE sy-repid VALUE sy-repid.
DATA:i_fieldcat TYPE slis_t_fieldcat_alv.
SELECT matnr
werks
lgort
pstat
FROM mard
INTO CORRESPONDING FIELDS OF TABLE it_mard
UP TO 100 ROWS.
CALL FUNCTION 'REUSE_ALV_FIELDCATALOG_MERGE'
EXPORTING
i_program_name = l_program
i_internal_tabname = 'IT_MARD'
i_inclname = l_program
i_bypassing_buffer = 'X'
CHANGING
ct_fieldcat = i_fieldcat[].
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
"Call ALV and pass fieldcatalog and data
CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
i_callback_program = l_program
it_fieldcat = i_fieldcat
TABLES
t_outtab = it_mard.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
The difference is that OCCURS creates a table with a header line, while TYPE STANDARD TABLE OF does not (unless you explicitly tell it to). I suppose that the function module is able to guess the structure from a table with a header line, but not a table without a header line. My suggestions would be to
use a data dictionary structure instead of a local structure - it's easier to maintain and extend later on and
don't use the REUSE function modules, but check the CL_SALV_* classes instead since they are officially supported and have a much cleaner API