3

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". enter image description here

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.

enter image description here

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 ?

Sandra Rossi
  • 11,934
  • 5
  • 22
  • 48
Cutter
  • 1,673
  • 7
  • 27
  • 43

3 Answers3

3

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.

Sandra Rossi
  • 11,934
  • 5
  • 22
  • 48
2

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.

Suncatcher
  • 10,355
  • 10
  • 52
  • 90
-1

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.

Cutter
  • 1,673
  • 7
  • 27
  • 43