[abap] smartforms句柄与以簇的方式存储数据

本文介绍了一种利用ABAP编程语言实现智能报表(Smartforms)输出的方法,详细讲解了如何设置句柄来传递复杂的参数数据,并通过具体示例展示了整个过程。

说明:Smartforms输出打印,设置句柄,用于传递参数。

REPORT  ZIEB_WWFLD.

*-----------------      TABLES      ----------------------------*


*-----------------     VARIANTS     ----------------------------*
DATA l_sno TYPE ZIEB_ZSNNM.
DATA: ls_ctr  TYPE ssfctrlop,
      ls_cre  TYPE ssfcrescl,
      ls_opt TYPE ssfcompop.
  DATA : wa_indx TYPE indx .  " 作为全局声明
* 以下是一个定义宏的语句,在DEFINE和END-OF-DEFINITION之间有完整的ABAP语句,
* 用&N作为占位符,在调用的时候把真正的字符传入并取代。
** 例子:
*DATA: RESULT TYPE I,
*N1 TYPE I VALUE 5,
*N2 TYPE I VALUE 6.
*DEFINE OPERATION.
*RESULT = &1 &2 &3.
*OUTPUT &1 &2 &3 RESULT.
*END-OF-DEFINITION.
*OPERATION 4 + 3.
*OPERATION 2 ** 7.
*OPERATION N2 - N1.

DEFINE savebuffer.
  perform save_to_buffer using &1 &2.
END-OF-DEFINITION.

DEFINE clearbuffer.
  perform clear_buffer using &1.
END-OF-DEFINITION.
*-----------------    CONSTANTS     ----------------------------*


*-----------------  INTERNAL  TABLES ----------------------------*
DATA:  item_LFA1 LIKE LFA1 OCCURS 0 WITH HEADER LINE,
       item_T156T LIKE T156T OCCURS 0 WITH HEADER LINE,
       item_MAKT LIKE MAKT OCCURS 0  WITH HEADER LINE.

*结果内表item_out
TYPES: BEGIN OF TY_item_out,
           SNO   TYPE ZIEB_zsnnm,         " 序号      说明: 数据元素不能用LIKE
           WERKS LIKE MSEG-WERKS,         " 工厂
           TName1 LIKE T001W-NAME1,       " 工厂名称
           Ebeln LIKE EKPO-EBELN,         " 采购订单号
           LIFNR LIKE MSEG-LIFNR,         " 委外加工商代码
           LNAME1 LIKE LFA1-NAME1,        " 委外加工商名称
           BLDAT LIKE MKPF-BLDAT,         " 凭证日期
           MBLNR LIKE MSEG-MBLNR,         " 物料凭证号
           BWART LIKE MSEG-BWART,         " 移动类型
           BTEXT LIKE T156T-BTEXT,        " 移动类型描述
           ZEILE LIKE MSEG-ZEILE,         " 序号
           MATNR LIKE MSEG-MATNR,         " 物料编号
           MAKTX LIKE MAKT-MAKTX,         " 物料描述
           ERFMG LIKE MSEG-ERFMG,         " 数量
           ERFME LIKE MSEG-ERFME,         " 单位
           LGORT LIKE MSEG-LGORT,         " 库存地代码
           LGOBE LIKE T001L-LGOBE,        " 库存地描述
           CHARG LIKE MSEG-CHARG,         " 批次
           SGTXT LIKE MSEG-SGTXT,         " 备注
      END OF TY_item_out.
DATA : item_out TYPE TABLE OF TY_item_out WITH HEADER LINE.
Data hd_item_out TYPE TY_item_out.      " 用来存放抬头的固定内容。
Data wa_item_out TYPE TY_item_out.      " 用来存放行项目的可循环内容。
*-----------------   SELECTION-SCREEN --------------------------*
SELECTION-SCREEN BEGIN OF BLOCK block1 WITH FRAME TITLE text-001.
PARAMETERS: p_werks LIKE mseg-werks OBLIGATORY DEFAULT '2100', " 工厂
            p_MJAHR LIKE mseg-MJAHR OBLIGATORY DEFAULT sy-datum," 当前年度
            p_MBLNR LIKE MSEG-MBLNR OBLIGATORY DEFAULT '4900001625'.  " 物料凭证
SELECTION-SCREEN  SKIP 1.
SELECTION-SCREEN END OF BLOCK block1.

*-----------------   START-OF-SELECTION --------------------------*
" MSEG - a, T001W - b,EKPO-c,LFA1-d,MKPF-e,T156T-f,MAKT-g,T001L-h
if p_werks <> '2100'.
  "  MESSAGE S004 with '工厂选择错误!'.  " MESSAGE-ID ZIEB01
  MESSAGE  '工厂选择错误!' TYPE 'E'.
  STOP.
endif.
if p_MJAHR <> sy-datum(04).
  MESSAGE '凭证年度选择错误!' TYPE 'E'.
  STOP.
ENDIF.

