ABAP News for Release 7.50 – CORRESPONDING, again …
In ABAP, as a rule, the name is not always the game (see an entertaining recent discussion about that).
But as you all know there is a prominent exception to that rule: All the syntax forms involving CORRESPONDING for assigning structure components that (by chance) have the same name.
- Before ABAP 7.40, these were mainly MOVE-CORRESPONDING for the components of structures, the CORRESPONDING addition to Open SQL’s SELECT, and some obsolete calculation statements.
- With ABAP 7.40 MOVE-CORRESPONDING was enabled to handle structured internal tables and a new constructor operator CORRESPONDING was introduced that allows an explicit mapping of structure components with different names.
What was still missing? A dynamic mapping capability! And this was introduced with ABAP 7.50.
The new system class CL_ABAP_CORRESPONDING allows you to assign components of structures or internal tables with dynamically specified mapping rules.
The mapping rules are created in a mapping table that is passed to a mapping object, e.g. as follows:
DATA(mapper) =
cl_abap_corresponding=>create(
source = struct1
destination = struct2
mapping = VALUE cl_abap_corresponding=>mapping_table(
( level = 0
kind = cl_abap_corresponding=>mapping_component
srcname = ‘…’
dstname = ‘…’ )
( level = 0
kind = cl_abap_corresponding=>mapping_component
srcname = ‘…’
dstname = ‘…’ )
( level = 0
kind = cl_abap_corresponding=>mapping_component
srcname = ‘…’
dstname = ‘…’ ) ) ).
This is a simple example, where all structure components are on top level (0) and where all components are to be mapped (kind = cl_abap_coresponding=>mapping_component). More complicated forms involve nested structures and exclusions. With srcname and dstname the component names can be specified dynamically. The table setup is similar to the mapping-clause of the CORRESPONDING operator.
After creating the mapping object, all you have to do is to execute the assignment as follows:
mapper->execute( EXPORTING source = struct1
CHANGING destination = struct2 ).
You can do that again and again for all structures or internal tables that have the same types as those used for creating the mapping object.
Not much more to say about that. For details and more examples see CL_ABAP_CORRESPONDING – System Class.
Outlook
Up to now, only the basic form of the CORRESPONDING operator is mirrored in CL_ABAP_CORRESPONDING. But a variant for using a lookup table is already in the queue.
Thanks!
In ABAP, as a rule, the name is not the game (see an entertaining recent discussion about that).
Would be nice to have a summary blog about it, which would be easier to read. 😉
What was still missing? A dynamic mapping capability!
Actually I also missed to possibility to merge two structures into a 3rd one. I mean having an option to do the move-corresponding, but do not overwrite if the values are not initial (coming from 1st structure). We had a helper method for this with parameter KEEP_IF_NOT_INITIAL. I guess with this syntax there is still no better way.
Thanks,
Peter
For your second missing option, would you not get the wanted functionality if you just change the order of the two MOVE-CORRESPONDING statements?
Hi Gerrit,
Not really, because it could be like this:
Source struct 1:
struct1-field1 = A
struct1-field2 = space
struct1-field3 = C
struct1-field4 = space
(eg: coming from some screen where user entered new values)
Source struct 2:
struct2-field1 = space
struct2-field2 = B
struct2-field3 = space
struct2-field4 = D
(eg: coming from some SAP master data for example)
Expected result:
struct3-field1 = A
struct3-field2 = B
struct3-field3 = C
struct3-field4 = D
(should be the merged values)
Of course struct1, struct2, struct3 could be different, because struct1 is coming from the popup screen, struct2 is coming from BAPI_GET_DETAIL for example.
Peter
I don't see such a possibility in the moment. Also with the BASE additiion of CORRESPONDING you do not succeed.
The reason is, that you want to have a new kind of assignment that is dependent from the contents of the target.
Written in ABAP, it would look like follows:
b = COND #( WHEN b IS INITIAL THEN a ELSE b).
But we don't have that kind of "KEEPING MOVE" in ABAP yet (at least I don't know it).
I'll ask my development colleagues about it ...
Thanks for the info!
This is a YEND (yet another name-depending) MOVE-CORRESPONDING.
I am waiting for years for a command, that maps content not by name, but by type, i. e. a simple command for copy all content of a VBAK-structure/-table to a BAPISDHD1-structure/-table. We still have to copy field by field by field, feeling like being in 18th century.
MOVE-TYPE-MATCHING vbak TO bapisdhd1.
Ideal would be, that not matching fields are not to be filled, so
MOVE-TYPE-MATCHING: vbak TO bapisdhd1, vbkd to bapisdhd
merges the content of vbak and vbkd into bapisdhd1 (instead of clearing the vbak-related fields in bapisdhd1).
Sorry, but SAP has to learn much about field naming. Just one example: The same (identical) address number field has the following names in different tables: ADRNR, ADDRESS_NO, ADDR_NO, etc.
I call this "SAP fieldname scrabble". Someone seems to have a special sets of dices to compose fieldnames. "Hey, it's Tuesday of an odd week, let's take the long name today".
Do SAP have a special department of experts for inventing more and more fieldnames for identical fields? Does no one at SAP know the default component name? Why it exists if even SAP does not use it?
Another example: Some return messages of FMs are transported by BAPIRET2, some other FMs use BAPIRETURN, etc. CALL TRANSACTION uses BSCMSGCOLL which brings us another return table. In each if this tables, there are different names for message type, message number etc. I'm mapping and mapping and mapping field by field instead of using a more intelligent move command variant.
This would be just a little problem, if there would be a feature for MOVE, which does not depending on the fieldname, because SAP uses different names for the same meaning!
I developed a method, which does this work (it's that simple in most cases: by comparing the data element! But my method compares more: the default component name and others), but I think, it's very poor, that the customer has to develop such an important feature instead of getting it from SAP - because SAP only knows "n+1 name depending move commands".
Hi Ralf,
One thing is the ABAP language cannot smooth out all the sins that are done by application programmers or modellers, as incoherent namings in that case.
Another thing is, I cannot imagine a language element that copies structure components based on equal types. How should that work if several components of a structure have the same type? At runtime, ABAP doesn't know the data element of a field.
Horst
Horst, if I could develop a routine, that works like this, SAP would not be able to do that?
I have a method, that compares structures or internal tables by data element, default component name and some other attributes. Using this way, I can map all bapiret*-structures to all other bapiret*-structures (or tables, as mentioned) or vbak to bapi-SD-structures or....
I can not understand, that there are no rules for component names or the usage of default component names. Are SAP developers not talking which each other? It there no quality management that avoids different component names for the same component? A simple program, that compares component names by data element, implemented in transport organizer?
Sounds like a German authority: "Not my department, go for Passierschein A38" (sorry, German link). Maybe, but who could know the right address if you don't?
It will not be enough to satisfy you, but I added a rule to the ABAP programming guidelines that handles the naming of structure components (available with 7.50, SP02). Yes, it is decades too late for that and no, nobody will notice it.
Just a question. Wouldn't the dynamic mapping capabilities of CL_ABAP_CORRESPONDING be helpful in your type mapping tasks?
Last but not least. Since neither names nor technical types are sufficient for semantical mappings, ABAP CDS allows you to annotate the elements of an entity (the components of its structured type). Such semantical annotations enable frameworks to identify elements according to their meaning.
ROFL
I'll check this - but not today. We had a going live, recently, and it does not seem to be tested well.... So I have to do some open-heart-surgeries.....
Thanks for helping me.
Hello Horst,
the dynamic mapping is nice, even if it was possible already before using the RTTI classes, just by constructing a structure that is technical identical to the target structure and name identical to the source structure. Will be interesting to check if the code looks better with the new class CL_ABAP_CORRESPONDING.
But what I really miss since years in the area of MOVE-CORRESPONDING is a move corresponding from structure to class attributes and back. In other programming languages like Javascript there is no difference between structures and objects.
Especially when integrating old API into new OO coding or loading data from database into objects, usually structures are involved. But these structures are only used for a very short time and then transferred into object attributes. However today this has to be done one by one ... So when it would possible to move corresponding from a structure to attributes (assuming doing this in one statement is faster than having individual statements) this would be a very helpful feature.
Regards,
Ralf
thanks, pretty cool.
Is CL_ABAP_CORRESPONDING also available for 7.40 with a current (dck) kernel?
An ABAP class with a kernel?
Hello Horst,
thank you for the blog!
Is it possible to map a nested structure to a flat structure and vice versa?
Thanks!
If the structured components are convertible to the elementary components it should work.
(B.t.w. flat is not the opposite to nested but to deep)
Thank you for the quick reply!
Do you happen to have a simple example, like mapping of those two structures (a1->b1; a2->b2):
DATA:
BEGIN OF struct1,
a1 TYPE string VALUE 'a1',
BEGIN OF asub,
a2 TYPE string VALUE 'a2',
END OF asub,
END OF struct1,
BEGIN OF struct2,
b1 TYPE string,
b2 TYPE string,
END OF struct2.
Thank you very much!
This of course won't work due to incompatibility of the components ...
Hello Horst,
thank you for clarifying!
Hello Horst,
Thanks for the blog. Your blogs are always fascinating.
In continuation to this question,
I am left wondering if the following is feasible:
Moving of just field b2 of struct2, which is at level 0, to field a2, which is at level 1?
Thanks,
Ruchir
Writing this long code is only beneficial over CORRESPONDING operator if we have deep structures, is my understanding correct?
Thanks!