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

Data type doubled on dynamic table

Former Member
0 Likes
1,304

Hello Everyone,

I'm creating a Z program to insert data to any Z table created, for that, the user must put the name of the Z table and the path of the file with all data to be inserted.

The problem is that on dynamic table creation the datatype of the fields are doubled, I.E.: if the datatype is N length 3, it's coming as N length 6.

Does anyone know to solve this issue?

Thanks in Advance!

10 REPLIES 10
Read only

ThomasZloch
Active Contributor
0 Likes
1,254

Hard to guess without knowing how you are doing this exactly.

So how are you doing this exactly?

Thomas

Read only

0 Likes
1,254

Hello Thomas,

sorry, I wasn't very clear, actually the problem is on "Intlen" field which it comes doubled in the table I'm using, here's a piece of code:

data : t_details type abap_compdescr_tab,

wa_details type abap_compdescr.

data : ref_table_des type ref to cl_abap_structdescr.

  • Get the structure of the table.

ref_table_des ?=

cl_abap_typedescr=>describe_by_name( p_table ).

t_details[] = ref_table_des->components[].

loop at t_details into wa_details.

clear wa_fc.

wa_fc-fieldname = wa_details-name .

wa_fc-datatype = wa_details-type_kind.

wa_fc-inttype = wa_details-type_kind.

wa_fc-intlen = wa_details-length. "here, if the intlen on my Z table is 3, here comes as 6

wa_fc-decimals = wa_details-decimals.

append wa_fc to t_fc.

endloop.

on my selection-screen I put a parameter to get the path of the file with all the data to be inserted on the Z table and another one so the user can input the name of the Z table.

It's a simple program to insert values to any Z table created on system, my problem, as described above is that I'm creating the internal table dynamicly and the method I'm using it's bringing a table with the data field intlen doubled. I'd just like to know why this happen, because it shouldn't, right? And as it does, i get an error while inserting fields on my Z table

Actually I know how to overcome this problem, in this case, I can make a division by 2 with this field and modify my table, but I don't think this field should come this way.

Thanks!!

Read only

0 Likes
1,254

I was looking for a resolution of this same problem. It seems the intlen is expressed in number of bytes, and thus it is doubled in UTF-16 (unicode) systems. So you have to divide by 2 (instead, use cl_abap_char_utilities=>charsize which is the number of bytes per character).

I am wondering if there is a standard function module or a method which does that... (because there are many other field types to check too)

Read only

0 Likes
1,254

Hello Sandra,

thanks for your answer. You got the point, I just wanted to know the reason why it came doubled and i did what you said: just divided by 2.

If you find any standard method, please let us know!!

Thank you very much!

Read only

0 Likes
1,254

Hi

Just Sandra said it's a unicode problem (I suppose your system is unicode).

If the structure, so table, u need to create is defined in the dictionary, u can get the fields characteristics using the fm DDIF_FIELDINFO_GET, instead of the method cl_abap_typedescr=>describe_by_name

Max

Read only

0 Likes
1,254

I "give up". I have just found method CL_UG_MD_FIELDNAME=>CONVERT_INTLEN_TO_LENG supplied in FIN_BASIS component, but it requires DDIC type. I have migrated it to the following routine so that we can use the internal type. Examples: C 510 -> 255 (unicode), F -> 16, etc. I don't know if it works yet. I will test it in my program later. Note: I don't use the ALV, I just need the length like given in DDIC.