START-OF-SELECTION.
* b~NAME1 as TName1     d~NAME1 as LNAME1      f~BTEXT     g~MAKTX     h~LGOBE
  SELECT a~werks   c~EBELN  a~LIFNR
         e~BLDAT a~MBLNR a~BWART  a~ZEILE a~MATNR
         a~ERFMG a~ERFME a~LGORT  a~CHARG a~SGTXT APPENDING CORRESPONDING
         FIELDS OF TABLE item_out from MSEG as a
         left join EKPO as c  on a~MATNR = c~MATNR
         left join MKPF as e  on a~MBLNR = e~MBLNR
         WHERE a~WERKS = p_werks and a~MJAHR = p_MJAHR and a~MBLNR = p_MBLNR and a~BWART in ('541','542')
         .
  if sy-subrc <> 0 .
    MESSAGE '没有委外发料凭证的行项目!' TYPE 'I'.
    STOP.
  endif.
  CLEAR item_out.
  LOOP AT  item_out.
    SELECT SINGLE NAME1 INTO item_out-TName1
      FROM T001W  WHERE werks EQ item_out-werks
                    AND SPRAS = SY-LANGU.

    SELECT SINGLE NAME1 INTO item_out-LNAME1
      FROM LFA1  WHERE LIFNR EQ item_out-LIFNR
                   AND SPRAS = SY-LANGU.
    SELECT SINGLE BTEXT  INTO item_out-BTEXT
      FROM T156T  WHERE BWART  EQ item_out-BWART
                    AND SPRAS = SY-LANGU.
    SELECT SINGLE MAKTX  INTO item_out-MAKTX
      FROM MAKT   WHERE MATNR  EQ item_out-MATNR
                    AND SPRAS = SY-LANGU.
    SELECT SINGLE LGOBE  INTO item_out-LGOBE
      FROM T001L  WHERE LGORT EQ item_out-LGORT.
    l_sno = l_sno + 1.
    item_out-SNO = l_sno.
    MODIFY item_out.

  ENDLOOP.
  read TABLE item_out INDEX 1 INTO hd_item_out.
  PERFORM Display_BySF.
*&---------------------------------------------------------------------*
*&      Form  Display_BySF
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
Form Display_BySF.
* 取得smartforms中的参数
  DATA : fm_name TYPE rs38l_fnam.

*NOTE:SmartForms中的内表不能有HeaderLine

*通过SmartForms的名称取得编译以后的对应的Function Module的名称
  CALL FUNCTION 'SSF_FUNCTION_MODULE_NAME'
    EXPORTING
      formname                 = 'ZFIEB_WWFLD'
*     VARIANT                  = ' '
*     DIRECT_CALL              = ' '
   IMPORTING
     fm_name                  = fm_name
   EXCEPTIONS
     no_form                  = 1
     no_function_module       = 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.

* 句柄的声明
  DATA : prt_handler1(22) .
  DATA : prt_handler2(22) .
  DATA : wa_indx TYPE indx .
*smartforms中的内存地址给句柄
*在句柄中加上服务器当前时间作为句柄名称,防止多人同时使用该程序,导致句柄名称相同
  CONCATENATE 'ZFMM_HDR' sy-uzeit INTO prt_handler1 .
  CONCATENATE 'ZFMM_ITEM' sy-uzeit INTO prt_handler2 .

* 将内表数据传输到数据簇表里
*  wa_indx-aedat = sy-datum .
*  wa_indx-usera = sy-uname .
*  wa_indx-pgmid = sy-repid .

*在SAP中可以将一个对象Export到内存或者数据库中,我们就可以根据一个类似于句柄的字符串再次取出该数据,
*传送一个字符串到SmartForms中是没有任何问题的,所以我们只需要Export内表到内存或者数据库中,
*然后将句柄传递到SmartForms中,在SmartForms中首先定义完全相同类型的内表,
*再将数据Impor到内表中即可完全恢复数据,这样就完成的数据的传递工作。
* Report中用EXPORT:

  EXPORT hd_item_out TO DATABASE indx(hk) ID prt_handler1 FROM wa_indx .
*  EXPORT item_out TO DATABASE indx(hk) ID prt_handler2 FROM wa_indx .
*Smartforms中用IMPORT:
*IMPORT HD_ITEM_OUT FROM DATABASE indx(hk) id PRT_HANDLER1.
*IMPORT ITEM_OUT FROM DATABASE indx(hk) id PRT_HANDLER2.
   savebuffer item_out[] prt_handler2.
  DATA : output_opt TYPE ssfcompop.   " ssfcompop :打印参数设置的“结构”

  output_opt-rqposname ='Local'.
  output_opt-tdimmed = 'X'.

  CALL FUNCTION fm_name
    EXPORTING
      prt_handler1       = prt_handler1    " 要跟Smartfroms中的全局变量对应好
      prt_handler2       = prt_handler2
      output_options     = output_opt
      control_parameters = ls_ctr
      user_settings      = 'X'
    IMPORTING
      job_output_info    = ls_cre
    EXCEPTIONS
      formatting_error   = 1
      internal_error     = 2
      send_error         = 3
      user_canceled      = 4.

  IF sy-subrc <> 0.
    MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
            WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  ENDIF.

*  DELETE FROM DATABASE indx(hk) ID prt_handler1.
*  DELETE FROM DATABASE indx(hk) ID prt_handler2.
    clearbuffer prt_handler1.
    clearbuffer prt_handler2.
