因为用户不用GUI客户端,不能用SQVI和query,有时候需要查询某些关联表的时候就有点麻烦。
所以就想着做一个可以配置的报表,把查询字段和结果字段已经关联条件全部配置起来,这样用户要是突发奇想要查点东西,只要简单配置下就可以了。
1,新建配置表:可根据用户配置对应的组件(用户,组件,组件描述,查询from表和关联关系配置)

2,组件配置表:根据组件,查询/结果条件,字段,字段类型,描述,表字段,查询的表,位置(可以根据S/R区分查询条件和结果字段,根据字段类型动态创建查询和结果结构和表,根据表字段,动态构建查询结果字段)

两个配置表可以动态分配程序到用户,动态构建查询和结果,动态展示
3,新建WEB DYNPRO程序:ZCRM_DYNAMIC_REPORT
组件里添加ALV和SELECTION的组件

4,组件控制器Component Controller中做动态ALV初始化(也可以在用户选择下拉报表的时候初始化)
METHOD wddoinit . DATA lo_cmp_usage TYPE REF TO if_wd_component_usage. lo_cmp_usage = wd_this->wd_cpuse_dynmaic_alv( ). IF lo_cmp_usage->has_active_component( ) IS INITIAL. lo_cmp_usage->create_component( ). ENDIF. ENDMETHOD.
3,1 在MAIN视图中,我们新建一个node节点,做拉下用,下拉列表里展示当前登录用户可以选择的报表
参照上面的配置表1就可以了