FORM convert_intlen_to_leng
      USING
        I_INTTYPE       TYPE INTTYPE
        I_INTLEN        TYPE numeric "bytes
      CHANGING
        R_LENG          TYPE numeric "DDIC
        NOT_CALCULABLE  TYPE flag.
  CASE i_inttype.
    WHEN 'C' OR 'N'.
      IF i_intlen IS INITIAL. not_calculable = 'X'. EXIT. ENDIF.
      r_leng = i_intlen / cl_abap_char_utilities=>charsize.
    WHEN 'P'.
      IF i_intlen IS INITIAL. not_calculable = 'X'. EXIT. ENDIF.
      r_leng = i_intlen * 2 - 1.
    WHEN 'D'.
      r_leng = '8'.
    WHEN 'F'.
      r_leng = '16'.
    WHEN 'b'.
      r_leng = '3'.
    WHEN 's'.
      r_leng = '5'.
    WHEN 'I'.
      r_leng = '10'.
    WHEN 'X'.
      IF i_intlen IS INITIAL. not_calculable = 'X'. EXIT. ENDIF.
      r_leng = i_intlen.
    WHEN 'l' OR 'r'.
      r_leng = '0'.
    WHEN 'y'.
      r_leng = '0'.
    WHEN 'g'.
      r_leng = '0'.
    WHEN 'T'.
      r_leng = '6'.
    WHEN OTHERS.
      not_calculable = 'X'. EXIT.
  ENDCASE.
ENDFORM.

Read only

0 Likes
1,254

Yes Max, my system is unicode

Thanks for your answer

Read only

0 Likes
1,254

Thanks once again for your time Sandra....

Later I'll try to use it too!

Read only

0 Likes
1,254

Hi

Just as I said, if u need to create a table like a dictionary table u can use the standard fm DDIF_FIELDINFO_GET in order to get the informations, so it doesn't need to calculate the real size.

My system is unicode too, and I used the fm above to create dynamically a structure based on dictionary definition:

 LOOP AT VAKE_DFIES_TAB INTO DFIES WHERE FIELDNAME <> 'KFRST' AND
                                          FIELDNAME <> 'KBSTAT'.
    COMPONENT-NAME = DFIES-FIELDNAME.

    MOVE DFIES-LENG     TO _LEN.
    MOVE DFIES-DECIMALS TO _DEC.

    CASE DFIES-DATATYPE.
      WHEN 'CHAR' OR 'LANG' OR 'CUKY'.
        MOVE CL_ABAP_ELEMDESCR=>GET_C( P_LENGTH = _LEN )
                                                      TO LR_VALUE_DESCR.
      WHEN 'NUMC'.
        MOVE CL_ABAP_ELEMDESCR=>GET_N( P_LENGTH = _LEN )
                                                      TO LR_VALUE_DESCR.
      WHEN 'INT1' OR 'INT2' OR 'INT4'.
        MOVE CL_ABAP_ELEMDESCR=>GET_I( ) TO LR_VALUE_DESCR.
      WHEN 'DATE'.
        MOVE CL_ABAP_ELEMDESCR=>GET_D( ) TO LR_VALUE_DESCR.
      WHEN 'DEC' OR 'CURR'.
        MOVE CL_ABAP_ELEMDESCR=>GET_P( P_LENGTH   = _LEN
                                       P_DECIMALS = _DEC )
                                                      TO LR_VALUE_DESCR.
      WHEN 'TIME'.
        MOVE  CL_ABAP_ELEMDESCR=>GET_T( ) TO LR_VALUE_DESCR.
      WHEN 'UDEF'.
    ENDCASE.

    COMPONENT-TYPE = LR_VALUE_DESCR.
    INSERT COMPONENT INTO TABLE LT_COMPONENTS.
  ENDLOOP.
  IF SY-SUBRC <> 0.
    PERFORM RAISE_ERROR USING 'C'.
  ENDIF.
* Creazione struttura chiave
  LR_STRUCT_DESCR
        = CL_ABAP_STRUCTDESCR=>CREATE( P_COMPONENTS = LT_COMPONENTS
                                       P_STRICT     = 'X' ).

  CREATE DATA DYN_VAKEY TYPE HANDLE LR_STRUCT_DESCR.
  ASSIGN DYN_VAKEY->* TO <FS_VAKEY>. 

Max

Read only

0 Likes
1,254

Hi

Anyway u can use the value from attribute CL_ABAP_CHAR_UTILITIES=>CHARSIZE in order to know how many bytes are for a CHAR

write CL_ABAP_CHAR_UTILITIES=>CHARSIZE.

Max