ENDFORM.                    "Display_BySF
*&可以用数据簇方式对程序的任何复杂内部数据对像过行分组保存,
*&并将其临时存储在程序内存中,或长时间存储在数据库中,
*&使用export to memory 语句在内存中存储数据对像
*&格式: Export <f1>[from<g1>]<f2>[from<g2>]…..to memory ID <key>.
*&
*&使用import from memory 语句从内存中读取数据对像
*&格式:  IMPORT <F1> [TO <g1>] <F2> [TO <g2>] ... FROM MEMORY ID <key>.
*&
*&使用 free memory 语句从内存中删除数据簇;
*&Free memory [id<key>].
*& 说明:如果不附加ID<key>,则此语句删除整个内存,包括此前用exoprt存储到内存中的所有数据簇 附加ID<key>之后,该语句只能删除此名称命名的数据簇;
*&
FORM save_to_buffer USING t TYPE table typeid TYPE c .
    wa_indx-aedat = sy-datum.
    wa_indx-usera = sy-uname.
    wa_indx-pgmid = sy-repid.
*以簇方式存储数据对像
*数据对像从程序写入到内存
  EXPORT t TO DATABASE indx(hk) ID typeid from wa_indx.
ENDFORM.
FORM  clear_buffer using buffid TYPE c.
   DELETE FROM DATABASE indx(hk) ID buffid.
ENDFORM.

 