2添加一个查询 ViewContainerUIElement (SELECT)
3添加一个结果展示的 ViewContainerUIElement (ALV)
4,init中初始化拉下程序列表(init_drop 根据用户取配置表报表)
METHOD wddoinit . init_drop( ). init_select( ). ENDMETHOD.
METHOD init_drop . DATA: lt_value_set TYPE TABLE OF wdy_key_value, ls_value_set TYPE wdy_key_value. DATA:lr_node_info TYPE REF TO if_wd_context_node_info. lr_node_info = wd_context->get_node_info( ). lr_node_info = lr_node_info->get_child_node( `ZCRMT0209` ). SELECT component_name AS key text AS value INTO TABLE lt_value_set FROM zcrmt0209 WHERE uname = sy-uname. lr_node_info->set_attribute_value_set( name = `COMPONENT_NAME` value_set = lt_value_set ). ENDMETHOD.
METHOD init_select . **初始化select option组件 DATA: lr_componentcontroller TYPE REF TO ig_componentcontroller, l_ref_cmp_usage TYPE REF TO if_wd_component_usage. DATA: display_btn_cancel TYPE abap_bool, display_btn_check TYPE abap_bool, display_btn_reset TYPE abap_bool, display_btn_execute TYPE abap_bool. * create the used component l_ref_cmp_usage = wd_this->wd_cpuse_selection( ). IF l_ref_cmp_usage->has_active_component( ) IS INITIAL. l_ref_cmp_usage->create_component( ). ENDIF. * get a pointer to the interface controller of the select options *component wd_this->m_wd_select_options = wd_this->wd_cpifc_selection( ). * init the select screen wd_this->m_handler = wd_this->m_wd_select_options->init_selection_screen( ). * adjust the global options wd_this->m_handler->set_global_options( i_display_btn_cancel = display_btn_cancel i_display_btn_check = display_btn_check i_display_btn_reset = display_btn_reset i_display_btn_execute = display_btn_execute ). ENDMETHOD.
5,根据下拉列表初始化选择条件和alv
METHOD onactionselect_comp . DATA lo_nd_zcrmt0209 TYPE REF TO if_wd_context_node. DATA lo_el_zcrmt0209 TYPE REF TO if_wd_context_element. DATA ls_zcrmt0209 TYPE wd_this->element_zcrmt0209. * navigate from <CONTEXT> to <ZCRMT0209> via lead selection lo_nd_zcrmt0209 = wd_context->get_child_node( name = wd_this->wdctx_zcrmt0209 ). * get element via lead selection lo_el_zcrmt0209 = lo_nd_zcrmt0209->get_element( ). * get all declared attributes lo_el_zcrmt0209->get_static_attributes( IMPORTING static_attributes = ls_zcrmt0209 ). CHECK ls_zcrmt0209-component_name IS NOT INITIAL. **初始化select和alv add_select( ls_zcrmt0209-component_name ). init_alv( ls_zcrmt0209-component_name ). **控制查询清空按钮显示 DATA lo_el_context TYPE REF TO if_wd_context_element. DATA ls_context TYPE wd_this->element_context. DATA lv_bt_vis TYPE wd_this->element_context-bt_vis. * get element via lead selection lo_el_context = wd_context->get_element( ). * @TODO fill attribute lv_bt_vis = 'X'. * set single attribute lo_el_context->set_attribute( name = `BT_VIS` value = lv_bt_vis ). ENDMETHOD.
METHOD add_select . DATA:gt_zcrmt0209s TYPE TABLE OF zcrmt0209s, gw_zcrmt0209s LIKE LINE OF gt_zcrmt0209s. DATA: lt_range_table TYPE REF TO data, rt_range_table TYPE REF TO data, read_only TYPE abap_bool, typename TYPE string, id TYPE string, desc TYPE string. wd_this->m_handler->remove_all_sel_screen_items( ). **根据选择的组件从配置表中带出查询条件并添加到select option中 SELECT * INTO TABLE gt_zcrmt0209s FROM zcrmt0209s WHERE component_name = component_name AND zusage = 'S'. CHECK gt_zcrmt0209s[] IS NOT INITIAL. LOOP AT gt_zcrmt0209s INTO gw_zcrmt0209s. typename = gw_zcrmt0209s-field_type. id = gw_zcrmt0209s-field. desc = gw_zcrmt0209s-text. * create a range table that consists of this new data element lt_range_table = wd_this->m_handler->create_range_table( i_typename = typename ). * add a new field to the selection wd_this->m_handler->add_selection_field( i_id = id i_description = desc it_result = lt_range_table i_read_only = read_only ). ENDLOOP. ENDMETHOD.
根据配置表初始化alv字段结构并绑定到alv
METHOD init_alv . DATA:lt_child_node TYPE wdr_context_child_info_map, ls_child_node TYPE wdr_context_child_info. DATA:lv_name TYPE string. DATA:gt_zcrmt0209s TYPE TABLE OF zcrmt0209s, gw_zcrmt0209s LIKE LINE OF gt_zcrmt0209s. DATA: ls_comp TYPE LINE OF cl_abap_structdescr=>component_table, lt_comp TYPE cl_abap_structdescr=>component_table, ls_fieldcat TYPE LINE OF lvc_t_fcat, struct_type TYPE REF TO cl_abap_structdescr. lt_child_node = wd_context->get_node_info( )->get_child_nodes( ). **取配置表的结果R字段,构建动态的节点,节点名就用报表名 SELECT * INTO TABLE gt_zcrmt0209s FROM zcrmt0209s WHERE component_name = component_name AND zusage = 'R'. LOOP AT gt_zcrmt0209s INTO gw_zcrmt0209s. ls_comp-name = gw_zcrmt0209s-field. ls_comp-type ?= cl_abap_typedescr=>describe_by_name( gw_zcrmt0209s-field_type ). APPEND ls_comp TO lt_comp. ENDLOOP. * Create structure defined in lt_comp struct_type = cl_abap_structdescr=>create( lt_comp ). lv_name = component_name. READ TABLE lt_child_node INTO ls_child_node WITH KEY name = lv_name. IF sy-subrc = 0. ELSE. * Append dynamic node with name ( ) wd_context->get_node_info( )->add_new_child_node( name = lv_name is_mandatory = abap_true is_multiple = abap_true static_element_rtti = struct_type is_static = abap_false ). ENDIF. **Step 4: Assign this context to ALV DATA lo_interfacecontroller TYPE REF TO iwci_salv_wd_table . lo_interfacecontroller = wd_this->wd_cpifc_dynmaic_alv( ). lo_interfacecontroller->set_data( * only_if_new_descr = " wdy_boolean r_node_data = wd_context->get_child_node( lv_name ) " ref to if_wd_context_node ). **以下是根据配置表控制alv显示的,暂时用默认也可以,先不用 * DATA:gt_zcrmt0209s TYPE TABLE OF zcrmt0209s, * gw_zcrmt0209s LIKE LINE OF gt_zcrmt0209s. * DATA: lr_comp_alv TYPE REF TO if_wd_component_usage, * lr_comp_if_alv TYPE REF TO iwci_salv_wd_table. * DATA: lr_column_settings TYPE REF TO if_salv_wd_column_settings, * lr_column TYPE REF TO cl_salv_wd_column, * lr_column_header TYPE REF TO cl_salv_wd_column_header. * DATA:gv_string TYPE string. * * DATA: lt_column TYPE salv_wd_t_column_ref, * ls_column TYPE salv_wd_s_column_ref. * *****"定义特殊格式的类型 * DATA: lr_input_field TYPE REF TO cl_salv_wd_uie_input_field, * lr_checkbox TYPE REF TO cl_salv_wd_uie_checkbox, * lr_link TYPE REF TO cl_salv_wd_uie_link_to_action, * lr_drop TYPE REF TO cl_salv_wd_uie_dropdown_by_key. * DATA lr_column_id TYPE string. * * * CHECK gt_zcrmt0209s[] IS NOT INITIAL. * * * * * "创建组件/实例化组件 * lr_comp_alv = wd_this->wd_cpuse_dynmaic_alv( ) . * IF lr_comp_alv->has_active_component( ) IS INITIAL. * lr_comp_alv->create_component( ). * ENDIF. * * * DATA lr_config TYPE REF TO cl_salv_wd_config_table. * DATA:lr_func_config TYPE REF TO cl_salv_wd_config_table. * "获取ALV对象的设置对象 * lr_comp_if_alv = wd_this->wd_cpifc_dynmaic_alv( ). * lr_config = lr_comp_if_alv->get_model( ). * lr_func_config = lr_comp_if_alv->get_model( ). * * lr_column_settings ?= lr_config . * lt_column = lr_column_settings->get_columns( )."获取ALV字段 * "取配置表数据 * **========================================================= * * DATA: l_value TYPE REF TO cl_salv_wd_config_table. * * l_value = lr_comp_if_alv->get_model( ). * l_value->if_salv_wd_table_settings~set_fixed_table_layout( abap_false ). "使列宽不可自动调节 * l_value->if_salv_wd_table_settings~set_width( '100%' ) . "设置宽度 * l_value->if_salv_wd_table_settings~set_visible_row_count( '15' ). "显示的行数 * l_value->if_salv_wd_table_settings~set_scrollable_col_count( '10' )."设置滚动条行数 * l_value->if_salv_wd_table_settings~set_read_only( abap_false )."设置只读 * l_value->if_salv_wd_table_settings~set_display_empty_rows( abap_false )."设置空表也显示alv行 * l_value->if_salv_wd_table_settings~set_selection_mode( cl_wd_table=>e_selection_mode-multi_no_lead )."多选无lead * l_value->if_salv_wd_function_settings~set_enabled( abap_true ) ."功能 * l_value->if_salv_wd_std_functions~set_edit_check_available( abap_false ) . * l_value->if_salv_wd_std_functions~set_edit_insert_row_allowed( abap_false ) . * l_value->if_salv_wd_std_functions~set_export_allowed( abap_true ) ."可excel导出 ** l_value->if_salv_wd_std_functions~set_view_list_allowed( abap_false ). * l_value->if_salv_wd_std_functions~set_pdf_allowed( abap_false ) ."可pdf导出 * l_value->if_salv_wd_std_functions~set_edit_append_row_allowed( abap_false ) . * l_value->if_salv_wd_std_functions~set_edit_delete_row_allowed( abap_false ) . * l_value->if_salv_wd_std_functions~set_filter_filterline_allowed( abap_true ). * l_value->if_salv_wd_std_functions~set_filter_complex_allowed( abap_true )."多字段筛选 ** l_value->if_salv_wd_std_functions~set_dialog_settings_allowed( abap_true ). * * DATA: lr_table_settings TYPE REF TO if_salv_wd_table_settings. * lr_table_settings ?= l_value. * lr_table_settings->set_data_check( '01' ). * lr_table_settings->set_read_only( abap_false ). * * LOOP AT lt_column INTO ls_column. * lr_column_id = ls_column-id. * lr_column = ls_column-r_column. * * lr_column->set_resizable( value = 'X' ). * lr_column->set_width( value = '100' ). * * READ TABLE gt_zcrmt0209s INTO gw_zcrmt0209s WITH KEY field = ls_column-id. * IF sy-subrc = 0. ** IF gw_zcrmt0209s-visiable = 'X'. * lr_column_header = ls_column-r_column->create_header( ). ** ls_column-r_column->set_position( gw_ZCRMT0209S-posit ). * CASE gw_zcrmt0209s-field. * WHEN 'SEL'. * CREATE OBJECT lr_checkbox * EXPORTING * checked_fieldname = ls_column-id. * ls_column-r_column->set_cell_editor( lr_checkbox ). * WHEN 'ZZCON_TYPE'. * CREATE OBJECT lr_drop * EXPORTING * selected_key_fieldname = ls_column-id. * * lr_drop->set_read_only_fieldname( value = ls_column-id ). * * ls_column-r_column->set_cell_editor( lr_drop ). * WHEN 'CTYPE'. * CREATE OBJECT lr_drop * EXPORTING * selected_key_fieldname = ls_column-id. ** lr_drop->set_read_only_fieldname( value = ls_column-id ). * ls_column-r_column->set_cell_editor( lr_drop ). * WHEN 'OBJECT_ID'. * CREATE OBJECT lr_link. * lr_link->set_text_fieldname( ls_column-id ). * ls_column-r_column->set_cell_editor( lr_link ). * WHEN 'E'. * WHEN 'F'. * WHEN OTHERS. * ENDCASE. * IF gw_zcrmt0209s-text CS 'CRM/'."otr text使用特定格式的 * gv_string = gw_zcrmt0209s-text. * lr_column_header->set_text( zcl_otr=>get_text( gv_string ) ). * ELSE. * IF gw_zcrmt0209s-text IS NOT INITIAL. * gv_string = gw_zcrmt0209s-text. * lr_column_header->set_text( gv_string ). * ENDIF. * ENDIF. ** ELSE. ** ls_column-r_column->set_position( gw_zcrmt0209s-posit ). ** lr_column = lr_column_settings->get_column( ls_column-id ). ** lr_column->set_visible( if_wdl_core=>visibility_none ). ** ENDIF. * ELSE. ** ls_column-r_column->set_position( gw_zcrmt0209s-posit ). * lr_column = lr_column_settings->get_column( ls_column-id ). * lr_column->set_visible( if_wdl_core=>visibility_none ). * ENDIF. * ENDLOOP. ENDMETHOD.
6,查询处理,动态构建内表并展示
METHOD onactionsearch . DATA:gt_zcrmt0209s TYPE TABLE OF zcrmt0209s, gw_zcrmt0209s LIKE LINE OF gt_zcrmt0209s, gw_zcrmt0209 TYPE zcrmt0209. DATA lo_nd_zcrmt0209 TYPE REF TO if_wd_context_node. DATA lo_el_zcrmt0209 TYPE REF TO if_wd_context_element. DATA ls_zcrmt0209 TYPE wd_this->element_zcrmt0209. DATA: rt_object_id TYPE REF TO data, lt_where TYPE rsds_where_tab, lt_from TYPE rsds_where_tab, lt_sql TYPE rsds_where_tab, lv_s TYPE string, lv_n TYPE n LENGTH 2, lv_line(70) TYPE c. DATA: dy_table TYPE REF TO data, ifc TYPE lvc_t_fcat. FIELD-SYMBOLS: <fs01> TYPE table, <fs02> TYPE table, <fs03> TYPE table, <fs04> TYPE table, <fs05> TYPE table, <fs06> TYPE table, <fs07> TYPE table, <fs08> TYPE table, <fs09> TYPE table, <fs10> TYPE table. FIELD-SYMBOLS : <table> TYPE ANY TABLE. DATA:lr_node TYPE REF TO if_wd_context_node. * navigate from <CONTEXT> to <ZCRMT0209> via lead selection lo_nd_zcrmt0209 = wd_context->get_child_node( name = wd_this->wdctx_zcrmt0209 ). * get element via lead selection lo_el_zcrmt0209 = lo_nd_zcrmt0209->get_element( ). * get all declared attributes lo_el_zcrmt0209->get_static_attributes( IMPORTING static_attributes = ls_zcrmt0209 ). "根据配置表查询条件获得查询参数,限制10个条件 SELECT * INTO TABLE gt_zcrmt0209s FROM zcrmt0209s WHERE component_name = ls_zcrmt0209-component_name AND zusage = 'S'. LOOP AT gt_zcrmt0209s INTO gw_zcrmt0209s. CLEAR:lv_line,lv_s. lv_n = sy-tabix. lv_s = gw_zcrmt0209s-field. rt_object_id = wd_this->m_handler->get_range_table_of_sel_field( i_id = lv_s ). CASE lv_n. WHEN '01'. ASSIGN rt_object_id->* TO <fs01>. IF <fs01>[] IS INITIAL. CONTINUE. ENDIF. WHEN '02'. ASSIGN rt_object_id->* TO <fs02>. IF <fs02>[] IS INITIAL. CONTINUE. ENDIF. WHEN '03'. ASSIGN rt_object_id->* TO <fs03>. IF <fs03>[] IS INITIAL. CONTINUE. ENDIF. WHEN '04'. ASSIGN rt_object_id->* TO <fs04>. IF <fs04>[] IS INITIAL. CONTINUE. ENDIF. WHEN '05'. ASSIGN rt_object_id->* TO <fs05>. IF <fs05>[] IS INITIAL. CONTINUE. ENDIF. WHEN '06'. ASSIGN rt_object_id->* TO <fs06>. IF <fs06>[] IS INITIAL. CONTINUE. ENDIF. WHEN '07'. ASSIGN rt_object_id->* TO <fs07>. IF <fs07>[] IS INITIAL. CONTINUE. ENDIF. WHEN '08'. ASSIGN rt_object_id->* TO <fs08>. IF <fs08>[] IS INITIAL. CONTINUE. ENDIF. WHEN '09'. ASSIGN rt_object_id->* TO <fs09>. IF <fs09>[] IS INITIAL. CONTINUE. ENDIF. WHEN '10'. ASSIGN rt_object_id->* TO <fs10>. IF <fs10>[] IS INITIAL. CONTINUE. ENDIF. WHEN OTHERS. ENDCASE. "动态查询条件,第二次拼接需要添加and CONCATENATE '<fs' lv_n '>' INTO lv_line. IF lt_where[] IS INITIAL. CONCATENATE gw_zcrmt0209s-name_on_db 'IN' lv_line INTO lv_line SEPARATED BY space. ELSE. CONCATENATE 'AND' gw_zcrmt0209s-name_on_db 'IN' lv_line INTO lv_line SEPARATED BY space. ENDIF. APPEND lv_line TO lt_where. ENDLOOP. CHECK lt_where[] IS NOT INITIAL. DATA:lv_name TYPE string. SELECT name_on_db INTO TABLE lt_sql FROM zcrmt0209s WHERE component_name = ls_zcrmt0209-component_name AND zusage = 'R'. "根据配置字段属性,构建动态内表 SELECT dd03l~fieldname dd03l~inttype dd03l~leng AS intlen dd03l~decimals INTO CORRESPONDING FIELDS OF TABLE ifc FROM dd03l INNER JOIN zcrmt0209s ON zcrmt0209s~field = dd03l~fieldname AND zcrmt0209s~dbtabname = dd03l~tabname WHERE zcrmt0209s~component_name = ls_zcrmt0209-component_name AND zusage = 'R'. CALL METHOD cl_alv_table_create=>create_dynamic_table EXPORTING it_fieldcatalog = ifc IMPORTING ep_table = dy_table. ASSIGN dy_table->* TO <table>. **另一种动态构建内表的方法 * DATA: ls_comp TYPE LINE OF cl_abap_structdescr=>component_table, * lt_comp TYPE cl_abap_structdescr=>component_table, * ls_fieldcat TYPE LINE OF lvc_t_fcat, * struct_type TYPE REF TO cl_abap_structdescr. * SELECT * INTO TABLE gt_zcrmt0209s FROM zcrmt0209s WHERE component_name = ls_zcrmt0209-component_name AND zusage = 'R'. * LOOP AT gt_zcrmt0209s INTO gw_zcrmt0209s. * ls_comp-name = gw_zcrmt0209s-field. * ls_comp-type ?= cl_abap_typedescr=>describe_by_name( gw_zcrmt0209s-field_type ). * APPEND ls_comp TO lt_comp. * ENDLOOP. * ** Create structure defined in lt_comp * struct_type = cl_abap_structdescr=>create( lt_comp ). * DATA p_result TYPE REF TO cl_abap_tabledescr. * * p_result = cl_abap_tabledescr=>create( * p_line_type = CAST #( struct_type ) * p_table_kind = cl_abap_tabledescr=>tablekind_std ). * DATA: table TYPE REF TO data. * CREATE DATA table TYPE HANDLE p_result. * ASSIGN table->* TO <table>. "查询表连接处理 SELECT SINGLE * INTO gw_zcrmt0209 FROM zcrmt0209 WHERE uname = sy-uname AND component_name = ls_zcrmt0209-component_name. CHECK gw_zcrmt0209-fromcond IS NOT INITIAL. SPLIT gw_zcrmt0209-fromcond AT '/' INTO TABLE lt_from. "动态查询 SELECT (lt_sql) INTO CORRESPONDING FIELDS OF TABLE <table> FROM (lt_from) WHERE (lt_where). lv_name = ls_zcrmt0209-component_name. "绑定结果到node显示 lr_node = wd_context->get_child_node( name = lv_name ). lr_node->bind_table( new_items = <table> set_initial_elements = abap_true ). ENDMETHOD.
效果展示:
配置数据:



    ^_^很多人都把资料锁进了note里,以后还怎么百度呢^_^
 
                    
                     
                    
                 
                    
                 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号