Error trying to screen an internal table abap - abap

I´m learning ABAP and I keep trying to write that internal table and show it. There's syntax error message at line WRITE: / I_EJSEIS:
"I_EJSEIS" cannot be converted to a character-like value
I just don't understand it.
TYPES: S_EJSEIS LIKE SPFLI.
DATA: I_EJSEIS TYPE TABLE OF S_EJSEIS WITH HEADER LINE,
WA_EJSEIS TYPE S_EJSEIS.
SELECT FLTYPE
FROM SPFLI
INTO TABLE I_EJSEIS
WHERE CARRID = 'LH'.
LOOP AT I_EJSEIS.
WRITE: / I_EJSEIS.
ENDLOOP.

According to the ABAP documentation of WRITE dobj:
For dobj, those data types are allowed that are grouped under the generic type simple:
All flat data types; flat structures are handled like a data object of type c and can only contain any character-like components.
The data types string and xstring
enumerated types; the name (maximum three characters) of the enumerated constant is used in uppercase letters, which defines the current enumerated value.
In your case, I_EJSEIS is a (flat) structure containing at least one non-character component (e.g. fltime, distance, period), so it doesn't fall in any of the categories above.
The workaround is to display the fields individually:
WRITE: / I_EJSEIS-FLTYPE, I_EJSEIS-FLTIME.

Related

How to get a datatype DF16_RAW with precision 16 by using CL_ABAP_ELEMDESCR for internal table in ABAP?

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' ).

Get Text Symbol Programmatically With ID

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.

Casting from a Packed(8) type to a TMSTMP (DEC15) type in a Unicode system (and back)

Background:
I have several tables that are connected for maintenance in a view cluster (SE54). Each of these tables have the standard Created/Changed By/On fields. For created data updating the fields are easy, and I use event 05 (On Create) in the Table Maintenance generator. For defaulting the changing fields it's a little bit more involved. I have to use event 01 (Before Save), and then update the tables TOTAL[] and EXTRACT[] with the field values as needed.
When maintaining the table in SM30, the format of TOTAL[] and EXTRACT[] is the same as the view I'm maintaining with an additional flag to identify what type of change is made (update/create/delete)
However, when maintaining in SM54 (which is the business requirement), the format of TOTAL[] and EXTRACT[] is just an internal table of character lines.
Problem:
I can figure out what the type of the table that is being edited is. But when I try to move the character line to the type line I get the following run-time errors: (Depending on how I try to move/assign it)
ASSIGN_BASE_TOO_SHORT
UC_OBJECTS_NOT_CONVERTIBLE
UC_OBJECTS_NOT_CHAR
All my structures are in the following format:
*several generic (flat) types
CREATED TYPE TMSTMP, "not a flat type
CHANGED TYPE TMSTMP, "not a flat type
CREATED_BY TYPE ERNAM,
CHANGED_BY TYPE AENAM,
The root of the problem is that the two timestamp fields are not flat types. I can see in the character line, that the timestamps are represented by 8 Characters.
Edit: Only after finding the solution could I identify the Length(8) field as packed.
I have tried the following in vain:
"try the entire structure - which would be ideal
assign ls_table_line to <fs_of_the_correct_type> casting.
"try isolating just the timestamp field(s)
assign <just_the_8char_representation> to <fs_of_type_tmpstmp> casting.
I've tried a few other variations on the "single field only" option with no luck.
Any ideas how I can cast from the Character type to type TMSTMP and then back again in order to update the internal table values?
I've found that the following works:
In stead of using:
field-symbols: <structure> type ty_mystructure,
<changed> type tmstmp.
assign gv_sapsingle_line to <structure> casting. "causes a runtime error
assign gv_sap_p8_field to <changed> casting. "ditto
I used this:
field-symbols: <structure> type any,
<changed> type any.
assign gv_sapsingle_line to <structure> casting type ty_mystructure.
assign gv_sap_p8_field to <changed> casting type ty_tmstmp.
For some reason it didn't like that I predefined the field symbols.
I find that odd as the documentation states the following:
Casting with an Implicit Type Declaration Provided the field symbol is
either fully typed or has one of the generic built-in ABAP types – C,
N, P, or X – you can use the following statement:
ASSIGN ... TO <FS> CASTING.
When the system accesses the field symbol, the content of the
assigned data object is interpreted as if it had the same type as the
field symbol.
I can only assume that my structure wasn't compatible (due to the P8 -> TMSTMP conversion)
The length and alignment of the data object must be
compatible with the field symbol type. Otherwise the system returns a
runtime error. If the type of either the field symbol or the data
object is – or contains – a string, reference type, or internal table,
the type and position of these components must match exactly.
Otherwise, a runtime error occurs.

Field symbol and data reference concept in ABAP