REPORT zppr105. TABLES:afpo,aufk,afko,ztwm008,zppt085,makt,zppt086,tj02t. *定义全局变量 TYPE-POOLS: slis. DATA:gt_fcat TYPE lvc_t_fcat. DATA:gs_lout TYPE lvc_s_layo. DATA:t_status TYPE TABLE OF jstat WITH HEADER LINE. TYPES:BEGIN OF ty_alv, matnr TYPE afpo-matnr, "物料编码 objnr TYPE aufk-objnr, "对象号 zdjcs TYPE zppt085-zdjcs, "登记次数 plnbez TYPE afko-plnbez, "订单物料编码 plnbez1 TYPE afko-plnbez, "订单物料编码 maktx TYPE makt-maktx, "订单物料描述 werks TYPE aufk-werks, "工厂 auart TYPE aufk-auart, "生产订单类型 aufnr TYPE aufk-aufnr, "生产订单号 aufnr1 TYPE aufk-aufnr, "生产订单号 gamng TYPE afko-gamng, "订单数量 gstrp TYPE afko-gstrp, "开始日期 gltrp TYPE afko-gltrp, "结束日期 zmph TYPE ztwm008-zmph, "铭牌号 zcsry TYPE zppt085-zcsry, "测试人员 zryxm TYPE zppt086-zryxm, "人员姓名 zrybm TYPE zppt086-zrybm, "部门 zcsrq TYPE zppt085-zcsrq, "测试日期 zcsjg TYPE zppt085-zcsjg, "测试结果 zdjrq TYPE zppt085-zdjrq, "登记日期 date TYPE string, zbhgy TYPE zppt085-zbhgy, "不合格描述 txt30 TYPE tj02t-txt30, "生产订单状态 autyp TYPE aufk-autyp, "订单类别 loekz TYPE aufk-loekz, "删除标记 istat TYPE tj02t-istat, "系统状态 sel TYPE c, END OF ty_alv. DATA:gs_alv TYPE ty_alv, gt_alv TYPE TABLE OF ty_alv, go_grid TYPE REF TO cl_gui_alv_grid, gs_alv1 TYPE zppt085, gt_alv1 TYPE TABLE OF zppt085, gs_alv2 TYPE ty_alv. DATA: gt_fieldcat TYPE lvc_t_fcat, gs_layout TYPE lvc_s_layo, gs_grid_settings TYPE lvc_s_glay, gs_fieldcat TYPE lvc_s_fcat. DEFINE add_fieldcat. CLEAR:gs_fieldcat. gs_fieldcat-fieldname = &1. gs_fieldcat-scrtext_l = &2. gs_fieldcat-scrtext_m = &2. gs_fieldcat-scrtext_s = &2. gs_fieldcat-coltext = &2. gs_fieldcat-ref_table = &3. gs_fieldcat-ref_field = &4. gs_fieldcat-cfieldname = &5. gs_fieldcat-currency = &6. gs_fieldcat-quantity = &7. gs_fieldcat-qfieldname = &8. gs_fieldcat-decimals = &9. IF gs_fieldcat-fieldname = 'SEL'. gs_fieldcat-checkbox = 'X'. gs_fieldcat-edit = 'X'. ENDIF. IF gs_fieldcat-fieldname = 'ZCSRY' OR gs_fieldcat-fieldname = 'ZCSRQ' OR gs_fieldcat-fieldname = 'ZCSJG' OR gs_fieldcat-fieldname = 'ZBHGY'. gs_fieldcat-edit = 'X'. ENDIF. APPEND gs_fieldcat TO gt_fieldcat. END-OF-DEFINITION. SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE TEXT-000. SELECT-OPTIONS: p_matnr FOR afpo-matnr NO INTERVALS."订单物料编码 SELECT-OPTIONS: p_werks FOR aufk-werks NO INTERVALS OBLIGATORY."工厂 SELECT-OPTIONS: p_aufnr FOR aufk-aufnr NO INTERVALS."生产订单号 SELECT-OPTIONS: p_gstrp FOR afko-gstrp."开始日期 SELECT-OPTIONS: p_gltrp FOR afko-gltrp."结束日期 SELECT-OPTIONS: p_auart FOR aufk-auart NO INTERVALS."订单类型 SELECT-OPTIONS: p_zmph FOR ztwm008-zmph NO INTERVALS."铭牌号 SELECTION-SCREEN END OF BLOCK b1. SELECTION-SCREEN BEGIN OF BLOCK b2 WITH FRAME TITLE TEXT-002. PARAMETERS: p_ch TYPE c AS CHECKBOX DEFAULT 'X'. SELECTION-SCREEN END OF BLOCK b2. AT SELECTION-SCREEN. * 检查权限(Check Author) * PERFORM frm_check_author. *&---------------------------------------------------------------------* *& START-OF-SELECTION *&---------------------------------------------------------------------* START-OF-SELECTION. * 赋值(get data) PERFORM frm_get_data. *&---------------------------------------------------------------------* *& END-OF-SELECTION *&---------------------------------------------------------------------* END-OF-SELECTION. *设置ALV输出格式(set layout) PERFORM frm_set_layout CHANGING gs_layout. * 设置ALV输出字段(set fieldacat) PERFORM frm_set_fieldcat. * ALV展示(display ALV) PERFORM frm_display_alv. FORM frm_get_data. DATA:number TYPE string. DATA:lv_where TYPE string. DATA: lv_year TYPE char4, "年份 lv_month TYPE char2, "月份 lv_day TYPE char2, "日期 lv_date TYPE char10. "格式化后的日期 "获取系统当前日期 DATA(lv_current_date) = sy-datum. "提取日期各部分 lv_year = lv_current_date(4). "取前4位作为年份 lv_month = lv_current_date+4(2). "从第5位开始取2位作为月份 lv_day = lv_current_date+6(2). "从第7位开始取2位作为日期 "使用CONCATENATE函数拼接 CONCATENATE lv_year '.' lv_month '.' lv_day INTO lv_date. SELECT b~matnr, a~werks, a~auart, a~aufnr, d~gamng, d~plnbez, c~maktx, e~zmph, a~objnr FROM aufk AS a INNER JOIN afko AS d ON d~aufnr = a~aufnr INNER JOIN afpo AS b ON b~matnr = d~plnbez AND b~aufnr = d~aufnr INNER JOIN makt AS c ON c~matnr = d~plnbez INNER JOIN ztwm008 AS e ON e~aufnr = a~aufnr WHERE a~autyp = 10 AND c~spras = 1 AND a~loekz <> 'X' AND b~matnr IN @p_matnr AND a~werks IN @p_werks AND a~aufnr IN @p_aufnr AND d~gstrp IN @p_gstrp AND d~gltrp IN @p_gltrp AND a~auart IN @p_auart AND e~zmph IN @p_zmph INTO TABLE @DATA(lt_form). LOOP AT lt_form INTO DATA(ls_form). MOVE-CORRESPONDING ls_form TO gs_alv. SELECT a~zdjcs,a~plnbez,a~maktx ,a~werks,a~auart,a~aufnr,a~gamng,c~zmph,a~zcsry,b~zryxm,b~zrybm,a~zcsrq,a~zcsjg,a~zdjrq,a~zbhgy FROM zppt085 AS a LEFT OUTER JOIN zppt086 AS b ON a~zcsry = b~zrygh LEFT OUTER JOIN ztwm008 AS c ON c~zmph = @gs_alv-zmph WHERE a~werks = @gs_alv-werks AND a~aufnr = @gs_alv-aufnr AND A~ZMPH = @GS_ALV-ZMPH INTO TABLE @DATA(lt_form2). "判断查询出的表是否为空,不为空,直接将数据插入alv内表中 IF lt_form2 IS NOT INITIAL. LOOP AT lt_form2 INTO DATA(ls_form2). MOVE-CORRESPONDING ls_form2 TO gs_alv2. gs_alv2-plnbez1 = gs_alv2-plnbez. gs_alv2-aufnr1 = gs_alv2-aufnr. SHIFT gs_alv2-plnbez1 LEFT DELETING LEADING '0'. SHIFT gs_alv2-aufnr1 LEFT DELETING LEADING '0'. "获取系统当前日期 CLEAR:lv_current_date,lv_year,lv_month,lv_day. lv_current_date = gs_alv2-zdjrq. "提取日期各部分 lv_year = lv_current_date(4). "取前4位作为年份 lv_month = lv_current_date+4(2). "从第5位开始取2位作为月份 lv_day = lv_current_date+6(2). "从第7位开始取2位作为日期 "使用CONCATENATE函数拼接 CONCATENATE lv_year '.' lv_month '.' lv_day INTO lv_date. gs_alv2-date = lv_date. APPEND gs_alv2 TO gt_alv. CLEAR gs_alv2. ENDLOOP. ELSE. IF gs_alv-zdjcs = 0. gs_alv-zdjcs = 1. ENDIF. "获取系统当前日期 CLEAR:lv_current_date,lv_year,lv_month,lv_day. lv_current_date = sy-datum. "提取日期各部分 lv_year = lv_current_date(4). "取前4位作为年份 lv_month = lv_current_date+4(2). "从第5位开始取2位作为月份 lv_day = lv_current_date+6(2). "从第7位开始取2位作为日期 "使用CONCATENATE函数拼接 CONCATENATE lv_year '.' lv_month '.' lv_day INTO lv_date. gs_alv-date = lv_date. gs_alv-zdjrq = lv_current_date. "结果存放在STATUS表中 CALL FUNCTION 'STATUS_READ' EXPORTING client = sy-mandt objnr = gs_alv-objnr TABLES status = t_status EXCEPTIONS object_not_found = 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. number = '0'. LOOP AT t_status. IF p_ch = 'X'. IF ( t_status-stat = 'I0001' AND t_status-inact IS INITIAL ) OR ( t_status-stat = 'I0045' AND t_status-inact IS INITIAL ). number = '1'. ENDIF. ELSEIF t_status-stat = 'I0001' AND t_status-inact IS INITIAL. number = '1'. ENDIF. ENDLOOP. gs_alv-plnbez1 = gs_alv-plnbez. gs_alv-aufnr1 = gs_alv-aufnr. SHIFT gs_alv-plnbez1 LEFT DELETING LEADING '0'. SHIFT gs_alv-aufnr1 LEFT DELETING LEADING '0'. IF number <> '1'. APPEND gs_alv TO gt_alv. ENDIF. CLEAR:gs_alv. ENDIF. ENDLOOP. ENDFORM. *&---------------------------------------------------------------------* *& Form FRM_SET_LAYOUT *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* * --> p1 text * <-- p2 text *----------------------------------------------------------------------* FORM frm_set_layout CHANGING p_layout TYPE lvc_s_layo. p_layout-zebra = 'X'. p_layout-sel_mode = 'D'. p_layout-cwidth_opt = 'X'. "自适应宽度(Adaptive width) ENDFORM. "frm_set_layout FORM frm_set_fieldcat. REFRESH gt_fieldcat. add_fieldcat: 'SEL ' '选择 ' '' '' '' '' '' '' '' , ' ' '消息类型 ' '' '' '' '' '' '' '' , ' ' '消息文本 ' '' '' '' '' '' '' '' , 'ZDJCS ' '登记次数 ' '' '' '' '' '' '' '' , 'PLNBEZ1 ' '订单物料编码 ' '' '' '' '' '' '' '' , 'MAKTX ' '订单物料描述 ' '' '' '' '' '' '' '' , 'WERKS ' '工厂 ' '' '' '' '' '' '' '' , 'AUART ' '生产订单类型 ' '' '' '' '' '' '' '' , 'AUFNR1 ' '生产订单号 ' '' '' '' '' '' '' '' , 'GAMNG ' '订单数量 ' '' '' '' '' '' '' '' , 'ZMPH ' '铭牌号 ' '' '' '' '' '' '' '' , 'ZCSRY' '测试人员 ' 'ZPPT086' 'ZRYGH' '' '' '' '' '' , 'ZRYXM ' '人员姓名 ' '' '' '' '' '' '' '' , 'ZRYBM ' '部门 ' '' '' '' '' '' '' '' , 'ZCSJG ' '测试结果 ' '' '' '' '' '' '' '', 'DATE ' '登记日期 ' '' '' '' '' '' '' '' , 'ZBHGY ' '不合格描述 ' '' '' '' '' '' '' '' . * GS_LOUT-BOX_FNAME = 'SEL'. gs_lout-zebra = 'X'. gs_lout-cwidth_opt = 'X'. ENDFORM. *&---------------------------------------------------------------------* *& Form FRM_DISPLAY_ALV *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* * --> p1 text * <-- p2 text *----------------------------------------------------------------------* FORM frm_display_alv. DATA:lt_events TYPE slis_t_event, ls_events TYPE slis_alv_event. gs_grid_settings-edt_cll_cb = 'X'. "回车后直接修改内表数据 ls_events-name = slis_ev_data_changed . ls_events-form = 'FRM_DATA_CHANGED'. APPEND ls_events TO lt_events. CLEAR:ls_events. CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC' EXPORTING i_callback_program = sy-repid i_callback_pf_status_set = 'FRM_SET_STATUS' "控制GUI i_callback_user_command = 'FRM_USER_COMMAND' "控制用户请求 i_grid_settings = gs_grid_settings " is_layout_lvc = gs_layout it_fieldcat_lvc = gt_fieldcat i_save = 'A' it_events = lt_events TABLES t_outtab = gt_alv EXCEPTIONS program_error = 1 OTHERS = 2. IF sy-subrc <> 0. * MESSAGE s006(zfi_msg) DISPLAY LIKE 'E'. ENDIF. IF go_grid IS INITIAL. CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR' IMPORTING e_grid = go_grid. ENDIF. ENDFORM. FORM frm_data_changed USING er_data_changed TYPE REF TO cl_alv_changed_data_protocol. DATA: ls_stable TYPE lvc_s_stbl. ls_stable-row = 'X'. ls_stable-col = 'X'. " 在事件处理中获取网格实例 IF go_grid IS NOT BOUND. CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR' IMPORTING e_grid = go_grid. ENDIF. FIELD-SYMBOLS: <f_data>, <f_value> TYPE lvc_s_modi-value, <f_field> TYPE any. DATA: ls_modi TYPE lvc_s_modi, lv_matnr TYPE mara-matnr, lv_value TYPE lvc_s_modi-value. LOOP AT er_data_changed->mt_mod_cells INTO DATA(ls_mod). ENDLOOP. LOOP AT er_data_changed->mt_good_cells INTO ls_modi . lv_value = ls_modi-value. SHIFT lv_value LEFT DELETING LEADING space. "去掉空格 IF ls_modi-fieldname = 'ZCSRY'. READ TABLE gt_alv ASSIGNING FIELD-SYMBOL(<fs_alv>) INDEX ls_modi-row_id. IF sy-subrc = 0. ASSIGN COMPONENT ls_modi-fieldname OF STRUCTURE <fs_alv> TO <f_field>. IF sy-subrc = 0. <f_field> = lv_value. ENDIF. SELECT SINGLE zryxm zrybm INTO (<fs_alv>-zryxm,<fs_alv>-zrybm) FROM zppt086 WHERE zrygh = lv_value. IF sy-subrc <> 0. CLEAR:<fs_alv>-zryxm,<fs_alv>-zrybm. ENDIF. ENDIF. ENDIF. ENDLOOP. " 只有在网格实例有效时才刷新 IF go_grid IS BOUND. "确保布局设置中启用了自适应列宽 gs_layout-cwidth_opt = 'X'. " 刷新显示 CALL METHOD go_grid->refresh_table_display EXPORTING is_stable = ls_stable. ELSE. " 如果无法获取网格实例,使用其他方式刷新 MESSAGE '数据已更新,请手动刷新显示' TYPE 'S'. ENDIF. ENDFORM. FORM frm_set_status USING rt_extab TYPE slis_t_extab. SET PF-STATUS 'STANDARD'. ENDFORM. *&---------------------------------------------------------------------* *& Form FRM_USER_COMMAND *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* * --> p1 text * <-- p2 text *----------------------------------------------------------------------* FORM frm_user_command USING r_ucomm LIKE sy-ucomm ##CALLED rs_selfield TYPE slis_selfield. DATA: e_lo_grid TYPE REF TO cl_gui_alv_grid. * 设置刷新模式,行列保持不变 rs_selfield-refresh = 'X'. rs_selfield-col_stable = 'X'. rs_selfield-row_stable = 'X'. IF go_grid IS INITIAL.. CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR' IMPORTING e_grid = go_grid. ENDIF. CALL METHOD go_grid->check_changed_data. * CALL METHOD go_grid->get_filtered_entries * IMPORTING * et_filtered_entries = lt_filt. "筛选数据的定义 DATA: lo_grid TYPE REF TO cl_gui_alv_grid. CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR' IMPORTING e_grid = lo_grid. CASE r_ucomm. WHEN '&SAVE'. " 打印 READ TABLE gt_alv INTO gs_alv WITH KEY sel = 'X'. IF sy-subrc <> 0. MESSAGE '请选择要保存的数据' TYPE 'E'. ENDIF. PERFORM frm_save_smartforms. WHEN '&COPY'. PERFORM copy_selected_rows. WHEN OTHERS. ENDCASE. CALL METHOD go_grid->refresh_table_display."刷新alv ENDFORM. FORM copy_selected_rows. DATA: lt_selected TYPE TABLE OF ty_alv, ls_selected TYPE ty_alv, lv_max_zdjcs TYPE zppt085-zdjcs, lt_group_data TYPE STANDARD TABLE OF ty_alv, lv_count TYPE i. "检查数据变更 CALL METHOD go_grid->check_changed_data. READ TABLE gt_alv INTO gs_alv WITH KEY sel = 'X'. IF sy-subrc <> 0. MESSAGE '请选择要复制的数据' TYPE 'E'. ENDIF. "遍历内表查找选中行 CLEAR gs_alv. CLEAR gs_alv2. "获取所有选中的行数据 LOOP AT gt_alv INTO gs_alv WHERE sel = 'X'. APPEND gs_alv TO lt_selected. ENDLOOP. LOOP AT lt_selected INTO ls_selected. CLEAR lt_group_data. LOOP AT gt_alv INTO DATA(ls_temp) WHERE werks = ls_selected-werks AND aufnr = ls_selected-aufnr AND zmph = ls_selected-zmph. " 替换为实际铭牌号字段 APPEND ls_temp TO lt_group_data. ENDLOOP. " 获取组内最大登记次数 lv_max_zdjcs = 1. LOOP AT lt_group_data INTO DATA(ls_group). IF ls_group-zdjcs > lv_max_zdjcs. lv_max_zdjcs = ls_group-zdjcs. ENDIF. ENDLOOP. ls_selected-zdjcs = lv_max_zdjcs + 1. ls_selected-zdjrq = sy-datum. ls_selected-sel = ''. APPEND ls_selected TO gt_alv. ENDLOOP. "刷新ALV显示 CALL METHOD go_grid->refresh_table_display. "显示成功消息 lv_count = lines( lt_selected ). MESSAGE |已成功复制 { lv_count } 行数据| TYPE 'S'. ENDFORM. FORM frm_save_smartforms. CLEAR gs_alv. CLEAR gs_alv1. LOOP AT gt_alv INTO gs_alv WHERE sel = 'X'. gs_alv1-zdjcs = gs_alv-zdjcs. gs_alv1-plnbez = gs_alv-plnbez. gs_alv1-maktx = gs_alv-maktx . gs_alv1-werks = gs_alv-werks. gs_alv1-auart = gs_alv-auart. gs_alv1-aufnr = gs_alv-aufnr. gs_alv1-gamng = gs_alv-gamng. gs_alv1-zmph = gs_alv-zmph. gs_alv1-zcsry = gs_alv-zcsry. gs_alv1-zryxm = gs_alv-zryxm. gs_alv1-zrybm = gs_alv-zrybm. gs_alv1-zcsrq = gs_alv-zcsrq. gs_alv1-zcsjg = gs_alv-zcsjg. gs_alv1-zdjrq = gs_alv-zdjrq. gs_alv1-zbhgy = gs_alv-zbhgy. APPEND gs_alv1 TO gt_alv1. CLEAR gs_alv. CLEAR gs_alv1. ENDLOOP. * MODIFY zppt085 FROM TABLE gt_alv1 . MODIFY zppt085 FROM TABLE gt_alv1. IF sy-subrc = 0. COMMIT WORK. MESSAGE '保存成功' TYPE 'I'. ELSE. ROLLBACK WORK. MESSAGE '保存失败' TYPE 'E'. ENDIF. ENDFORM. 根据上述完整代码添加功能:给测试结果字段添加下拉框:OK、NG
最新发布
11-30
<think> 我们正在处理ALV GRID中的下拉框设置。用户希望为字段ZCSJG添加下拉框,选项为OK和NG。 根据之前的上下文,我们需要以下步骤: 1. 定义一个内表来存储下拉值(类型为LVC_T_DROP),以及一个工作区(LVC_S_DROP)。 2. 填充下拉值:为每个选项指定相同的句柄(handle)和对应的值(value)。 3. 在字段目录(field catalog)中,找到字段名为'ZCSJG'的字段,设置其drdn_hndl属性为对应的句柄,并设置edit属性为'X'(允许编辑)。 4. 在创建ALV GRID实例之后,使用set_drop_down_table方法设置下拉表。 5. 如果需要,刷新ALV显示。 注意:用户提供的代码片段中,使用了内表gt_fcat作为字段目录。 因此,我们将在现有代码的基础上添加以下内容: 步骤1:在适当的位置声明下拉值内表和工作区(如果尚未声明) 步骤2:填充下拉值内表(假设我们使用句柄'1') 步骤3:修改字段目录中ZCSJG字段的属性 步骤4:在调用set_table_for_first_display之后(或之前)设置下拉表 由于用户没有提供完整的代码,我将假设代码中已经有一个字段目录内表gt_fcat,并且已经创建了ALV GRID对象go_alv_grid。 具体添加的代码: 在定义数据的地方添加: DATA: gt_dropdown TYPE lvc_t_drop, gs_dropdown TYPE lvc_s_drop. 在填充字段目录之前或之后,我们填充下拉表: gs_dropdown-handle = '1'. gs_dropdown-value = 'OK'. APPEND gs_dropdown TO gt_dropdown. gs_dropdown-handle = '1'. gs_dropdown-value = 'NG'. APPEND gs_dropdown TO gt_dropdown. 然后,在设置字段目录时,找到ZCSJG字段,设置drdn_hndl和edit属性。如果字段目录是循环处理的,可以这样: LOOP AT gt_fcat ASSIGNING FIELD-SYMBOL(<fs_fcat>) WHERE fieldname = 'ZCSJG'. <fs_fcat>-drdn_hndl = '1'. " 下拉值表中的handle一致 <fs_fcat>-edit = 'X'. " 允许编辑 ENDLOOP. 注意:如果字段目录是逐个字段添加的,可以在添加ZCSJG字段时直接设置属性。 在调用ALV显示方法之后,设置下拉表(也可以在之前,但通常在显示前设置): CALL METHOD go_alv_grid->set_drop_down_table EXPORTING it_drop_down = gt_dropdown. 另外,如果ALV已经显示,可能需要刷新: CALL METHOD go_alv_grid->refresh_table_display. 但是,如果是在第一次显示之前设置,则不需要立即刷新。 下面是一个整合的代码示例(假设在已有代码基础上添加): 注意:如果代码中已经有了字段目录的构建,我们只需要在构建字段目录时对ZCSJG字段进行特殊设置。 如果用户使用的是函数式ALV(REUSE_ALV_GRID_DISPLAY),则方法不同。但根据问题中提到的go_alv_grid,应该是面向对象的ALV(CL_GUI_ALV_GRID)。 因此,我们按照上述步骤修改。 如果用户提供的代码中没有字段目录的处理,我们需要先构建字段目录,但这不在本问题的范围内。我们假设已有字段目录内表gt_fcat。 代码添加位置示例: 在声明部分: DATA: gt_dropdown TYPE lvc_t_drop, gs_dropdown TYPE lvc_s_drop. 在程序逻辑中(比如在准备ALV显示之前): " 填充下拉表 CLEAR gt_dropdown. gs_dropdown-handle = '1'. gs_dropdown-value = 'OK'. APPEND gs_dropdown TO gt_dropdown. gs_dropdown-value = 'NG'. APPEND gs_dropdown TO gt_dropdown. " 修改字段目录 LOOP AT gt_fcat ASSIGNING FIELD-SYMBOL(<fs_fcat>) WHERE fieldname = 'ZCSJG'. <fs_fcat>-drdn_hndl = '1'. <fs_fcat>-edit = 'X'. ENDLOOP. " 创建ALV GRID对象(如果还没有创建) " ... 创建代码 ... " 设置下拉表 go_alv_grid->set_drop_down_table( EXPORTING it_drop_down = gt_dropdown ). " 显示ALV CALL METHOD go_alv_grid->set_table_for_first_display EXPORTING ... " 其他参数 CHANGING it_outtab = gt_data it_fieldcatalog = gt_fcat. 注意:如果ALV已经显示,可能需要刷新,但第一次显示时不需要。 如果用户希望动态更新下拉框(例如,在程序运行过程中改变下拉选项),可以重新调用set_drop_down_table方法,然后刷新ALV。 现在,我们根据用户要求,在给定的代码中为ZCSJG字段添加下拉框。 </think> 在ABAP代码中为测试结果字段`ZCSJG`添加包含`OK`和`NG`选项的下拉框,需要以下步骤: ### 实现步骤 1. **声明下拉值表**: 在数据定义部分添加: ```abap DATA: gt_dropdown TYPE lvc_t_drop, " 下拉值表 gs_dropdown TYPE lvc_s_drop. " 下拉值行结构 ``` 2. **填充下拉选项**: 在初始化逻辑中添加下拉值: ```abap " 填充下拉选项 gs_dropdown-handle = '1'. " 下拉框标识符 gs_dropdown-value = 'OK'. " 选项1 APPEND gs_dropdown TO gt_dropdown. gs_dropdown-handle = '1'. " 相同标识符 gs_dropdown-value = 'NG'. " 选项2 APPEND gs_dropdown TO gt_dropdown. ``` 3. **配置字段目录**: 在ALV字段目录设置中修改`ZCSJG`字段: ```abap LOOP AT gt_fcat ASSIGNING FIELD-SYMBOL(<fs_fcat>) WHERE fieldname = 'ZCSJG'. <fs_fcat>-drdn_hndl = '1'. " 绑定下拉句柄 <fs_fcat>-edit = 'X'. " 启用编辑模式 ENDLOOP. ``` 4. **设置下拉数据源**: 在ALV初始化后绑定下拉表: ```abap " 在调用set_table_for_first_display之后 CALL METHOD go_alv_grid->set_drop_down_table EXPORTING it_drop_down = gt_dropdown. " 传入下拉值表 ``` 5. **刷新显示**(可选): ```abap CALL METHOD go_alv_grid->refresh_table_display. ``` ### 完整代码示例 ```abap " 1. 数据定义 DATA: gt_dropdown TYPE lvc_t_drop, gs_dropdown TYPE lvc_s_drop. " 2. 下拉值初始化 FORM init_dropdown_values. CLEAR: gt_dropdown. gs_dropdown-handle = '1'. gs_dropdown-value = 'OK'. APPEND gs_dropdown TO gt_dropdown. gs_dropdown-handle = '1'. gs_dropdown-value = 'NG'. APPEND gs_dropdown TO gt_dropdown. ENDFORM. " 3. ALV字段目录配置 FORM prepare_fieldcatalog. LOOP AT gt_fcat ASSIGNING FIELD-SYMBOL(<fs_fcat>) WHERE fieldname = 'ZCSJG'. <fs_fcat>-drdn_hndl = '1'. " 绑定下拉句柄 <fs_fcat>-edit = 'X'. " 启用编辑 ENDLOOP. ENDFORM. " 4. ALV显示逻辑 FORM display_alv. " 创建ALV实例 go_alv_grid = NEW cl_gui_alv_grid( ... ). " 设置下拉表 CALL METHOD go_alv_grid->set_drop_down_table EXPORTING it_drop_down = gt_dropdown. " 显示数据 CALL METHOD go_alv_grid->set_table_for_first_display( ... ). ENDFORM. ``` ### 关键说明 1. **句柄一致性** 字段目录的`drdn_hndl`值必须下拉值表的`handle`匹配(本例中都使用`'1'`)[^1] 2. **编辑模式** 必须设置`edit = 'X'`才能使下拉框在ALV中可见 3. **数据刷新** 如果修改了下拉选项,需重新调用`set_drop_down_table()`并刷新ALV: ```abap CALL METHOD go_alv_grid->set_drop_down_table( it_drop_down = gt_new_dropdown ). CALL METHOD go_alv_grid->refresh_table_display. ``` 4. **取值验证** 当用户选择值时,可在`DATA_CHANGED`事件中验证输入值是否在允许范围内 > 此实现基于标准ALV控件`CL_GUI_ALV_GRID`的`SET_DROP_DOWN_TABLE`方法[^1],通过句柄机制绑定字段下拉列表[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值