se16n,只能用来查一张表的数据
每每想到以前用的查询分析器或者各种Console就忍不住想吐槽
刚开始接触abap的时候就想自己写一个查询分析器
这两天周六周日上班,不想干活…
尝试着开始写这个东西
趁放假前把写好的东西放出来吧
实现了简单的查询 及 连接查询 (增删改暂时不支持,可以考虑根据关键字进行操作的分类,应该也是类似的)
(个人估计 五一后也没这么多精力来做这种东西了 这是第一个版本 也是最后一个版本了
虽然写的有点挫 部分代码都是copy过来后都没怎么改 所以比较凌乱 但单大致思路应该还是可以的)
主要使用的技术:
1. “自省”结构体: 主要是某个表结构的所有字段
2. 动态内表
3. 动态程序
现在的程序有个BUG:
P类型数据, 采用的技术手段获取字段信息不准确
例如 domain中定义的是 length 13 decimals 3 但是现在获取的是 length 7 decimals 2
导致select数据在添加到动态内表时,由于结构不一致,导致异常…
效果截图:
a.查询语句:
b.结果:
附:代码
REPORT Z_QUERY_PARSER. type-pools: esp1,abap . tables: mara. data: gt_message type ESP1_MESSAGE_TAB_TYPE with header line. data: gt_sql LIKE abapsource OCCURS 0 WITH HEADER LINE. *每个筛选字段 例如:mara~matnr types: begin of field_value, value(20), end of field_value. data: gt_field type field_value occurs 0 with header line. data: gt_component type field_value occurs 0 with header line. data: gt_tabname type field_value occurs 0 with header line. perform call_query_panel. perform spliter. perform create_dyn_pro. form call_query_panel. CALL FUNCTION 'EDITOR_APPLICATION' EXPORTING application = 'BF' display = ' ' name = 'Query Panel' * IMPORTING * fcode = fcode * changed = changed TABLES content = gt_sql[]. endform. form spliter. data: l_query type string. data: l_field(10),l_tabname1(10),l_tabname2(10). loop at gt_sql. concatenate l_query gt_sql into l_query separated by space. endloop. condense l_query. translate l_query to upper case. split l_query at space into table gt_field. endform. form create_dyn_pro. DATA: l_prog TYPE string, l_code TYPE STANDARD TABLE OF string with header line, l_mess TYPE string, l_sid TYPE string. data: l_query_string type string. data: l_state(1),lt_temp type standard table of string with header line. field-symbols: <dyn_field> type any, <comp_wa> TYPE abap_compdescr . data: ref_wa type ref to data, descr_ref TYPE REF TO cl_abap_structdescr. data: lt_compdes type abap_compdescr occurs 0 with header line. *1.确定筛选的字段 loop at gt_field. if gt_field-value = 'SELECT'. continue. endif. if gt_field-value = 'FROM'. EXIT. endif. gt_component-value = gt_field-value. if gt_component-value cs '~'. clear lt_temp[]. split gt_component-value at '~' into table lt_temp. read table lt_temp index 2. gt_component-value = lt_temp. endif. append gt_component.clear gt_component. endloop. *2.涉及的tables loop at gt_field. if gt_field-value = 'FROM' or gt_field-value = 'JOIN'. l_state = 'X'. continue. endif. if l_state = 'X'. gt_tabname-value = gt_field-value. append gt_tabname.clear gt_tabname. l_state = ''. endif. endloop. write / '===================================='. write / 'Components:'. write / ''. loop at gt_component. write gt_component-value. endloop. write / '===================================='. write / 'Tables:'. loop at gt_tabname. write / gt_tabname-value. endloop. write / '===================================='. write / 'Results:'. append 'PROGRAM subpool.' TO l_code. *定义数据表 loop at gt_tabname. concatenate 'tables:' gt_tabname '.' into l_code. append l_code. endloop. *添加动态数据的定义 append `field-symbols: <dyn_table> type standard table ,` & `<dyn_wa> type any,` & `<dyn_field> type any.` to l_code. append `data: dy_table type ref to data, ` & ` wa_line type ref to data. ` to l_code. append `data: it_structure type lvc_t_fcat,` & `wa_structure type lvc_s_fcat.` to l_code. loop at gt_tabname. *根据涉及的数据表结构 动态构造存放结果的内表 create data ref_wa type (gt_tabname-value). assign ref_wa->* to <dyn_field>. descr_ref ?= cl_abap_typedescr=>describe_by_data( <dyn_field> ). LOOP AT descr_ref->components ASSIGNING <comp_wa>. append <comp_wa> to lt_compdes. ENDLOOP. endloop. *删除重复字段 防止异常 sort lt_compdes by name . delete adjacent duplicates from lt_compdes. append 'form dyn_form.' to l_code. *加入创建动态内表的code data l_temp(3) type n. loop at lt_compdes. concatenate `wa_structure-fieldname = '` lt_compdes-name `'.` into l_code separated by space. append l_code. concatenate `wa_structure-inttype = '` lt_compdes-type_kind `'.` into l_code separated by space. append l_code. l_temp = lt_compdes-length. concatenate `wa_structure-intlen = '` l_temp `'.` into l_code separated by space. append l_code. l_temp = lt_compdes-decimals. concatenate `wa_structure-decimals_o = '` l_temp `'.` into l_code separated by space. append l_code. append `append wa_structure to it_structure.` to l_code. endloop. append `CALL METHOD cl_alv_table_create=>create_dynamic_table ` & ` EXPORTING ` & ` it_fieldcatalog = it_structure ` & ` IMPORTING ` & ` ep_table = dy_table . ` to l_code. append ` assign dy_table->* to <dyn_table>.` to l_code. append ` create data wa_line like line of <dyn_table>. ` to l_code. append ` assign wa_line->* to <dyn_wa>. ` to l_code. loop at gt_field. if gt_field-value = 'WHERE'. concatenate l_query_string 'into corresponding fields of table <dyn_table>' 'where' into l_query_string separated by space. else. concatenate l_query_string gt_field-value into l_query_string separated by space. endif. endloop. append '.' to l_code. append l_query_string to l_code. append `loop at <dyn_table> assigning <dyn_wa>.` to l_code. append `write / ''.` to l_code. loop at gt_component. concatenate `'` gt_component-value `'` into gt_component-value. concatenate 'assign component' gt_component-value 'of structure <dyn_wa> to <dyn_field>.' into l_code separated by space. append l_code. append `write <dyn_field>.` to l_code. endloop. append `endloop.` to l_code. append 'endform.' to l_code. GENERATE SUBROUTINE POOL l_code NAME l_prog MESSAGE l_mess SHORTDUMP-ID l_sid. IF sy-subrc = 0. PERFORM ('DYN_FORM') IN PROGRAM (l_prog) IF FOUND. ELSEIF sy-subrc = 4. MESSAGE l_mess TYPE 'I'. ELSEIF sy-subrc = 8. MESSAGE l_sid TYPE 'I'. ENDIF. endform.


浙公网安备 33010602011771号