REPORT Z_ABAP_24_CHAR_ASCII_TXN.
PARAMETERS: P_CHAR TYPE C DEFAULT 'A'.
PARAMETERS: P_ASC TYPE I DEFAULT '66'.
START-OF-SELECTION.
"CHAR TO ASCII
FIELD-SYMBOLS : <conver_fs> type x.
DATA: asc TYPE i.
ASSIGN p_char TO <conver_fs> CASTING.
MOVE <conver_fs> TO asc.
WRITE asc.
NEW-LINE.
"ASCII TO CHAR
DATA: l_char TYPE c.
DATA: i_hex TYPE x.
DATA: class_convert TYPE REF TO cl_abap_conv_in_ce.
i_hex = p_asc.
class_convert = cl_abap_conv_in_ce=>create( encoding = 'UTF-8' ).
class_convert->convert( EXPORTING input = i_hex
IMPORTING data = l_char ).
WRITE l_char.
END-OF-SELECTION.
CHAR -> ASCII 透過 field-symble X type 把 char 轉成 16 進為,再把 16 進位轉入 10 進位
ASCII -> CHAR 則是透過 class cl_abap_conv_in_ce 將 16 進位直接轉入 Char
產生的結果
============================================================
進階範例 - 編碼 0~9 A~Z 的累加,並可以跳過特定字元
[CUATION] follow sample code is not support little endian environment (A 的 16 進制在 big endian 是 0041,但是在 little endian 則變 4100,如果 0041 + 1 => 0042 ascii 轉 char 為 B,但在 4100 + 1 => 4101 並不是 B,下面程式並沒有做 Big Endian / Little Endian 轉換的功能)
SAMPLE CODE :
FUNCTION Z_SEQ_0_Z.
*"----------------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" VALUE(I_SEQ) TYPE STRING DEFAULT ''
*" VALUE(I_SKIP_CHAR) TYPE STRING DEFAULT ''
*" VALUE(I_LEN) TYPE INT2 OPTIONAL
*" VALUE(I_START_FROM_0) TYPE CHAR01 OPTIONAL
*" EXPORTING
*" VALUE(E_ERRORCODE) TYPE CHAR01
*" VALUE(E_ERRORDESC) TYPE TEXT256
*" VALUE(E_SEQ) TYPE STRING
*"----------------------------------------------------------------------
DATA: BEGIN OF itab_seq OCCURS 0,
seq TYPE i,
chr TYPE c,
asc TYPE i,
hex TYPE x,
END OF itab_seq.
DATA: i_num TYPE i.
RANGES: r_skip_char FOR itab_seq-chr.
DATA: l_last TYPE c.
DATA: l_len TYPE i,
l_len_flag TYPE i,
l_len_char TYPE c.
DATA: itab_seq_flag TYPE i.
DATA: l_num_char(20) TYPE c.
DATA: l_num(256) TYPE n.
DATA: l_carry TYPE c.
DATA: class_convert TYPE REF TO cl_abap_conv_in_ce.
DATA: i_hex TYPE x.
DATA: l_char TYPE c.
CLEAR: e_errorcode, e_errordesc, e_seq.
"把 i_seq = '0000000' 換成 0
IF i_seq CO '0'.
i_seq = '0'.
ENDIF.
l_len = strlen( i_seq ).
IF l_len > i_len.
e_errorcode = 'F'.
e_errordesc = 'i_len 序號長度小於目前傳入 i_seq 的長度'.
EXIT.
ENDIF.
CLEAR: r_skip_char, r_skip_char[].
l_len = strlen( i_skip_char ).
l_len_flag = l_len.
DO l_len TIMES.
l_len_flag = l_len_flag - 1.
l_char = i_skip_char+l_len_flag(1).
r_skip_char-sign = 'I'.
r_skip_char-option = 'EQ'.
r_skip_char-low = l_char.
APPEND r_skip_char. CLEAR r_skip_char.
ENDDO.
IF r_skip_char[] IS INITIAL.
r_skip_char-sign = 'I'.
r_skip_char-option = 'EQ'.
r_skip_char-low = '_'. "放一個不會編到的字元
APPEND r_skip_char. CLEAR r_skip_char.
ENDIF.
IF i_len <= 0.
e_errorcode = 'F'.
e_errordesc = 'i_len 序號長度需大於 0'.
EXIT.
ELSEIF i_len > 256.
e_errorcode = 'F'.
e_errordesc = 'i_len 序號長度需小於 256'.
EXIT.
ENDIF.
DO i_len TIMES.
i_num = i_num + 1.
itab_seq-seq = i_num.
itab_seq-chr = '0'.
APPEND itab_seq. CLEAR itab_seq.
ENDDO.
"由 0 開始編碼 (因無法判斷是目前已有 0 號還是要編 0,所以要從 0 就要放空白)
IF i_seq = space AND i_start_from_0 = 'X'.
SORT itab_seq BY seq.
LOOP AT itab_seq.
CONCATENATE e_seq itab_seq-chr INTO e_seq.
ENDLOOP.
e_errorcode = 'S'.
EXIT.
ENDIF.
"由 1 始編碼
IF i_seq = space AND i_start_from_0 = space.
LOOP AT itab_seq.
CLEAR l_last.
AT LAST.
l_last = 'X'.
ENDAT.
IF l_last = 'X'.
itab_seq-chr = '1'.
ENDIF.
CONCATENATE e_seq itab_seq-chr INTO e_seq.
ENDLOOP.
e_errorcode = 'S'.
EXIT.
ENDIF.
IF i_seq EQ space.
e_errorcode = 'F'.
e_errordesc = 'i_seq 參數無值,無法進行編號'.
EXIT.
ENDIF.
IF NOT i_seq CO '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
e_errorcode = 'F'.
e_errordesc = 'i_seq 序號'.
EXIT.
ENDIF.
DESCRIBE TABLE itab_seq LINES itab_seq_flag.
"將序號置入 Internal Table
CLEAR: l_len, l_len_flag.
l_len = strlen( i_seq ).
l_len_flag = l_len.
DO l_len TIMES.
l_len_flag = l_len_flag - 1. "字元位置從 0 開始編碼
l_len_char = i_seq+l_len_flag(1).
READ TABLE itab_seq WITH KEY SEQ = itab_seq_flag. "依字元第幾碼放入 itab_seq
IF sy-subrc EQ 0.
itab_seq-chr = l_len_char.
MODIFY itab_seq INDEX sy-tabix.
itab_seq_flag = itab_seq_flag - 1.
ELSE.
WRITE itab_seq_flag TO l_num_char NO-GROUPING.
CONDENSE l_num_char.
e_errorcode = 'F'.
CONCATENATE '捉取 itab_seq 序號字元' l_num_char '異常'
INTO e_errordesc.
EXIT.
ENDIF.
ENDDO.
CHECK e_errorcode <> 'F'.
"產生 char to ascii
field-symbols : <conver_fs> type x.
LOOP AT itab_seq.
ASSIGN itab_seq-chr TO <conver_fs> CASTING.
MOVE <conver_fs> TO itab_seq-asc.
MODIFY itab_seq.
ENDLOOP.
"char -> ascii
"0~9 =>48~57
"A~Z =>65~90
CLEAR l_carry.
SORT itab_seq BY seq DESCENDING.
LOOP AT itab_seq.
IF sy-tabix = 1 or ( sy-tabix <> 1 and l_carry = 'X' ). "第一筆 or 非第一筆要進位時才做
CLEAR l_carry.
DO.
IF sy-index > 100. "避勉因傳入0~9, A~Z 都 SKIP 造成無窮回轉,因此跑超過 100 次直接 Error
e_errorcode = 'F'.
e_errordesc = '編碼取號異常,請 IT 確認異常編碼原因'.
EXIT.
ENDIF.
IF itab_seq-chr = 'Z'.
IF l_carry = 'X'. "不能進兩次位,表示
e_errorcode = 'F'.
e_errordesc = '相同位數不能進位兩次,請 IT 確認異常原因'.
EXIT.
ENDIF.
l_carry = 'X'.
IF I_START_FROM_0 = 'X'.
itab_seq-chr = '0'.
itab_seq-asc = '48'.
ELSE.
itab_seq-chr = '1'.
itab_seq-asc = '49'.
ENDIF.
ELSEIF itab_seq-asc = '57'.
itab_seq-chr = 'A'.
itab_seq-asc = '65'.
ELSE.
itab_seq-asc = itab_seq-asc + 1.
i_hex = itab_seq-asc.
class_convert = cl_abap_conv_in_ce=>create( encoding = 'UTF-8' ).
class_convert->convert( EXPORTING input = i_hex
IMPORTING data = itab_seq-chr ).
ENDIF.
"當字元非限定的字元則可繼續編碼
IF itab_seq-chr NOT IN r_skip_char.
EXIT.
ENDIF.
ENDDO.
MODIFY itab_seq.
IF l_carry EQ space. "沒有要進位就不用再 Loop 下去
EXIT.
ENDIF.
IF e_errorcode = 'F'. "有異常也不用再 Loop 下去
EXIT.
ENDIF.
ELSE. "非第一筆,且沒有要進位就不用再 Loop 下去
EXIT.
ENDIF.
ENDLOOP.
IF l_carry = 'X' AND e_errorcode <> 'F'. "進位符如果結束 Loop 仍是 X,表示已超過編碼
e_errorcode = 'F'.
e_errordesc = '序號已是最大號,無法再進行編碼'.
ENDIF.
IF e_errorcode <> 'F'.
SORT itab_seq BY seq.
LOOP AT itab_seq.
CONCATENATE e_seq itab_seq-chr INTO e_seq.
ENDLOOP.
e_errorcode = 'S'.
ENDIF.
ENDFUNCTION.
沒有留言:
張貼留言