I am trying to see if there is a way to do the following
IF line_exists( company_accounts2[ saknr+0(2) = wa_company_accounts-saknr+0(wa_account_levels-num_of_digits) ] ).
ENDIF.
But the number 2 in saknr+0(2) with a parameter and specifically with the one that exists in the other side of equality (wa_account_levels-num_of_digits). Is there any way to do it with another way? Because if I replace the 2 with the wa_account_levels-num_of_digits I am getting the error "The length specification "WA_ACCOUNT_LEVELS-NUM_OF_DIGITS" is not numeric."
Thanks in advance
PS. What is not working and this is what I am asking below the above code is the following code:
IF line_exists( tab[ matnr+0(ls_mara-num_of_digits) = ls_mara-matnr+0(ls_mara-num_of_digits) ] ).
THIS CODE IS NOT WORKING.
Pass the left side of the equality as a text variable between parentheses, which contains the name of the variable and its offset:
DATA(lv_text) = |saknr+({ wa_account_levels-num_of_digits })|.
IF line_exists( company_accounts2[ (lv_text) = wa_company_accounts-saknr+0(wa_account_levels-num_of_digits) ] ).
CONTINUE.
ELSE.
"make the APPEND
ENDIF.
It works perfectly, for what you wanna achieve your wa_account_levels-num_of_digits should have primitive type i (INT1, INT2, INT4, INT8 in database).
Here is the working MARA sample
SELECT * UP TO 5 ROWS
FROM mara
INTO TABLE #DATA(tab).
READ TABLE tab INTO DATA(ls_mara) INDEX 1.
IF line_exists( tab[ matnr+0(2) = ls_mara-matnr+0(ls_mara-stfak) ] ).
ENDIF.
UPDATE: dynamic specification of the table components for read access is not possible:
If the data type of the components is character-like and flat, an offset/length +off(len) can be appended to the name of the component (as in substring access) to access subareas of the component. Only directly specified numbers or constants can be specified for off and len.
Related
I have internal type A for DF16_RAW and E for DF34_RAW and now at runtime I am creating a dynamic table for that I want datatype DF16_RAW and DF34_RAW with specified precision based on internal type. My code is like below:
CASE WA_COL-INTTYPE.
WHEN 'A'. LO_DESCR_RESULT = CL_ABAP_ELEMDESCR=>GET_DECFLOAT16( ).
WHEN 'E'. LO_DESCR_RESULT = CL_ABAP_ELEMDESCR=>GET_DECFLOAT34( ).
Here I want to get datatype with specified precision. I don't know how it be done?
Some parts of a variable are specific to the ABAP dictionary a.k.a. "DDIC" (search help, output style for the DF* types, etc.) If you want to create one variable with information specific to the ABAP dictionary, then you must refer to an element in the DDIC (i.e. a data element or table/structure component), then use:
lo_descr_result = cl_abap_typedescr=>describe_by_name( 'DDICdataelement' ).
or
lo_descr_result = cl_abap_typedescr=>describe_by_name( 'DDICtablestruct-Component' ).
Is there any way of programmatically getting the value of a Text Symbol at runtime?
The scenario is that I have a simple report that calls a function module. I receive an exported parameter in variable LV_MSG of type CHAR1. This indicates a certain status message created in the program, for instance F (Fail), X (Match) or E (Error). I currently use a CASE statement to switch on LV_MSG and fill another variable with a short description of the message. These descriptions are maintained as text symbols that I retrieve at compile time with text-MS# where # is the same as the possible returns of LV_MSG, for instance text-MSX has the value "Exact Match Found".
Now it seems to me that the entire CASE statement is unnecessary as I could just assign to my description variable the value of the text symbol with ID 'MS' + LV_MSG (pseudocode, would use CONCATENATE). Now my issue is how I can find a text symbol based on the String representation of its ID at runtime. Is this even possible?
If it is, my code would look cleaner and I wouldn't have to update my actual code when new messages are added in the function module, as I would simply have to add a new text symbol. But would this approach be any faster or would it in fact degrade the report's performance?
Personally, I would probably define a domain and use the fixed values of the domain to represent the values. This way, you would even get around the string concatenation. You can use the function module DD_DOMVALUE_TEXT_GET to easily access the language-dependent text of a domain value.
To access the text elements of a program, use a function module like READ_TEXT_ELEMENTS.
Be aware that generic programming like this will definitely slow down your program. Whether it would make your code look cleaner is in the eye of the beholder - if the values change rarely, I don't see why a simple CASE statement should be inferior to some generic text access.
Hope I understand you correctly but here goes. This is possible with a little trickery, all the text symbols in a report are defined as variables in the program (with the name text-abc where abc is the text ID). So you can use the following:
data: lt_all_text type standard table of textpool with default key,
lsr_text type ref to textpool.
"Load texts - you will only want to do this once
read textpool sy-repid into lt_all_text language sy-langu.
sort lt_all_Text by entry.
"Find a text, the field KEY is the text ID without TEXT-
read table lt_all_text with key entry = i_wanted_text
reference into lsr_text binary search.
If you want the address you can add:
field-symbols: <l_text> type any.
data l_name type string.
data lr_address type ref to data.
concatenate 'TEXT-' lsr_text->key into l_name.
assign (l_name) to <l_text>.
if sy-subrc = 0.
get reference of <l_text> into lr_address.
endif.
As vwegert pointed out this is probably not the best solution, for error handling rather use message classes or exception objects. This is useful in other cases though so now you know how.
As I rarely loop into a field symbol, I often forget to use ASSIGNING instead of INTO which will promptly cause an abend. Is there a valid use of INTO with <fieldsymbol> or is this something that the syntax checker really ought to catch?
LOOP...INTO is perfectly valid but it will work differently. LOOP...INTO transports the values to the structure provided but ASSIGNING assigns the field symbol to the actual table rows.
The only difference is if you are going to change the table contents. See the following:
* Changes all entries in the CARRID column of lt_flights to 50.
LOOP AT lt_flights ASSIGNING <flight>.
<flight>-carrid = 50.
ENDLOOP.
* Does not change the entries in lt_flights (MODIFY...FROM would be required).
ASSIGN <flight> TO ls_flight.
LOOP AT lt_flights INTO <flight>.
<flight>-carrid = 50.
ENDLOOP.
LOOP...INTO with a field symbol would be useless unless you had some kind of dynamic programming requirement.
It is valid when <fieldsymbol> was previously assigned to a structure which has the type of the lines of the table you loop over.
It is a perfectly valid statement:
APPEND INITIAL LINE TO lt_foo ASSIGNING <ls_foo>.
READ TABLE lt_bar INTO <ls_foo> INDEX 1.
A field symbol just takes the place of a variable - at almost any point - so the syntax check can't flag this as invalid. It might issue a warning, though...
I am trying to add a new record to my internal table and this code is giving me an error, but I am doing exactly the same thing as in my SAP book. What am I doing wrong?
TYPES : BEGIN OF personel_bilgileri,
Ad TYPE c LENGTH 20,
Soyad TYPE c LENGTH 20,
Telefon_no Type n LENGTH 12,
END OF personel_bilgileri.
TYPES personel_bilgi_tablo_tipi TYPE STANDARD TABLE OF
personel_bilgileri WITH NON-UNIQUE KEY ad soyad.
DATA : personel_bilgi_kaydi TYPE personel_bilgileri,
personel_bilgi_tablosu TYPE personel_bilgi_tablo_tipi.
personel_bilgi_kaydi-ad = 'Murat'.
personel_bilgi_kaydi-soyad = 'Sahin'.
personel_bilgi_kaydi-telefon_no = '5556677'.
APPEND personel_bilgi_kaydi TO personel_bilgileri.
personel_bilgi_kaydi-ad = 'Ayse'.
personel_bilgi_kaydi-soyad = 'Bil'.
personel_bilgi_kaydi-telefon_no = '5556611'.
APPEND personel_bilgi_kaydi TO personel_bilgileri.
personel_bilgi_kaydi-ad = 'Mehmet'.
personel_bilgi_kaydi-soyad = 'Kalan'.
personel_bilgi_kaydi-telefon_no = '5556622'.
APPEND personel_bilgi_kaydi TO personel_bilgileri.
Actually, I don't know which adding record method I should use. I mean there is too many ways to do this operation. Which method will be the true one?
I am getting this error:
The field Personel_bilgileri is unknown, but there are following fields similar names...
Moreover, I can do this with LOOP AT, but I didn't understand the usage of LOOP AT. What does it do?
In your code sample, you first defined PERSONEL_BILGILERI as a TYPE, then PERSONEL_BILGI_TABLO_TIPI as a internal table TYPE of PERSONEL_BILGILERI.
Up to that point, no variables are declared yet. Only data types.
Then:
PERSONEL_BILGI_KAYDI is defined of type PERSONEL_BILGILERI. This is a structure that you use as a work area (which is fine).
PERSONEL_BILGI_TABLOSU is defined of type PERSONEL_BILGI_TABLO_TIPI. So PERSONEL_BILGI_TABLOSU is your internal table.
When you APPEND your work area, you have to append to an internal table, not a data type. try with PERSONEL_BILGI_TABLOSU instead of your type PERSONEL_BILGI:
APPEND personel_bilgi_kaydi TO personel_bilgileri_tablosu.
You need to APPEND your WA(workarea, personel_bilgi_kaydi) in to your table (personel_bilgi_tablosu). You cant append the WA to the defined type.
So it should look like this:
APPEND personel_bilgi_kaydi TO personel_bilgi_tablosu.
Also you can use this code to show them on the page.
LOOP AT personel_bilgi_tablosu into personel_bilgi_kaydi.
write: / 'İSİM: ' ,personel_bilgi_kaydi-ad,
'SOYİSİM: ',personel_bilgi_kaydi-soyad,
'TEL NO: ', personel_bilgi_kaydi-telefon_no.
ENDLOOP.
You can use other methods to show your table on the page, such as REUSE_ALV_GRID_DISPLAY. You can get more information about that in scn.sap.com
Hope it was helpful.
Kolay gelsin.
Talha
I have a deep structure that I would like to display as a tree with the values of each field (sort of like the hierarchical display of a structure you can do in SE11, but with values).
Is there a class or function that does this for you? I really don't want to have to go reinvent the wheel.
Well, I would say it is faster to do DIY then to search for something generic enough to help you. You can try following coding as basis.
It does the plain recursion through the variable (be it table or structure) and it prints the fields found at bottom...
*&---------------------------------------------------------------------*
*& Form print_structure
*&---------------------------------------------------------------------*
form print_structure using im_data.
data: lr_typeref type ref to cl_abap_typedescr,
lf_ddic_in type fieldname,
lt_dfies type ddfields,
lf_string type c length 200.
field-symbols: <lt_table> type any table,
<ls_table> type any,
<lf_field> type any,
<ls_dfies> like line of lt_dfies.
lr_typeref = cl_abap_typedescr=>describe_by_data( im_data ).
case lr_typeref->type_kind.
when cl_abap_typedescr=>typekind_table. " internal table
assign im_data to <lt_table>.
loop at <lt_table> assigning <ls_table>.
perform print_structure using <ls_table>.
endloop.
when cl_abap_typedescr=>typekind_struct1 or
cl_abap_typedescr=>typekind_struct2. " deep/flat structure
lf_ddic_in = lr_typeref->get_relative_name( ).
call function 'DDIF_FIELDINFO_GET'
exporting
tabname = lf_ddic_in
all_types = 'X'
tables
dfies_tab = lt_dfies
exceptions
not_found = 1
others = 0.
check sy-subrc eq 0.
loop at lt_dfies assigning <ls_dfies>.
assign component <ls_dfies>-fieldname of structure im_data to <lf_field>.
perform print_structure using <lf_field>.
endloop.
when others. " any field
write im_data to lf_string.
write: / lf_string.
endcase.
endform. "print_structure
Would an ALV Tree work? CL_SALV_TREE
I've never seen such functionality and think there is no one in standard. Can't remeber any situation in standard where such functionality should be used. In my opinion most appropriate way to implement this - to use Column Tree. Take a look into SAPCOLUMN_TREE_CONTROL_DEMO