If we compare ABAP field symbols and data references with the pointer in C, we observe :-
In C, say we declare a variable "var" type "integer" with default value "5".
The variable "var" will be stored some where in memory, and say the memory address which holds this variable is "1000".
Now we define a pointer "ptr" and this pointer is assigned to our variable.
So, "ptr" will be "1000" and " *ptr " will be 5.
Lets compare the above situation in ABAP.
Here we declare a Field symbol "FS" and assign that to the variable "var".
Now my question is what "FS" holds ? I have searched this rigorously in the internet but found out many ABAP consultants have the opinion that FS holds the address of the variable i.e. 1000. But that is wrong. While debugging i found out that fs holds only 5. So fs (in ABAP) is equivalent to *ptr (in C). Please correct me if my understanding is wrong.
Now lets declare a data reference "dref" and another filed symbol "fsym" and after creating the data reference we assign the same to field symbol . Now we can do operations on this field symbol. So the difference between data refernec and field symbol is :-
in case of field symbol first we will declare a variable and assign it to a field symbol.
in case of data reference first we craete a data reference and then assign that to field symbol.
Then what is the use of data reference? The same functionality we can achive through field symbol also.
The field-symbol is much like a pointer, but one that you can only access in a dereferenced form. In other words, it will hold, internally, the memory address of the variable that was assigned to it, but it will not allow you to see the memory address, only the data that is stored in the variable that it points to. This can be proved, because if you change the contents of a field-symbol that points to an internal table line, you'll see that the changes will be made directly in the line.
A data reference acts like a simple pointer, except that you can't increment or decrement the memory address like in C (ptr++, ptr-- and such). It differs from a field-symbol because you can compare two data references to check if they point to the exact same spot in the memory. Comparing two field-symbols will be a simple value comparison. Another difference is that you can allocate memory dynamically by creating data references, with the CREATE DATA command. A field-symbol can only be assigned to an already allocated variable.
Although data references and field symbols look very similar and are often used in a similar fashion (see the other answers), they are fundamentally different.
Data references are variables that store a value, just like a string or an integer. They have a fixed size in memory and a content. The only difference is that these references are pointers to other data objects, i. e. the content has a special meaning. They can point nowhere, they can be dereferenced, you can pass them along to other routines, you can manipulate either the pointer (GET REFERENCE) or the value it points to. Nothing special to it, really - just pointers as you know them from your favorite programming language.
Field Symbols are no "real" variables. The documentation states that
They do not physically reserve space for a field
Field Symbols are really only clever manipulations of the local symbol table of the ABAP VM. I'll try to illustrate this - note that this is a heavily simplified model. Let's say you declare three variables:
DATA: my_char TYPE c,
my_int TYPE i,
my_ref TYPE REF TO i.
Then the symbol table will contain - among others - entries that might look like this:
name type size addr
------------------------------
MY_CHAR c 1 0x123456
MY_INT i 4 0x123457
MY_REF r ? 0x123461
(I'm not sure about the actual size of a reference variable.)
These entries only point to an address that contains the values. Depending on the scope of these variables, they might reside in totally different memory areas, but that's not our concern at the moment. The important points are:
Memory has to be reserved for the variables (this is done automatically, even for references).
References work just like all the other variables.
Let's add a field symbol to this:
FIELD-SYMBOLS: <my_fs> TYPE any.
Then the symbol might look like this:
name type size addr target
--------------------------------------
MY_CHAR c 1 0x123456
MY_INT i 4 0x123457
MY_REF r ? 0x123461
<MY_FS> *
The field symbol is created in its initial state (unassigned). It doesn't point anywhere, and using it in this state will result in a short dump. The important point is: It is not backed by "heap" memory like the other variables. Let's
ASSIGN my_char TO <my_fs>.
Again the symbol might look like this:
name type size addr target
--------------------------------------
MY_CHAR c 1 0x123456
MY_INT i 4 0x123457
MY_REF r ? 0x123461
<MY_FS> * MY_CHAR
Now, when accessing <my_fs>, the runtime system will recognize it as a field symbol, lookup the current target in the symbol table and redirect all operations to the actual location of my_char. If, on the other hand, you'd issue the command
GET REFERENCE OF my_int INTO my_ref.
the symbol table would not change, but at the "heap address" 0x123461, you'd find the "address" 0x123457. Just a value assignment like my_char = 'X' or my_int = 42 * 2.
This is, in a very simplified version, the reason why you cannot pass field symbols as changing parameters and allow them to be reassigned inside the subroutine. They do not exist in the same way that other variables do, and they have no meaning outside of the scope of the symbol table they were added to.
A field symbol, which has been around in ABAP much longer, allows you to manipulate and pass values of fields at runtime, without knowing the name of the field beforehand. Consider this use case: You have a structure with 20 fields, you can reference each field by name and assign it to a field symbol, and then change the value of a particular field etc.
A data reference (TYPE REF TO DATA), which is a relatively newer addition to ABAP, allows you to instantiate data at runtime without knowing the type beforehand using the 'CREATE DATA' statement.
For an example of the use of CREATE DATA, see the following SAP Help page. It shows you how you can for example get a reference to a reference object (i.e. ABAP Objects reference) using CREATE DATA, which is something you could not do with a field symbol: http://help.sap.com/abapdocu_70/en/ABAPCREATE_DATA_REFERENCE.htm

Syntax error "field ITAB unknown" in APPEND wa TO itab

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