将长文本分割成行宽一致的行(长文本在ScriptForm显示美观整齐)
DATA: l_tline TYPE TABLE OF tline WITH HEADER LINE. DATA: rf_tlinetab TYPE REF TO data. FIELD-SYMBOLS:<l_tab> TYPE STANDARD TABLE,<fs_wa>,<l_dec>. DATA: l_rows TYPE i .
CLEAR: l_tline[]. l_tline-tdline = con_tab-ojtxp.将某个字符串按照每行指定英文字符数分隔成多行,如果是读取的长文本,则直接将长文本内表传递给split_ltx即可 APPEND l_tline.
PERFORM split_ltx TABLES l_tline USING rf_tlinetab 37.ASSIGN rf_tlinetab->* TO <l_tab>.DESCRIBE TABLE <l_tab> LINES l_rows.IF l_rows > 1. LOOP AT <l_tab> ASSIGNING <fs_wa>. ASSIGN COMPONENT 'TDLINE' OF STRUCTURE <fs_wa> TO <l_dec>. ... ENDLOOP.ELSE.
*&---------------------------------------------------------------------**& Form split_ltxt_to_print*&---------------------------------------------------------------------** 将 READ_TEXT 函数读取的长文本按指定的行字符宽度截取成多行,* 以便长文本在ScriptForm显示整齐美观(注:每个中文本将按二个英文进行计算)*----------------------------------------------------------------------** -->P_TLINE READ_TEXT函数返回的 tline 类型内表* -->P_RC_TAB 返回分割好的长文本内表引用
* -->p_linewidth 每行最多可显示的英文字符个数,一个中文会兑换成两个英文*----------------------------------------------------------------------*FORM split_ltxt_for_scrptfrm_outprt TABLES p_tline STRUCTURE tline USING p_rc_tab TYPE REF TO data value(p_linewidth) TYPE i. DATA: rf_strc TYPE REF TO data, rf_tab TYPE REF TO data, rf_elem_typ TYPE REF TO cl_abap_elemdescr, rf_strc_typ TYPE REF TO cl_abap_structdescr, rf_tab_typ TYPE REF TO cl_abap_tabledescr, t_component TYPE cl_abap_structdescr=>component_table WITH HEADER LINE. FIELD-SYMBOLS: <fs_wa> , <fs_tab> TYPE STANDARD TABLE. rf_elem_typ ?= cl_abap_elemdescr=>get_c( p_linewidth ). t_component-name = 'TDLINE'. t_component-type = rf_elem_typ. APPEND t_component. rf_strc_typ = cl_abap_structdescr=>create( t_component[] ). rf_tab_typ = cl_abap_tabledescr=>create( p_line_type = rf_strc_typ p_table_kind = cl_abap_tabledescr=>tablekind_std ). CREATE DATA rf_strc TYPE HANDLE rf_strc_typ. ASSIGN rf_strc->* TO <fs_wa>. CREATE DATA rf_tab TYPE HANDLE rf_tab_typ. ASSIGN rf_tab->* TO <fs_tab>. FIELD-SYMBOLS:<fs_field>. ASSIGN COMPONENT 'TDLINE' OF STRUCTURE <fs_wa> TO <fs_field> . DATA: l_len TYPE i,i_counter TYPE i,l_c,l_cc(4) ,i_start TYPE i, at_fist VALUE 'X',last_blankline,i_off_set TYPE i . FIELD-SYMBOLS: <fs_c> TYPE x. ASSIGN l_c TO <fs_c> CASTING. LOOP AT p_tline . IF ( p_tline-tdformat = '*' AND at_fist <> 'X' ) OR i_counter >= p_linewidth . INSERT <fs_wa> INTO TABLE <fs_tab>. CLEAR:i_off_set ,i_counter, <fs_wa>. ENDIF. l_len = STRLEN( p_tline-tdline ). DO l_len TIMES. IF i_counter >= p_linewidth. INSERT <fs_wa> INTO TABLE <fs_tab>. CLEAR:i_off_set,i_counter, <fs_wa>. ENDIF. i_start = sy-index - 1. l_c = p_tline-tdline+i_start(1). <fs_field>+i_off_set(1) = l_c. i_off_set = i_off_set + 1.*如果我们将0x1234abcd写入到以0x0000开始的内存中,则结果为*big-endian: 0x0000 0x0001 0x0002 0x0003* 0x12 0x34 0xab 0xcd*little-endian: 0x0000 0x0001 0x0002 0x0003* 0xcd 0xab 0x34 0x12*little-endian与人的阅读习惯是反的(阅读习惯:高位放在前,低*位放在后,而little-endian则是将高位放在后,低们放在前,但内*地址是越往后越大,即后面是高字符,靠前的是低字节),但我们在*程序中给一个变量赋值是按照人的阅读习惯来书写的——即认为是高字节序的方式赋值,而在低字节序的系统中,*以little-endian低字节序的字节内容读取出来给l_c变量后,l_c变量内容也是低字节序方式显示存储的,此时将l_c赋值给X类型字段符号<fs_field>时,需要将l_c转换为赋值方式所采用的高字节序方式 IF cl_abap_char_utilities=>endian = 'L'. l_cc = <fs_c>."将十六进制(字符的Unicode码)转换为字面意义上的字符串 SHIFT l_cc BY 2 PLACES CIRCULAR. <fs_c> = l_cc."再将字符转换为十六进制数(字符的Unicode码) ENDIF. IF <fs_c> > 255. i_counter = i_counter + 2. ELSE. i_counter = i_counter + 1. ENDIF. ENDDO. AT LAST. IF l_len = 0 . last_blankline = 'X'. ENDIF. ENDAT. CLEAR at_fist . ENDLOOP. IF i_counter <> 0 OR last_blankline = 'X' . INSERT <fs_wa> INTO TABLE <fs_tab>. CLEAR:i_off_set ,i_counter, <fs_wa>. ENDIF. p_rc_tab = rf_tab.ENDFORM. "split_ltxt_to_print
结构拷贝(拷贝的列名可以不同)
*&---------------------------------------------------------------------**& Form strc_copy*&---------------------------------------------------------------------** 结构拷贝,如果要拷贝的两个字段名不同时使用 SRC_FILEDNAME-DEST_fILEDNAME* 将两个不同的名映射起来,并通过field_maping内表参数进行转递,如果相同,则* 不需要*----------------------------------------------------------------------** -->FIELD_MAPING 不同名称字段映射* -->SRC 源结构* -->DEST 目标结构*----------------------------------------------------------------------*FORM strc_copy TABLES field_maping USING src dest . FIELD-SYMBOLS : <fs_field_src> TYPE x, <fs_field_dest> TYPE x. DATA: field_name_src TYPE string, field_name_dest TYPE string. LOOP AT field_maping. SPLIT field_maping AT '-' INTO field_name_src field_name_dest . ASSIGN COMPONENT field_name_src OF STRUCTURE src TO <fs_field_src> CASTING. ASSIGN COMPONENT field_name_dest OF STRUCTURE dest TO <fs_field_dest> CASTING. <fs_field_dest> = <fs_field_src>.”原汁原味的进行赋值,因为都是X类型,在赋值过程中不会发生类型转换而可能会出现的问题 ENDLOOP. MOVE-CORRESPONDING src TO dest.ENDFORM. " FRM_STRC_COPY
结构不同的两个内表之间进行拷贝
*&---------------------------------------------------------------------**& Form tab_copy*&---------------------------------------------------------------------** 内表拷贝,如果要拷贝的两个字段名不同时使用 SRC_FILEDNAME-DEST_fILEDNAME* 将两个不同的名映射起来,并通过field_maping内表参数进行转递,如果相同,则* 不需要*----------------------------------------------------------------------** -->FIELD_MAPING 不同名称字段映射* -->SRC_TAB 源内表* -->DEST_TAB 目标内表*----------------------------------------------------------------------*FORM tab_copy TABLES field_maping USING src_tab TYPE ANY TABLE dest_tab TYPE ANY TABLE . FIELD-SYMBOLS: <wa_src>, <wa_dest>. FIELD-SYMBOLS: <fs_src_tab> TYPE ANY TABLE. DATA: rf_tabdecr TYPE REF TO cl_abap_tabledescr. DATA: rf_linetype TYPE REF TO cl_abap_structdescr. ASSIGN src_tab TO <fs_src_tab>. rf_tabdecr ?= cl_abap_tabledescr=>describe_by_data( dest_tab ). rf_linetype ?= rf_tabdecr->get_table_line_type( ). DATA: rf_wa_dest_tmp TYPE REF TO data. CREATE DATA rf_wa_dest_tmp TYPE HANDLE rf_linetype. ASSIGN rf_wa_dest_tmp->* TO <wa_dest>. LOOP AT <fs_src_tab> ASSIGNING <wa_src>. PERFORM strc_copy TABLES field_maping USING <wa_src> <wa_dest>. INSERT <wa_dest> INTO TABLE dest_tab. ENDLOOP. "SORT dest_tab . "DELETE ADJACENT DUPLICATES FROM dest_tab.ENDFORM. "frm_tab_copy
将内表中的某一列转换为RANG条件内表
RANGES: r_dispo FOR zkpipp02-dispo. "将内表转换为 Range Internal table PERFORM tab_to_rang TABLES lt_zkpipp02 r_dispo USING 'DISPO'.
*&---------------------------------------------------------------------**& Form tab_to_rang*&---------------------------------------------------------------------** text*----------------------------------------------------------------------** -->SRC_TAB text* -->RANG_TAB text* -->VALUE(FIELDNAME) text*----------------------------------------------------------------------*FORM tab_to_rang TABLES src_tab rang_tab USING value(fieldname) TYPE c. TYPES: BEGIN OF rang_line_type , sign TYPE c LENGTH 1, option TYPE c LENGTH 2 , low LIKE t001-bukrs, high LIKE t001-bukrs, END OF rang_line_type. "动态创建 Range Internal table DATA: rang_elemt_type_ref TYPE REF TO cl_abap_elemdescr, rang_line_type_ref TYPE REF TO cl_abap_structdescr, rang_tab_type_ref TYPE REF TO cl_abap_tabledescr, component_rang_tab TYPE cl_abap_structdescr=>component_table WITH HEADER LINE, src_line_type_ref TYPE REF TO cl_abap_structdescr, src_tab_type_ref TYPE REF TO cl_abap_tabledescr. DATA: rang_strc_ref TYPE REF TO data, rang_tab_ref TYPE REF TO data. FIELD-SYMBOLS: <rang_wa> , <rang_tab> TYPE STANDARD TABLE. component_rang_tab-name = 'SIGN'. rang_elemt_type_ref ?= cl_abap_elemdescr=>get_c( 1 ). component_rang_tab-type = rang_elemt_type_ref. APPEND component_rang_tab. component_rang_tab-name = 'OPTION'. rang_elemt_type_ref ?= cl_abap_elemdescr=>get_c( 2 ). component_rang_tab-type = rang_elemt_type_ref. APPEND component_rang_tab. component_rang_tab-name = 'LOW'. src_tab_type_ref ?= cl_abap_tabledescr=>describe_by_data( src_tab[] ). src_line_type_ref ?= src_tab_type_ref->get_table_line_type( ). component_rang_tab-type = src_line_type_ref->get_component_type( fieldname ). APPEND component_rang_tab. component_rang_tab-name = 'HIGH'. APPEND component_rang_tab. rang_line_type_ref = cl_abap_structdescr=>create( component_rang_tab[] ). rang_tab_type_ref = cl_abap_tabledescr=>create( p_line_type = rang_line_type_ref p_table_kind = cl_abap_tabledescr=>tablekind_std ). CREATE DATA rang_strc_ref TYPE HANDLE rang_line_type_ref. ASSIGN rang_strc_ref->* TO <rang_wa>. CREATE DATA rang_tab_ref TYPE HANDLE rang_tab_type_ref. ASSIGN rang_tab_ref->* TO <rang_tab>.* SORT src_tab BY (fieldname). DATA: src_tab_rows TYPE i. FIELD-SYMBOLS: <src_tab_fld>, <rang_tab_fld>, <src_tab_fld_last>. DATA: curr_i TYPE i VALUE 1, next_i TYPE i. READ TABLE <rang_tab> ASSIGNING <rang_wa> INDEX curr_i. ASSIGN COMPONENT 'SIGN' OF STRUCTURE <rang_wa> TO <rang_tab_fld>. <rang_tab_fld> = 'I'. ASSIGN COMPONENT 'OPTION' OF STRUCTURE <rang_wa> TO <rang_tab_fld>. <rang_tab_fld> = 'EQ'. ASSIGN COMPONENT 'LOW' OF STRUCTURE <rang_wa> TO <rang_tab_fld>. LOOP AT src_tab. ASSIGN COMPONENT fieldname OF STRUCTURE src_tab TO <src_tab_fld>. IF <src_tab_fld> <> <rang_tab_fld>. <rang_tab_fld> = <src_tab_fld>. APPEND <rang_wa> TO <rang_tab>. ENDIF. ENDLOOP. rang_tab[] = <rang_tab>.ENDFORM. "tab_to_rang
通过正则分组,查找所有子匹配串
*&---------------------------------------------------------------------**& Form fin_all_submatch*&---------------------------------------------------------------------** 找出所有的子匹配项(正则式中使用括号括起来的部分)*----------------------------------------------------------------------** -->P_RESULT text* -->P_STR text* -->P_REG text*----------------------------------------------------------------------*FORM find_all_submatch TABLES p_result USING p_str p_reg. DATA: result_tab TYPE match_result_tab WITH HEADER LINE. DATA: subresult_tab TYPE submatch_result_tab WITH HEADER LINE. "注意:带表达时 result_tab 后面一定要带上中括号,否则激活时出现奇怪的问题 FIND ALL OCCURRENCES OF REGEX p_reg IN p_str RESULTS result_tab[]. LOOP AT result_tab .* p_result = p_str+result_tab-offset(result_tab-length).* APPEND p_result. subresult_tab[] = result_tab-submatches. LOOP AT subresult_tab. p_result = p_str+subresult_tab-offset(subresult_tab-length). APPEND p_result. ENDLOOP. ENDLOOP.ENDFORM. "find_all_submatch
读取长文本
*&---------------------------------------------------------------------**& Form read_text*&---------------------------------------------------------------------** 读取长文本,可以自动在中英两种语言间切换,如果指定的语言不存在,* 则自动切换到另一种语言;如果输入的语言为空时,则先会默认使用当前语言,如果没
*有,则也会自动切换到另一种语言*----------------------------------------------------------------------*FORM read_text TABLES lines STRUCTURE tline USING txtid language txtname txtobj. DATA: cnt VALUE 2, l_name TYPE thead-tdname, lang(1). IF language IS INITIAL. lang = syst-langu. ELSE. lang = language. ENDIF. l_name = txtname. WHILE cnt >= 1. CALL FUNCTION 'READ_TEXT' EXPORTING id = txtid language = lang name = l_name object = txtobj TABLES lines = lines EXCEPTIONS id = 1 language = 2 name = 3 not_found = 4 object = 5 reference_check = 6 wrong_access_to_archive = 7 OTHERS = 8. IF sy-subrc = 0. EXIT. ENDIF. CASE lang. WHEN '1'. lang = 'E'. WHEN 'E'. lang = '1'. ENDCASE. cnt = cnt - 1. ENDWHILE.ENDFORM.
读取长方本,并按指定字符长度拼接单个字符串
*&---------------------------------------------------------------------**& Form read_text_bylen*&---------------------------------------------------------------------** 读取长文本(可以自动在中英两种语言间切换,如果指定的语言不存在,* 则自动切换到另一种语言),并将前 MAXLEN 个字符拼接一个字符串。* 该函数主要用在在ALV单元格显示长文本*----------------------------------------------------------------------** -->LINE_SEPARAT 行分隔符* -->MAXLEN 需拼接字符数* -->RETURN 返回的拼接字符串*----------------------------------------------------------------------*FORM read_text_bylen USING txtid language txtname txtobj line_separat maxlen return. DATA: lines TYPE TABLE OF tline , txt_len TYPE i, diff_len TYPE i, tmp_str TYPE string, l_line_separat TYPE string, i_separat_len TYPE i. FIELD-SYMBOLS: <tline> TYPE tline. PERFORM read_text TABLES lines USING txtid language txtname txtobj. LOOP AT lines ASSIGNING <tline> . IF sy-tabix = 1. l_line_separat = ``. ELSE. l_line_separat = line_separat. i_separat_len = i_separat_len + STRLEN( line_separat ). ENDIF. diff_len = maxlen - txt_len. IF diff_len > 132 .”因为TDLINE-TDLINE的最大长度为,每次截取时不能超过这个数,否则越界 diff_len = 132. ENDIF. CONCATENATE tmp_str <tline>-tdline(diff_len) INTO tmp_str SEPARATED BY l_line_separat . txt_len = STRLEN( tmp_str ) - i_separat_len. IF txt_len >= maxlen. EXIT. ENDIF. ENDLOOP. return = tmp_str.ENDFORM.
读取长方本,并按指定行数拼接单个字符串
*&---------------------------------------------------------------------**& Form read_text_byline*&---------------------------------------------------------------------** 读取长文本(可以自动在中英两种语言间切换,如果指定的语言不存在,* 则自动切换到另一种语言),并将前 MAXLINES 行长文本拼接成字符串。* 该函数主要用在在ALV单元格显示长文本*----------------------------------------------------------------------** -->ID text* -->LANGUAGE text* -->NAME text* -->OBJECT text* -->LINE_SEPARAT 行分隔符* -->MAXLINES 要拼接的行数* -->RETURN 返回拼接好的字符串*----------------------------------------------------------------------*FORM read_text_byline USING id language name object line_separat maxlines return. DATA: lines TYPE TABLE OF tline , l_line_separat TYPE string. FIELD-SYMBOLS: <tline> TYPE tline. PERFORM read_text TABLES lines USING id language name object. LOOP AT lines ASSIGNING <tline> . IF sy-tabix = 1. l_line_separat = ``. ELSE. l_line_separat = line_separat. ENDIF. CONCATENATE return <tline>-tdline INTO return SEPARATED BY l_line_separat . IF sy-tabix = maxlines. EXIT. ENDIF. ENDLOOP.ENDFORM. "read_text_byline
将含有数字类型字段内表转化为可写入到服务器文本文件的内表
data: begin of lt_tab occurs 0, content(300), end of lt_tab . perform itab_to_exceltab tables t_div lt_tab.
form itab_to_exceltab tables p_src_tab p_excel_tab. data:strct_type_ref type ref to cl_abap_structdescr, tab_type_ref type ref to cl_abap_tabledescr, t_component type cl_abap_structdescr=>component_table, wa_component like line of t_component. field-symbols: <fldvalue>. data: begin of t_fldinfo occurs 0, fldname type string, fldtype, end of t_fldinfo, begin of lt_tab occurs 0, content(300), end of lt_tab . data :l_str type string,fldtype,firsttime value 'X'. tab_type_ref ?= cl_abap_tabledescr=>describe_by_data( p_src_tab[] ). strct_type_ref ?= tab_type_ref->get_table_line_type( ). t_component = strct_type_ref->get_components( ). loop at p_src_tab. firsttime = 'X'. loop at t_component into wa_component. fldtype = wa_component-type->type_kind. assign component wa_component-name of structure p_src_tab to <fldvalue>. l_str = <fldvalue>. if fldtype = 'P' or fldtype = 'F' or fldtype = 'I' or fldtype = 'b' or fldtype = 's'. call function 'CLOI_PUT_SIGN_IN_FRONT' changing value = l_str. endif. if firsttime = 'X'. lt_tab-content = l_str . clear firsttime. else. concatenate lt_tab-content l_str into lt_tab-content separated by cl_abap_char_utilities=>horizontal_tab . endif. endloop. append lt_tab. clear: lt_tab. endloop. p_excel_tab[] = lt_tab[].endform.
上面的程序是将内表转换为可以直接写入到服务器上文件的字符串,如果是要将内表下载到客户端,则只需要使用GUI_DOWNLOAD就可以直接做到,这与将内表写入服务器上是不一样的。GUI_DOWNLOAD可以将内表中的任何类型组件字段转换为字符类型后下载,并且以 DAT 模式下载时(此时以TAB键分隔),还可直接由Excel打开:
call function 'GUI_DOWNLOAD' exporting filename = l_filename filetype = 'DAT' 使用TAB键分隔 codepage = '8400' tables data_tab = itab
上面Form程序就是模拟GUI_DOWNLOAD,将内表转换为可以直接使用open dataset l_file for output IN TEXT MODE语句写入文件的纯字符内表,因为如果内表中包数字类型的字段时,如果不经过转换,在以IN TEXT MODE模式写入时,会出现乱码。
该程序就是用在将内表写入SAP服务器上的文件中,再上传到FTP上,在这过程中如果不经过这样的转换就会出现乱码