In der Vorschriften Klasse werden Funktionen für die Generierung der PP spezifischen Strukturen für Stücklisten und Arbeitsplan implementiert. Nachfolgend sind Beispiele für speziell die Vorschriftenarten WORKORDER und PRODUCTION_VERSION dargestellt. Zu beachten ist, dass eine kundenindividuelle Implementierung zugeschnitten an die jeweiligen Anforderungen Unterschiede aufweisen kann.
1. Initiales Anlegen der VART-Klasse
Initiales Anlegen einer Klasse zur Vorschriftenart (P)
2. Implementierung Interface /SCT/QP_IF_PP und Stammdaten Methode GET_PP_MASTER_DATA
Mit dieser Methode werden die Stücklisten und Arbeitsplandaten der Vorschriftenarten aufgebaut:
Verwendung /SCT/QP_IF
PUBLIC SECTION. INTERFACES /sct/qp_if_pp . METHOD /sct/qp_if_pp~get_pp_master_data.* Call of PP-service-method. Converting specification structur into structture MKAL, STPO and PLPO rt_dispo = mo_pp_service->/sct/qp_if_pp_service~map_instance_to_masterdata( is_origin = is_origin io_vart = me ). ENDMETHOD.Die Methode wird sowohl für die Vorschriftenart WORKORDER als auch PRODUCTION_VERSION benötigt.
3. Implementierung SYNC Methoden SYNC_ORDER_TO_QPPD und SYNC_QPPD_TO_ORDER
Für die Vorschriftenart WORKORDER sind die folgenden beiden Methoden zu implementieren über das Interface /SCT/QP/IF/PP. Diese werden benötigt, um die Synchronisierung zwischen dem QPPD-Objekt zum Fertigungsauftrag zum Standard SAP herzustellen:
Verwendung /SCT/QP_IF
METHOD /sct/qp_if_pp~sync_order_to_qppd. TRY. mo_pp_service->workorder_to_qppd( EXPORTING ir_header = ir_header ir_operations = ir_operations ir_bom = ir_bom io_vart = me iv_syncmodel = c_mapping_workorder ). CATCH /sct/qp_cx_error INTO DATA(lo_error). ENDTRY. ENDMETHOD. METHOD /sct/qp_if_pp~sync_qppd_to_order. TRY. mo_pp_service->qppd_to_workorder( EXPORTING ir_header = ir_header ir_operations = ir_operations ir_bom = ir_bom io_vart = me iv_syncmodel = c_mapping_workorder CATCH /sct/qp_cx_error INTO DATA(lo_error). ENDTRY. ENDMETHOD. 4. Builder: Generierung von Knoten
Die Vorschriftenart besitzt eine Struktur mit rekursiven Baugruppen:

Die Builder Methoden bauen diese Struktur auf. Als Grundlage dienen die SAP Standard Stücklisten und Arbeitspläne.
Builder
* <SIGNATURE>---------------------------------------------------------------------------------------+* | Instance Protected Method /SCT/MT_CL_PRODUCTION_VERSION->BUILD* +-------------------------------------------------------------------------------------------------+* | [!CX!] /SCT/QP_CX_ERROR* | [!CX!] /SCT/MT_CX_ERROR* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD build. /sct/mt_if_production_version~mo_production ?= /sct/mt_cl_production=>/sct/mt_if_production~get_instance( iv_material = /sct/qp_if_vart~mrs_node_data->matnr iv_plant = /sct/qp_if_vart~mrs_node_data->werks ). CLEAR /sct/mt_if_production_version~mo_production. IF mo_ecc IS NOT BOUND. mo_ecc = /sct/mt_cl_ecc=>/sct/mt_if_ecc~get_instance( iv_link_guid = /sct/qp_if_vart~mrs_node_data->guid ). IF mo_ecc IS NOT BOUND. mo_ecc = /sct/mt_cl_ecc=>/sct/mt_if_ecc~get_instance( iv_doctype = mc->doctype_marc iv_link_guid = /sct/qp_if_vart~mrs_node_data->guid ). ENDIF. ENDIF. IF mo_ecc IS BOUND. /sct/mt_if_production_version~mo_production ?= mo_ecc->get_production( ). ENDIF. IF /sct/qp_if_vart~mrs_node_data->noderel IS INITIAL. build_init( ). RETURN. ENDIF. build_key_set( ). DATA(lr_assembly) = get_base( iv_vtyp = 'ASSEMBLY' ). DATA(lt_itembase) = mt_itembase. LOOP AT lt_itembase REFERENCE INTO DATA(lr_itembase). lr_itembase->val = build_key_get( it_element = lr_itembase->val ). build_delete_items( ir_itembase = lr_itembase ). IF is_item_existing( ir_itembase = lr_itembase ) = abap_false. CASE lr_itembase->vtyp. WHEN const-operation-vtyp. build_operation( is_itembase = lr_itembase->* ir_parent = lr_assembly ). WHEN const-testing-vtyp. build_testing( is_itembase = lr_itembase->* ir_parent = lr_assembly ). WHEN OTHERS. ENDCASE. ENDIF. ENDLOOP. ENDMETHOD. * <SIGNATURE>---------------------------------------------------------------------------------------+* | Instance Protected Method /SCT/MT_CL_PRODUCTION_VERSION->BUILD_INIT* +-------------------------------------------------------------------------------------------------+* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD build_init.*********************************************************************** Erzeugung der QPPD-Hierarchie anhand der SAP-Fertigungsversion*********************************************************************** KMAT ermitteln* PP_SERVICE bemühen und Abeitsplan und Stückliste besorgen* Dementsprechend Knoten aufbauen. DATA(lv_kmat) = /sct/mt_if_production_version~mo_production->/sct/qp_if_vart~get_value( 'MT_MATNR_CONF' ). IF lv_kmat IS INITIAL. lv_kmat = 'SLAB'. ENDIF. DATA : lo_mm_service TYPE REF TO /sct/qp_if_mm_service. /sct/qp_cl_factory=>get_instance( CHANGING co_instance = lo_mm_service ). DATA(lr_fvers) = lo_mm_service->get_prodversion( EXPORTING iv_matnr = lv_kmat iv_werks = CONV #( /sct/qp_if_vart~get_value( 'MT_PLANT' ) ) iv_verid = CONV #( /sct/qp_if_vart~get_value( 'MT_VERSION' ) ) ). do_map_from_masterdata( lr_fvers ). ENDMETHOD. * <SIGNATURE>---------------------------------------------------------------------------------------+* | Instance Protected Method /SCT/MT_CL_PRODUCTION_VERSION->BUILD_OPERATION* +-------------------------------------------------------------------------------------------------+* | [--->] IS_ITEMBASE TYPE TY_ITEMBASE* | [--->] IR_PARENT TYPE REF TO /SCT/QP_S_BASE* | [<-()] RS_ITEMBASE TYPE REF TO /SCT/QP_S_BASE* | [!CX!] /SCT/QP_CX_ERROR* +--------------------------------------------------------------------------------------</SIGNATURE> METHOD build_operation. DATA(ls_node) = CORRESPONDING /sct/qp_s_qvc_data_sort( is_itembase ). ls_node-vname = 'OPERATION'. build_create_item( is_base_parent = ir_parent->* iv_posnr = CONV #( 9999 - is_itembase-posnr ) is_node_target = ls_node ). ENDMETHOD.* <SIGNATURE>---------------------------------------------------------------------------------------+* | Instance Protected Method /SCT/MT_CL_PRODUCTION_VERSION->DO_MAP_FROM_MASTERDATA* +-------------------------------------------------------------------------------------------------+* | [--->] IR_PRODVERS TYPE REF TO /SCT/QP_IF_MM_SERVICE=>TY_PRODVERSION* +--------------------------------------------------------------------------------------</SIGNATURE> METHOD do_map_from_masterdata.*********************************************************************** Erzeugt eine QPPD Hierarchie anhand der gewählte Fertigungsversion********************************************************************** DATA(ls_node) = VALUE /sct/qp_s_qvc_data_sort( vtyp = const-assembly-vtyp hiera = const-assembly-hiera ovart = const-vart vname = 'Assembly' matnr = mrs_node_data->matnr werks = mrs_node_data->werks ). DATA(lr_assembly) = build_create_item( is_base_parent = ms_base is_node_target = ls_node ). DATA(lt_stpo) = ir_prodvers->t_stpo-> DATA(lt_plpo) = ir_prodvers->t_plpo-> SORT lt_plpo BY vornr DESCENDING. DATA(lv_first) = lines( lt_plpo ). LOOP AT lt_plpo REFERENCE INTO DATA(lr_plpo). DATA(lv_line) = sy-tabix. do_map_from_plpo( EXPORTING ir_plpo = lr_plpo ir_parent = lr_assembly ir_prodvers = ir_prodvers iv_first_op = xsdbool( lv_line = lv_first ) CHANGING ct_stpo = lt_stpo ). ENDLOOP. ENDMETHOD. * <SIGNATURE>---------------------------------------------------------------------------------------+* | Instance Protected Method /SCT/MT_CL_PRODUCTION_VERSION->DO_MAP_FROM_PLPO* +-------------------------------------------------------------------------------------------------+* | [--->] IR_PLPO TYPE REF TO /SCT/QP_IF_MM_SERVICE=>TY_PLPO* | [--->] IR_PRODVERS TYPE REF TO /SCT/QP_IF_MM_SERVICE=>TY_PRODVERSION(optional)* | [--->] IV_FIRST_OP TYPE BOOLEAN* | [--->] IR_PARENT TYPE REF TO /SCT/QP_S_BASE* | [<-->] CT_STPO TYPE /SCT/QP_IF_MM_SERVICE=>TTY_STPO* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD do_map_from_plpo.*********************************************************************** Erzeugt einen QPPD Knoten passend zum aktuellen Vorgang* und ordnet die passenden Stücklistenkomponente zu********************************************************************** FIELD-SYMBOLS: <field> TYPE any, <value> TYPE any. READ TABLE mt_itembase INTO DATA(ls_data) WITH KEY vtyp = const-operation-vtyp. CHECK sy-subrc = 0. DATA : ls_val LIKE LINE OF ls_data-val. DATA(lt_comp) = mo_tools->get_struct_comp( io_data = ir_plpo ). LOOP AT lt_comp ASSIGNING FIELD-SYMBOL(<comp>). UNASSIGN <field>. ASSIGN COMPONENT <comp>-name OF STRUCTURE ir_plpo->* TO <field>. CHECK <field> IS ASSIGNED AND <field> IS NOT INITIAL. IF <comp>-name = 'VORNR'. ls_data-posnr = CONV #( <field> ). ENDIF. mo_pp_service->map_tablefield_to_element( EXPORTING iv_syncmodel = c_mapping_prodversion iv_tabname = mo_pp_service->c_table-masterdata-operation iv_fieldname = CONV #( <comp>-name ) IMPORTING es_map = DATA(ls_map) ). IF ls_map-element IS NOT INITIAL. CLEAR ls_val. ls_val-element = ls_map-element. IF ls_map-objekttyp IS NOT INITIAL. ls_val-objekttyp = ls_map-objekttyp. ELSE. ls_val-objekttyp = 'OPER_ACTIVITY'. ENDIF. READ TABLE ls_data-val ASSIGNING FIELD-SYMBOL(<val>) WITH KEY element = ls_val-element objekttyp = ls_val-objekttyp. IF sy-subrc NE 0. INSERT ls_val INTO TABLE ls_data-val ASSIGNING <val>. ENDIF. IF <val> IS ASSIGNED. UNASSIGN <value>. ASSIGN COMPONENT ls_map-valfield OF STRUCTURE <val> TO <value>. IF <value> IS ASSIGNED. <value> = CONV #( <field> ). ENDIF. ENDIF. ENDIF. ENDLOOP. LOOP AT ir_prodvers->t_plmz->* REFERENCE INTO DATA(lr_plmz) WHERE plnty = ir_prodvers->plko->plnty AND plnnr = ir_prodvers->plko->plnnr AND plnal = ir_prodvers->plko->plnal AND stlty = ir_prodvers->cstmat->stlty AND stlnr = ir_prodvers->cstmat->stlnr AND stlal = ir_prodvers->cstmat->stlal. READ TABLE ct_stpo REFERENCE INTO DATA(lr_stpo) WITH KEY stlkn = lr_plmz->stlkn. IF sy-subrc = 0. DATA(lv_index) = sy-tabix. do_map_from_stpo( EXPORTING ir_stpo = lr_stpo CHANGING cs_data = ls_data ). DELETE ct_stpo INDEX lv_index. ENDIF. ENDLOOP. IF iv_first_op = abap_true. LOOP AT ct_stpo REFERENCE INTO lr_stpo. do_map_from_stpo( EXPORTING ir_stpo = lr_stpo CHANGING cs_data = ls_data ). ENDLOOP. ENDIF. mo_cust->get_node_hiera_elements( EXPORTING iv_vart = mrs_node_data->vart iv_vtyp = ls_data-vtyp iv_hiera = ls_data-hiera IMPORTING et_element_usage = DATA(lt_usage) DATA(lt_element) = VALUE /sct/qp_th_element( FOR GROUPS OF <wa> IN lt_usage GROUP BY <wa>-element ( <wa>-element ) ). ls_data-val = FILTER #( ls_data-val IN lt_element WHERE element = table_line ). DATA(lr_op) = build_operation( is_itembase = ls_data ir_parent = ir_parent ). ENDMETHOD.* <SIGNATURE>---------------------------------------------------------------------------------------+* | Instance Protected Method /SCT/MT_CL_PRODUCTION_VERSION->DO_MAP_FROM_STPO* +-------------------------------------------------------------------------------------------------+* | [--->] IR_STPO TYPE REF TO /SCT/QP_IF_MM_SERVICE=>TY_STPO* | [<-->] CS_DATA TYPE TY_ITEMBASE* +--------------------------------------------------------------------------------------</SIGNATURE>METHOD do_map_from_stpo.*********************************************************************** Erweitert QPPD Daten zum Vorgang mit den passenden* Stücklistenkomponente********************************************************************** FIELD-SYMBOLS: <field> TYPE any, <value> TYPE any. DATA : ls_val LIKE LINE OF cs_data-val. DATA(lt_comp) = mo_tools->get_struct_comp( io_data = ir_stpo ). DATA(lv_rowgrp) = CONV /sct/qp_rowgrp( ir_stpo->posnr ). LOOP AT lt_comp ASSIGNING FIELD-SYMBOL(<comp>). UNASSIGN <field>. ASSIGN COMPONENT <comp>-name OF STRUCTURE ir_stpo->* TO <field>. CHECK <field> IS ASSIGNED AND <field> IS NOT INITIAL. mo_pp_service->map_tablefield_to_element( EXPORTING iv_syncmodel = c_mapping_prodversion iv_tabname = mo_pp_service->c_table-masterdata-component iv_fieldname = CONV #( <comp>-name ) IMPORTING es_map = DATA(ls_map) ). IF ls_map-element IS NOT INITIAL. CLEAR ls_val. ls_val-element = ls_map-element. IF ls_map-objekttyp IS NOT INITIAL. ls_val-objekttyp = ls_map-objekttyp. ELSE. ls_val-objekttyp = 'COMPONENTS'. ENDIF. ls_val-rowgrp = lv_rowgrp. READ TABLE cs_data-val ASSIGNING FIELD-SYMBOL(<val>) WITH KEY element = ls_val-element objekttyp = ls_val-objekttyp rowgrp = ls_val-rowgrp. IF sy-subrc NE 0. INSERT ls_val INTO TABLE cs_data-val ASSIGNING <val>. <val>-sortnr = ir_stpo->posnr. "Sortierung ENDIF. IF <val> IS ASSIGNED. UNASSIGN <value>. ASSIGN COMPONENT ls_map-valfield OF STRUCTURE <val> TO <value>. IF <value> IS ASSIGNED. <value> = CONV #( <field> ). CASE <comp>-type->get_data_type_kind( <field> ). WHEN cl_abap_typedescr=>typekind_float OR cl_abap_typedescr=>typekind_packed OR cl_abap_typedescr=>typekind_int OR cl_abap_typedescr=>typekind_int2 OR cl_abap_typedescr=>typekind_int8. IF <field> < 0. SHIFT <value> LEFT DELETING LEADING space. DATA(length) = strlen( <value> ) - 1. <value> = '-' && <value>(length). ENDIF. ENDCASE. ENDIF. ENDIF. ENDIF. ENDLOOP. ENDMETHOD.5. Individuelle Bestimmung der Generierungsreihenfolge
Um eine individuelle Generierungsreihenfolge zu ermöglichen wird die globale Generierung aktiviert und im "Zuordnung Objekttypen"-Bild des Vorschriftenarten Customizings "Individuell (VART-Klasse)" gewählt:

mit diesen Einstellungen wird /SCT/QP_IF_VART~SET_GENER_FLAG aufgerufen.
SET_GENER_FLAG
PUBLIC SECTION. METHODS /sct/qp_if_vart~set_gener_flag REDEFINITION .METHOD /sct/qp_if_vart~set_gener_flag. CASE ir_source_base->vtyp.*---------------- ASSEMBLY --------------------------------------------- WHEN 'ASSEMBLY'. IF io_source_object->ms_node_object-objekttyp = 'TECHDATA'. *Mark all operations linked to the assembly rtr_base = /sct/qp_if_vart~get_base_tab( iv_vtyp = 'OPERATION' is_hint = VALUE #( base = ir_source_base children = abap_true ) ). ENDIF.*---------------- OPERATION --------------------------------------------- WHEN 'OPERATION'. DATA(lr_assembly) = zif_qp_prodweg~get_parent( ir_source_base ). IF io_source_object->ms_node_object-objekttyp = 'COMPONENT'. rtr_base = VALUE #( ( lr_assembly ) ). ENDIF. "if it is the last operation mark den next assembly DATA(lr_last_operation) = /sct/qp_if_vart~get_base( is_hint = value #( ir_base = ir_source position = 'LAST' ). IF lr_last_operatioon = ir_source_base. rtr_base = VALUE #( BASE rtr_base ( /sct/qp_if_vart~get_base( is_hint = value #( ir_base = ir_source vtypposition = 'LAST' ). ) ). ENDIF. "Gerierungsreiehnfolge setzen. Beim erneuten Ändern besteht die bereits vom Builder generierte Sortierreihenfolge nicht mehr. ENDCASE.* Sorting for generation beginning at the end LOOP AT rtr_base INTO DATA(rs_base). rs_base->gensort = c_max_gensort - rs_base->posnr. ENDLOOP. ENDMETHOD.