OPK8 正常情况下是不可以配置Smart form 的
OPK8进入工单打印配置界面,选择Forms, 你会发现只有Script form 和PDF form(Adobe form)可选的,没有配置smartform的地方
这时候如果想要使用Smart form 可以用以下这种解决方案
通过IMG或OPK8访问的SAP PP车间控制输出文书工作的标准配置并未更改,以受益于Smartforms(ECC6 EHP 0)的引入。这限制了SapScript的使用,尽管SapScript能够提供设计自己的输出的功能,但仍有一些限制。我们遇到的主要限制之一是要求拥有能够打印条形码的打印机,以便将其添加到输出中,而使用Smartforms,您可以在任何以图形形式发送的打印机上打印条形码。除此之外,Smartforms的设计和定制要容易得多,这促使我寻找一种配置SAP以允许Smartforms的方法。
1.OPK8 配置form时,选择一个已经存在的Script form。这个form只是一个傀儡,实际打印不会调用该form.
2. 配置自定义的Print Program.
注意程序结构
两个必须的include
INCLUDE ppcoincl.
INCLUDE lcodrinc.
一个必须的子例程,名字必须为print_sub
完整程序如下
*&--------------------------------------------------------------------* *& Report ZRMP0698_01 *&--------------------------------------------------------------------* *& *&--------------------------------------------------------------------* REPORT zrmp0698_01 MESSAGE-ID zmp. TABLES: nast. INCLUDE znmp0698_revision_log IF FOUND. INCLUDE ppcoincl. INCLUDE lcodrinc. INCLUDE znmp0698_01_top. * entry to print PERFORM print_sub. *&---------------------------------------------------------------------* *& Form PRINT_SUB *&---------------------------------------------------------------------* * entry to print *----------------------------------------------------------------------* FORM print_sub. CLEAR: gv_fmname,gt_components,gt_operations,gs_header,gs_control,gs_options. PERFORM sub_get_data. PERFORM sub_get_fm. PERFORM sub_set_print_param USING gs_control gs_options. PERFORM sub_perform_output. ENDFORM. *&---------------------------------------------------------------------* *& Form SUB_GET_DATA *&---------------------------------------------------------------------* * Get input data *----------------------------------------------------------------------* FORM sub_get_data. DATA:lv_number TYPE bapi_order_key-order_number. DATA:ls_objects TYPE bapi_pp_order_objects. DATA:ls_return TYPE bapiret2. DATA: lt_header TYPE STANDARD TABLE OF bapi_order_header1, "Header Info lt_position TYPE STANDARD TABLE OF bapi_order_item, "Position Info lt_operation TYPE STANDARD TABLE OF bapi_order_operation1, "Operation Info lt_component TYPE STANDARD TABLE OF bapi_order_component. "Copmonents Info DATA: lt_vali TYPE STANDARD TABLE OF api_vali. DATA:lv_object TYPE ausp-objek. DATA:lv_t TYPE char8. READ TABLE caufvd_tab INTO DATA(ls_tab) INDEX 1. lv_number = ls_tab-aufnr. * 1. Issue error message if order doesn’t exist IF lv_number IS INITIAL. CALL FUNCTION 'NAST_PROTOCOL_UPDATE' EXPORTING msg_arbgb = gc_msg_id msg_nr = gc_msg_nr msg_ty = gc_msg_e msg_v1 = 'Order does not exist!'(m01) msg_v2 = ' ' msg_v3 = ' ' msg_v4 = ' ' EXCEPTIONS message_type_not_valid = 1 no_sy_message = 2 OTHERS = 3. IF sy-subrc <> 0. " UPDATE ERROR LOG, NO NEED CHECK. ENDIF. ENDIF. SELECT aufnr, a~objnr, stat INTO TABLE @DATA(lt_jest) FROM aufk AS a JOIN jest AS b ON a~objnr = b~objnr WHERE aufnr = @lv_number AND stat = @gc_stat AND inact = ''. IF sy-subrc = 0. CALL FUNCTION 'NAST_PROTOCOL_UPDATE' EXPORTING msg_arbgb = gc_msg_id msg_nr = gc_msg_nr msg_ty = gc_msg_e msg_v1 = 'Order has been delete!'(m02) msg_v2 = ' ' msg_v3 = ' ' msg_v4 = ' ' EXCEPTIONS message_type_not_valid = 1 no_sy_message = 2 OTHERS = 3. IF sy-subrc <> 0. " UPDATE ERROR LOG, NO NEED CHECK. ENDIF. ENDIF. ls_objects-header = abap_true. ls_objects-operations = abap_true. ls_objects-components = abap_true. ls_objects-positions = abap_true. CALL FUNCTION 'BAPI_PRODORD_GET_DETAIL' EXPORTING number = lv_number order_objects = ls_objects IMPORTING return = ls_return TABLES header = lt_header position = lt_position operation = lt_operation component = lt_component. IF sy-subrc = 0. IF lt_header IS NOT INITIAL. READ TABLE lt_header INTO DATA(ls_header) INDEX 1. IF sy-subrc = 0. lv_object = ls_header-material. PERFORM sub_convert_date USING sy-datum sy-uzeit CHANGING gs_header-print_date gs_header-print_time. gs_header-aufart = ls_header-order_type. "Get special type CALL FUNCTION 'QC01_BATCH_VALUES_READ' EXPORTING i_val_matnr = ls_header-material i_val_werks = ls_header-production_plant i_val_charge = ls_header-batch i_language = sy-langu i_date = sy-datum TABLES t_val_tab = lt_vali EXCEPTIONS no_class = 1 internal_error = 2 no_values = 3 no_chars = 4 OTHERS = 5. IF sy-subrc = 0. SORT lt_vali BY atnam. READ TABLE lt_vali INTO DATA(ls_vali) WITH KEY atnam = gc_atnam BINARY SEARCH. IF sy-subrc = 0. gs_header-special_type = ls_vali-atwtb. ENDIF. ELSE. CALL FUNCTION 'NAST_PROTOCOL_UPDATE' EXPORTING msg_arbgb = sy-msgid msg_nr = sy-msgno msg_ty = sy-msgty msg_v1 = sy-msgv1 msg_v2 = sy-msgv2 msg_v3 = sy-msgv3 msg_v4 = sy-msgv4 EXCEPTIONS message_type_not_valid = 1 no_sy_message = 2 OTHERS = 3. IF sy-subrc <> 0. " UPDATE ERROR LOG, NO NEED CHECK. ENDIF. ENDIF. gs_header-batch = ls_header-batch. *Begin DEL:Joe Wang:23-Apr-2021:ECR202002738 * SELECT SINGLE licha INTO gs_header-licha * FROM mcha * WHERE matnr = ls_header-material * AND werks = ls_header-production_plant * AND charg = ls_header-batch. *End DEL:Joe Wang:23-Apr-2021:ECR202002738 *Begin ADD:Joe Wang:23-Apr-2021:ECR202002738 SELECT SINGLE licha INTO gs_header-licha FROM mch1 WHERE matnr = ls_header-material AND charg = ls_header-batch AND lvorm = ''. *End ADD:Joe Wang:23-Apr-2021:ECR202002738 IF sy-subrc = 0. IF gs_header-licha IS INITIAL. gs_header-licha = gs_header-batch. ENDIF. ENDIF. gs_header-aufnr = ls_header-order_number. gs_header-plant = ls_header-production_plant. gs_header-fevor = ls_header-production_scheduler. gs_header-co_dispo = ls_header-mrp_controller. gs_header-matnr = ls_header-material. SELECT pmatn INTO gs_header-pmatn UP TO 1 ROWS FROM mvke WHERE matnr = ls_header-material *Begin ADD:Joe Wang:23-Apr-2021:ECR202002738 and dwerk = ls_header-production_plant. *End ADD:Joe Wang:23-Apr-2021:ECR202002738 ENDSELECT. IF sy-subrc NE 0. "no acctions here , keep gs_header-pmatn ENDIF. gs_header-co_matxt = ls_header-material_text. READ TABLE lt_position INTO DATA(ls_pos) INDEX 1. IF sy-subrc = 0. gs_header-verid = ls_pos-production_version. SELECT SINGLE text1 INTO gs_header-vers_text FROM mkal WHERE matnr = ls_header-material AND werks = ls_header-production_plant AND verid = ls_pos-production_version. IF sy-subrc NE 0. "no acctions here , keep gs_header-vers_text ENDIF. ENDIF. SELECT a~doknr, a~dokvr, c~datuv INTO TABLE @DATA(lt_draw) FROM drad AS a INNER JOIN draw AS b ON a~dokar = b~dokar AND a~doknr = b~doknr AND a~dokvr = b~dokvr AND a~doktl = b~doktl LEFT JOIN aenr AS c ON b~aennr = c~aennr WHERE a~objky = @ls_header-material AND a~dokar = @gc_dokar AND b~dokst = @gc_dokst. IF sy-subrc = 0. SORT lt_draw BY datuv DESCENDING. READ TABLE lt_draw INTO DATA(ls_draw) INDEX 1. IF sy-subrc = 0. gs_header-doknr = ls_draw-doknr. gs_header-dokvr = ls_draw-dokvr. ENDIF. ENDIF. gs_header-gamng = ls_header-target_quantity. gs_header-gamng_st = gs_header-gamng. CONDENSE gs_header-gamng_st NO-GAPS. SHIFT gs_header-gamng_st RIGHT DELETING TRAILING gc_zero. SHIFT gs_header-gamng_st RIGHT DELETING TRAILING gc_point. CONDENSE gs_header-gamng_st NO-GAPS. gs_header-unit = ls_header-unit. PERFORM sub_convert_date USING ls_header-start_date ls_header-start_time CHANGING gs_header-start_date lv_t. PERFORM sub_convert_date USING ls_header-finish_date ls_header-finish_time CHANGING gs_header-finish_date lv_t. SELECT ablad INTO gs_header-ablad UP TO 1 ROWS FROM afpo WHERE aufnr = ls_header-order_number. ENDSELECT. IF sy-subrc NE 0. "no acctions here , keep gs_header-ablad ENDIF. ENDIF. ENDIF. IF lt_component IS NOT INITIAL. SELECT rsnum, rspos, schgt INTO TABLE @DATA(lt_resb) FROM resb FOR ALL ENTRIES IN @lt_component WHERE rsnum = @lt_component-reservation_number AND rspos = @lt_component-reservation_item. IF sy-subrc = 0. SORT lt_resb BY rsnum rspos. ENDIF. ENDIF. LOOP AT lt_component INTO DATA(ls_cm). APPEND INITIAL LINE TO gt_components ASSIGNING FIELD-SYMBOL(<fs_cm>). *Begin DEL:Joe Wang:23-Apr-2021:ECR202002738 * <fs_cm>-item = ls_cm-reservation_item. *End DEL:Joe Wang:23-Apr-2021:ECR202002738 *Begin ADD:Joe Wang:23-Apr-2021:ECR202002738 <fs_cm>-item = ls_cm-item_number. *End ADD:Joe Wang:23-Apr-2021:ECR202002738 <fs_cm>-matnr = ls_cm-material. <fs_cm>-maktx = ls_cm-material_description. <fs_cm>-erfmg = ls_cm-entry_uom. <fs_cm>-bdmng = ls_cm-req_quan. <fs_cm>-bdmng_st = ls_cm-req_quan. CONDENSE <fs_cm>-bdmng_st NO-GAPS. <fs_cm>-batch = ls_cm-batch. READ TABLE lt_resb INTO DATA(ls_resb) WITH KEY rsnum = ls_cm-reservation_number rspos = ls_cm-reservation_item BINARY SEARCH. IF sy-subrc = 0. <fs_cm>-schgt = ls_resb-schgt. ENDIF. UNASSIGN <fs_cm>. ENDLOOP. SORT gt_components BY item. IF lt_operation IS NOT INITIAL. SELECT steus, txt INTO TABLE @DATA(lt_t430t) FROM t430t FOR ALL ENTRIES IN @lt_operation WHERE steus = @lt_operation-opr_cntrl_key AND spras = @sy-langu AND plnaw = @gc_plnaw. IF sy-subrc = 0. SORT lt_t430t BY steus. ENDIF. SELECT aufpl, aplzl, vgw01, vge01, vgw02, vge02, vgw03, vge03 INTO TABLE @DATA(lt_afvv) FROM afvv FOR ALL ENTRIES IN @lt_operation WHERE aufpl = @lt_operation-routing_no AND aplzl = @lt_operation-counter. IF sy-subrc = 0. SORT lt_afvv BY aufpl aplzl. ENDIF. ENDIF. LOOP AT lt_operation INTO DATA(ls_op). APPEND INITIAL LINE TO gt_operations ASSIGNING FIELD-SYMBOL(<fs_op>). <fs_op>-vornr = ls_op-operation_number. <fs_op>-ltxa1 = ls_op-description. <fs_op>-steus = ls_op-opr_cntrl_key. READ TABLE lt_t430t INTO DATA(ls_430t) WITH KEY steus = ls_op-opr_cntrl_key BINARY SEARCH. IF sy-subrc = 0. <fs_op>-steutxt = ls_430t-txt. ENDIF. <fs_op>-arbpl = ls_op-work_center. <fs_op>-co_rueck = ls_op-conf_no. READ TABLE lt_afvv INTO DATA(ls_afvv) WITH KEY aufpl = ls_op-routing_no aplzl = ls_op-counter BINARY SEARCH. IF sy-subrc = 0. <fs_op>-setup = |{ ls_afvv-vgw01 } { ls_afvv-vge01 }|. <fs_op>-machine = |{ ls_afvv-vgw02 } { ls_afvv-vge02 }|. <fs_op>-labor = |{ ls_afvv-vgw03 } { ls_afvv-vge03 }|. ENDIF. UNASSIGN <fs_op>. ENDLOOP. SORT gt_operations BY vornr. ENDIF. ENDFORM. *&---------------------------------------------------------------------* *& Form SUB_CONVERT_DATE *&---------------------------------------------------------------------* * Convert date into local time *----------------------------------------------------------------------* FORM sub_convert_date USING i_date TYPE syst_datum i_time TYPE syst_uzeit CHANGING c_date TYPE char10 c_time TYPE char8. DATA: lv_date TYPE sy-datum, lv_time TYPE sy-uzeit. DATA:lv_tzone TYPE timezone. DATA:lv_timesp TYPE tzonref-tstamps."TIME STAMPS CALL FUNCTION 'GET_SYSTEM_TIMEZONE' IMPORTING timezone = lv_tzone EXCEPTIONS customizing_missing = 1 OTHERS = 2. IF sy-subrc <> 0. CALL FUNCTION 'NAST_PROTOCOL_UPDATE' EXPORTING msg_arbgb = sy-msgid msg_nr = sy-msgno msg_ty = sy-msgty msg_v1 = sy-msgv1 msg_v2 = sy-msgv2 msg_v3 = sy-msgv3 msg_v4 = sy-msgv4 EXCEPTIONS message_type_not_valid = 1 no_sy_message = 2 OTHERS = 3. IF sy-subrc <> 0. " UPDATE ERROR LOG, NO NEED CHECK. ENDIF. ENDIF. CALL FUNCTION 'IB_CONVERT_INTO_TIMESTAMP' EXPORTING i_datlo = i_date i_timlo = i_time i_tzone = lv_tzone IMPORTING e_timestamp = lv_timesp. IF sy-subrc <> 0. CALL FUNCTION 'NAST_PROTOCOL_UPDATE' EXPORTING msg_arbgb = sy-msgid msg_nr = sy-msgno msg_ty = sy-msgty msg_v1 = sy-msgv1 msg_v2 = sy-msgv2 msg_v3 = sy-msgv3 msg_v4 = sy-msgv4 EXCEPTIONS message_type_not_valid = 1 no_sy_message = 2 OTHERS = 3. IF sy-subrc <> 0. " UPDATE ERROR LOG, NO NEED CHECK. ENDIF. ENDIF. CALL FUNCTION 'IB_CONVERT_FROM_TIMESTAMP' EXPORTING i_timestamp = lv_timesp i_tzone = sy-zonlo IMPORTING e_datlo = lv_date e_timlo = lv_time. IF sy-subrc = 0. CONCATENATE lv_date+0(4) lv_date+4(2) lv_date+6(2) INTO c_date SEPARATED BY gc_sp_1. CONCATENATE lv_time+0(2) lv_time+2(2) lv_time+4(2) INTO c_time SEPARATED BY gc_sp_2. ENDIF. ENDFORM. *&---------------------------------------------------------------------* *& Form FRM_SET_PRINT_PARAM *&---------------------------------------------------------------------* * text *----------------------------------------------------------------------* * <--P_LS_CONTROL_PARAM text * <--P_LS_COMPOSER_PARAM text *----------------------------------------------------------------------* FORM sub_set_print_param CHANGING pv_control_param TYPE ssfctrlop pv_composer_param TYPE ssfcompop. DATA: ls_itcpo TYPE itcpo. DATA: lv_repid TYPE sy-repid. DATA: lv_device TYPE tddevice. DATA: lv_retcode TYPE sysubrc. lv_repid = sy-repid. CALL FUNCTION 'WFMC_PREPARE_SMART_FORM' EXPORTING pi_nast = nast pi_repid = lv_repid IMPORTING pe_returncode = lv_retcode pe_itcpo = ls_itcpo pe_device = lv_device. IF sy-subrc = 0 AND lv_retcode = 0. MOVE-CORRESPONDING ls_itcpo TO pv_composer_param. pv_composer_param-tdnewid = abap_true. pv_control_param-device = lv_device. pv_control_param-no_dialog = abap_true. pv_control_param-getotf = ls_itcpo-tdgetotf. pv_control_param-langu = nast-spras. ELSE. * pv_composer_param-tdarmod = abap_true. pv_composer_param-tdnewid = abap_true. pv_composer_param-tdimmed = abap_true. pv_composer_param-tddest = print_co-desti. * pv_control_param-device = 'LP01'. pv_control_param-no_dialog = abap_true. * pv_control_param-getotf = ls_itcpo-tdgetotf. pv_control_param-langu = print_co-spras. ENDIF. ENDFORM. *&---------------------------------------------------------------------* *& Form SUB_GET_FM *&---------------------------------------------------------------------* * This routine dynamically passes the function module name *----------------------------------------------------------------------* FORM sub_get_fm . DATA:lv_name TYPE rvari_vnam. " ABAP: Name of Variant Variable DATA:l_numb TYPE tvarv_numb . " ABAP: Current selection number MOVE print_co-drvar TO l_numb . CONCATENATE gc_sfname print_co-lstid INTO lv_name. * Fetch the smartform name based on output type and Current selection * number SELECT SINGLE low INTO gv_formname FROM tvarv " Table of variables in selection criteria WHERE name = lv_name AND type = gc_type_p AND numb = l_numb. "Print Varient CLEAR: gv_fmname. CALL FUNCTION 'SSF_FUNCTION_MODULE_NAME' EXPORTING formname = gv_formname IMPORTING fm_name = gv_fmname EXCEPTIONS no_form = 1 no_function_module = 2 OTHERS = 3. IF sy-subrc NE 0. CALL FUNCTION 'NAST_PROTOCOL_UPDATE' EXPORTING msg_arbgb = sy-msgid msg_nr = sy-msgno msg_ty = sy-msgty msg_v1 = sy-msgv1 msg_v2 = sy-msgv2 msg_v3 = sy-msgv3 msg_v4 = sy-msgv4 EXCEPTIONS message_type_not_valid = 1 no_sy_message = 2 OTHERS = 3. IF sy-subrc <> 0. " UPDATE ERROR LOG, NO NEED CHECK. ENDIF. ENDIF. ENDFORM. " sub_get_fm *&---------------------------------------------------------------------* *& Form sub_perform_output *&---------------------------------------------------------------------* * This routine populates the final tables and structures being * passed to the smartforms *----------------------------------------------------------------------* FORM sub_perform_output . * The smartform calling function IF gv_fmname IS NOT INITIAL. CALL FUNCTION gv_fmname EXPORTING control_parameters = gs_control output_options = gs_options it_components = gt_components it_operations = gt_operations is_header = gs_header EXCEPTIONS formatting_error = 1 internal_error = 2 send_error = 3 user_canceled = 4 OTHERS = 5. IF sy-subrc <> 0. CALL FUNCTION 'NAST_PROTOCOL_UPDATE' EXPORTING msg_arbgb = sy-msgid msg_nr = sy-msgno msg_ty = sy-msgty msg_v1 = sy-msgv1 msg_v2 = sy-msgv2 msg_v3 = sy-msgv3 msg_v4 = sy-msgv4 EXCEPTIONS message_type_not_valid = 1 no_sy_message = 2 OTHERS = 3. IF sy-subrc <> 0. " UPDATE ERROR LOG, NO NEED CHECK. ENDIF. ENDIF. ENDIF. ENDFORM. " sub_perform_output
真正的smartform 配置在表TVARV 里,改信息需要workbance 工作台传输请求。注意请求号0007的配置 和OPK8 的Print variant 有关。
搞定!