Application Development and Automation Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

How to split a string in byte mode?

QuyVu
Participant
2,619

Hi all,

In Japanese, there are haft-width character( 1 byte ) and full-width character( 2 byte ) and my customer has a requirement split a string into two strings in byte mode( x=x1+x2 😞 one string length is x1 bytes and the other string length is x2 bytes. Like 'イウ城イウ会カ株' in this example:

I've resolved this requirement as below program:

CONSTANTS:
  GCF_BYTE_CUT TYPE INT1 VALUE 6. "x1
DATA:
    GDF_TEXT          TYPE AD_NAME2,    
    GDF_COUNT_BYTE    TYPE INT1,
    GDF_TEMP_BYTE     TYPE INT1,
    GDF_RESULT1_LENG  TYPE INT1,
    GDF_RESULT2_LENG  TYPE INT1,
    GDF_RESULT1       TYPE ZZSHIPTO_NAME2,
    GDF_RESULT2       TYPE ZZSHIPTO_NAME3
    .

GDF_TEXT = 'イウ城イウ会カ株'.   "Contains half and full-width CJK character

PERFORM GET_TEXT_BYTE USING    GDF_TEXT
                      CHANGING GDF_COUNT_BYTE.

IF GDF_COUNT_BYTE <= GCF_BYTE_CUT.         
  GDF_RESULT1 = GDF_TEXT.
ELSE.
  CLEAR GDF_COUNT_BYTE.
  GDF_RESULT1_LENG = GCF_BYTE_CUT / 2.  "Get min index to achive GCF_BYTE_CUT = 6 bytes
  PERFORM GET_TEXT_BYTE USING    GDF_TEXT+0(GDF_RESULT1_LENG)
                        CHANGING GDF_COUNT_BYTE.

  WHILE GDF_COUNT_BYTE < GCF_BYTE_CUT.
    PERFORM GET_TEXT_BYTE USING    GDF_TEXT+GDF_RESULT1_LENG(1)
                          CHANGING GDF_TEMP_BYTE.
    GDF_COUNT_BYTE   = GDF_COUNT_BYTE + GDF_TEMP_BYTE.
    GDF_RESULT1_LENG = GDF_RESULT1_LENG + 1.
  ENDWHILE.

  IF GDF_COUNT_BYTE = GCF_BYTE_CUT.      "When exists 6 bytes
    GDF_RESULT1     = GDF_TEXT+0(GDF_RESULT1_LENG).
  ELSEIF GDF_COUNT_BYTE > GCF_BYTE_CUT.  "When only exists 5 or 7 bytes
    GDF_RESULT1_LENG = GDF_RESULT1_LENG - 1.  "Set index to split string is 5 bytes
    GDF_RESULT1      = GDF_TEXT+0(GDF_RESULT1_LENG).
  ENDIF.

  GDF_RESULT2_LENG = STRLEN( GDF_TEXT ) - GDF_RESULT1_LENG.
  GDF_RESULT2      = GDF_TEXT+GDF_RESULT1_LENG(GDF_RESULT2_LENG).
ENDIF.

WRITE / : GDF_RESULT1, CL_ABAP_LIST_UTILITIES=>DYNAMIC_OUTPUT_LENGTH( GDF_RESULT1 ),
          GDF_RESULT2, CL_ABAP_LIST_UTILITIES=>DYNAMIC_OUTPUT_LENGTH( GDF_RESULT2 ).
*&---------------------------------------------------------------------*
*&      Form  GET_TEXT_BYTE
*&---------------------------------------------------------------------*
*      Get byte of a string
*----------------------------------------------------------------------*
*      -->PVF_TEXT
*      <--PRF_BYTE
*----------------------------------------------------------------------*
FORM GET_TEXT_BYTE  USING    PVF_TEXT  TYPE ANY
                    CHANGING PRF_BYTE  TYPE INT1.
  CLEAR PRF_BYTE.
  PRF_BYTE = CL_ABAP_LIST_UTILITIES=>DYNAMIC_OUTPUT_LENGTH(
                FIELD  =  PVF_TEXT
             ).
ENDFORM.                    " GET_TEXT_BYTE

But I know my solution is not really good in performance. Is there another solution?

Best regards,

LeoVu.

6 REPLIES 6
Read only

Sandra_Rossi
Active Contributor
2,319

Please post the code as text instead of image + use the CODE button to colorize it.

Read only

QuyVu
Participant
2,319

Hi Sandra,

Thanks for your advice. I've updated this QA.

Best regards,

LeoVu.

Read only

Sandra_Rossi
Active Contributor
2,319

Thanks a lot, easier to test your code to understand what you want to achieve.

The issue is that you are mixing several notions which have different meanings. Bytes are places in memory, but what your code shows is that you are talking about CJK (Chinese, Japanese, Korean) characters displayed on two positions in ABAP lists.

Now, concerning your code, I don't understand why you do it so complex, this one-line program does exactly the same! Maybe I don't understand what you're trying to achieve.

WRITE / : 'ab城イウ', CL_ABAP_LIST_UTILITIES=>DYNAMIC_OUTPUT_LENGTH( 'ab城イウ' ),
'会カ株', CL_ABAP_LIST_UTILITIES=>DYNAMIC_OUTPUT_LENGTH( '会カ株' ).
Read only

QuyVu
Participant
0 Likes
2,319

Hi Sandra,

Thank you for your support.

I've updated for input data in this question. Sorry for this inconvenience.

But my aim in this question is to improve performance main processing instead of displaying result:

GDF_TXT_LENGTH = STRLEN( GDF_TEXT ).
GDF_MIN_CHAR  = GCF_NUM_BYTE / 2.


IF GDF_TXT_LENGTH <= GDF_MIN_CHAR.
  GDF_RESULT1 = GDF_TEXT.
ELSE.
  PERFORM GET_TEXT_BYTE USING    GDF_TEXT+0(GDF_MIN_CHAR)
                        CHANGING GDF_COUNT_BYTE.
  IF GDF_COUNT_BYTE < GCF_NUM_BYTE.
    DO.
      IF GDF_COUNT_BYTE >= GCF_NUM_BYTE OR GDF_MIN_CHAR > GDF_TXT_LENGTH.
        GDF_RESULT1 = GDF_TEXT+0(GDF_MIN_CHAR).
        EXIT.
      ENDIF.
      PERFORM GET_TEXT_BYTE USING    GDF_TEXT+GDF_MIN_CHAR(1)
                            CHANGING GDF_COUNT_TEMP.
      GDF_COUNT_BYTE = GDF_COUNT_BYTE + GDF_COUNT_TEMP.
      GDF_MIN_CHAR = GDF_MIN_CHAR + 1.
    ENDDO.
  ELSE.
    GDF_RESULT1 = GDF_TEXT+0(GDF_MIN_CHAR).
  ENDIF.
ENDIF.


IF GDF_MIN_CHAR < GDF_TXT_LENGTH.
  GDF_NUMC_RESULT2 = GDF_TXT_LENGTH - GDF_MIN_CHAR. "x2
  GDF_RESULT2 = GDF_TEXT+GDF_MIN_CHAR(GDF_NUMC_RESULT2).
ENDIF.

Best regards,

LeoVu.

Read only

Sandra_Rossi
Active Contributor
2,319

To help you improve the performance, I must first understand what you want to achieve, but sorry, I can't. I improved your algorithm by removing all the lines of your code, and keep only one.

Read only

QuyVu
Participant
0 Likes
2,319

Hi Sandra,

Thank you for your continued support.

Best regards,

LeoVu