Field Symbols (how to use practically??)
When I began learning the concept of field symbols , it looked quite scary with all the brackets and new syntax. But now after using it almost on a regular basis I actually am kind of tempted to use it maximum to where I can.
Field symbols are better performance wise but I am not going down that lane. I am here explaining how to be using it practically and effectively. In simple words , a field symbol refers or points (pointers known as in C language) to something. That something can be a table , a field or even nothing. When I say nothing I mean that the structure of a field symbol can be determined dynamically.
For our purpose let us consider MARA table as the referring table and MATNR field as the referring field.
Definition :
field-symbols: <fs_tab> type standard table,
<fs_wa> type mara.
Here we have defined a table <fs_tab> containing no structure and <fs_wa> with structure MARA.
Assign :
Note for field symbols just defining does not mean that we can start using it after definition. We have to assign a structure to that field symbol. i.e we have to tell the program that not <fs_tab>will be referring to table MARA.
Now we have an internal table itab_mara defined.
Data : itab_mara like mara occurs 0 with header line.
All we have to do is before using <fs_tab> we have to write
Data : itab_mara like mara occurs 0 with header line.
All we have to do is before using <fs_tab> we have to write
Assign : itab_mara[] to <fs_tab>.
You can now use <fs_tab> and whatever changes you make to <fs_tab> reflects to itab_mara.
Loop at <fs_tab> assigning <fs_wa>.
<fs_wa>-matnr = ‘NEW CHANGE MATERIAL’.
Endloop.
Now this automatically refer to <fs_tab> which will automatically modify itab_mara[].
field-symbols: <fs_tab> type standard table,
<fs_wa> type mara.data : itab_mara like mara occurs 0 with header line.
select * from mara up to 10 rows into table itab_mara.
assign : itab_mara[] to <fs_tab>.
loop at <fs_tab> assigning <fs_wa>.
<fs_wa>-matnr = ‘NEW CHANGE MATERIAL’.
endloop.
New Scenario :
1. Now in the above case you have internal table itab_mara ready. Suppose you don’t have internal table itab_mara then what?
You will need to assign <fs_tab> and <fs_wa> dynamically and also apply a select query dynamically.
Consider the same case for table MARA and field MATNR.
Defining the field symbol is same and also the looping part is same. The only change is where and how you assign the field symbols.
Consider the following scenario. You have a program with parameter field TABLE NAME. as soon as the user enters a table name he will get 10 rows selected from that table and modify the a field.
parameters : p_tab type dd03l-tabname.
field-symbols: <fs_tab> type standard table,
<fs_wa> type any,
<fs_matnr> type matnr.data: fs_data type ref to data,
dyn_line type ref to data.
data : itab_fcat type lvc_t_fcat.
data : fcat like line of itab_fcat.start-of-selection.
******* Assigncall function ‘LVC_FIELDCATALOG_MERGE’
exporting
i_structure_name = p_tab
changing
ct_fieldcat = itab_fcat.loop at itab_fcat into fcat.
clear: fcat-domname, fcat-ref_table.
modify itab_fcat index sy-tabix from fcat.
endloop.call method cl_alv_table_create=>create_dynamic_table
exporting
it_fieldcatalog = itab_fcat
importing
ep_table = fs_data.assign fs_data->* to <fs_tab>.
create data dyn_line like line of <fs_tab>.
assign dyn_line->* to <fs_wa>.
******* Assign
select * from (p_tab) up to 10 rows into corresponding fields of table <fs_tab>.loop at <fs_tab> assigning <fs_wa>.
assign component ‘MATNR’ of structure <fs_wa> to <fs_matnr>.
<fs_matnr> = ‘NEW CHANGE’.
endloop.
Here we use assign component as we do not know which fields are there in <fs_wa> before runtime.
Hello Devrath,
Just to make you aware and not to criticize. A field symbol is not a pointer. It is a just an alias for accessing variables, with its ability to latch on or to act as an "Alias" to any variable of a similar type ( if a type is specified ) or to any type if the field symbol is defined generically ( Type ANY ). Most importantly - > this is where it differs from pointers, is that a field symbol never has memory of its own, and that's why it is always important to "assign" a field symbol to existing memory.
In your above example, the only example of a pointer is the variable ' fs_data' ( data: fs_data type ref to data ) operator. ->* gives the memory location pointed to (the actual variable) , and the Field symbol acts as the alias to access it.
Thanks,
Venkat.
This is usually called "dereferenced pointer" because, in Abap, usage of a field-symbols addresses directly the assigned memory content (Like with dereference operator like the asterisk in C or the dot in java)
Regards,
Raymond
its same as pointer, but unlike C, we cannot identify location of pointer. it is not for us to see but to use. π
thanks for the replies guys,,, to stay on the safe side i have mentioned practically π . .
but they really come in handy. i feel what Gaurab suggested they are pointers but with little difference than C more precise.
Reference variables are similar to pointers in C & not field symbols!
Field symbols are similar to dereferenced pointers in C (that is, pointers to which the content operator * is applied). However, the only real equivalent of pointers in ABAP, that is, variables that contain a memory address (reference) and that can be used without the contents operator, are reference variables in ABAP Objects. (For more information, see Data References).
taken from :
http://help.sap.com/saphelp_nw04/helpdata/EN/fc/eb3860358411d1829f0000e829fbfe/content.htm
Reference Variables:
Reference variables are initial when you declare them. They do not point to an object. You cannot dereference an initial reference variable.
taken from:
http://help.sap.com/saphelp_nw70/helpdata/en/9a/871ad40c6c11d3b9350000e8353423/content.htm
That is why field-symbols are much closer to pointers than data reference variables.
In addition:
Pointers have no data type. Similarly in ABAP you can have TYPE ANY for field symbols.
That's what Raymond, Venkat & I have said. So where's the contradiction? π
One concern guys... have any of you used field symbols with for all entries. I have tried and when i dynamically give a where clause it takes loads of time even for a single record. So i am not completely sure whether it is a syntax error as no dump is there and also am very curious to know if it is possible in a faster way.
Disagree.
Reference variables are initial when you declare them. They do not point to an object. You cannot dereference an initial reference variable.
So are field-symbols when you don't assign them to something, aren't they?
Can you please point me the difference between these 2 statements?
And when i said "Reference variables" i meant(read: implicitly meant) variables referencing some instance & not the INITIAL reference.
- Suhas
Field symbols are not INITIAL before they are assigned.
Reference variables are INITIAL.
See ABAP
CHECK <FS> IS ASSIGNED.
compared to
CHECK lv_ref IS INITIAL.
Only reference variables with data reference has pointer characteristics. But that characteristics has many limitations. It always has initial value, cannot be type ANY and cannot be dereferenced without using field symbols.
So whos the daddy? of course field-symbols.
We don't use INITIAL to check if the reference variable contains a valid reference, we use BOUND.
http://help.sap.com/abapdocu_731/en/abenlogexp_bound.htm
Use this expression and check!
For reference variables the initial value is the null(or INITIAL) reference and this is not the same as the INITIAL for other data variables.
So what are they when they are declared - ever thought about it?
Why does the below code produce a RT error -
but the following code works -
If you understand the difference, then we're on the same page. And god-forbid if you don't, then refer to Venkat's initial reply.
- Suhas
An unassigned Field symbol points to NULL. You cannot check whether it is initial.
TYPE REF always points to a memory location {A:INITIAL} and assigning that location to a field symbol will mean that the field symbol refers to the {A:INITIAL} which the reference variable points to.
You simply proved that reference variables cannot have a NULL reference while field symbols do. Thanks.
god forbid if you do not understand the difference between having NO VALUE and having an INITIAL value.
So you say that you cannot check if they are initial, but this contradicts your previous statement -
Or do you mean to say they are not initial, but contain NULL or NO VALUE? π
Unfortunately i don't understand the difference between NO VALUE and INITIAL value π
Do you mean to say that when you define a FIELD-SYMBOL it points to NULL ( or NO VALUE, if you are using the terms synonymously)? So IS [NOT] ASSIGNED checks whether the field-symbol is NULL or has NO VALUE?
- Suhas
Just because i didn't want to sound rude & still get my point across the table, which tbh didn't seem to work π
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.
ABAP is safely typed. Type safety is closely linked to memory safety. Computer languages such as C and C++ that support arbitrary pointer arithmetic etc are typically not memory safe. There are several different approaches to find errors in such languages.Most high-level programming languages avoid the problem by disallowing pointer arithmetic and casting entirely, and by enforcing tracing garbage collection as the sole memory management scheme.
Please use wisely field symbols, one disadvantage during debugging process, you cannot set watch-points on them.
That is true but their flexibility makes them a really good tool.
Regards
Rich
I don't like type prefixes much, but even if you're a big fan the fs prefix, like <fs_wa> has to be the most pointless. You've already got the angled brackets. Why would you want to identify the type further? Use <material> not <fs_material>!
I strongly agree. Field symbols should follow the same conventions of other variables inside the angled brackets. If your field symbols points to a structure, it should be called <ls_...>. For a table, <lt_...> for a field, <lv_...> and so one. Unfortunately I frequently stumble upon old code (colleagues' and internal SAP employees') that uses the most ridiculous prefixes such as <fs_wa_...> or even <lfs_et_...> (like line of et_...).
I prefer <ls_...> and not <s_...> because I want to keep the same standards and conventions for all my data across every project - gc_..., lo_.., lv_..., <ls_...> , mt_..., etc. Always a two-letter prefix denoting the variable's scope (local, global, member) and type (table, structure, field, object, constant) that cannot be confused with other random or more-restricted-in-naming data, such as parameters and select-options that can be only up to 8 characters long, and so must start with p_... or s_... .
One last remark: variables' names, in my opinion, should not contain garbage or irrelevant text like "fs_wa" which doesn't help anything and only harms the readability, but the should be as long and informative as possible. I believe that when used properly, long variables' names are a good thing that benefits the readability.
I, SAP and DSAG prefer not to use prefixes for type indication at all... Just long names
<table_of_materials>Β π
Interesting. I know this concept from other languages like Java, but I find it a bit confusing to implement in ABAP, as the editor doesn't visually distinguish between types of variables (table, line, variable, object, etc.).
The prefixes I use tell the scope and are shorter than your suggestion (lt_materials vs. table_of_materials). Of course, there is no problem with long names! (as I stated in my last reply π ) but when ABAP forces you to restrict them to 30 charactersΒ you have to get creative if you want to have "table_of_complaints_filed_for_given_employees_list"...
Anyway, thank you very much for the links! It is always good to learn and improve one's development skills.
Here are the complete url's if SCN ever reboots itself like it did recently:
https://help.sap.com/doc/abapdocu_750_index_htm/7.50/en-US/abenprog_intern_names_guidl.htm
https://www.dsag.de/sites/default/files/dsag_recommendation_abap_development.pdf