A tweet from Jon Reed @jonerp (http://twitter.com/jonerp) caught my eye the other day – “Good programmers write good code, but great programmers reuse the good programmers’ code”. Jon was actually referring to an SCN blog posting by Ivan Femia:
“Ten golden rules that help me every day. What about your experiences?”
The specified item was not found.
This and other recent postings on SDN made me think about a great experience I had with the ASSIGN statement in a BAdI recently.
This is a short but hopefully useful nugget of information about what you can do with the ASSIGN COMPONENT syntax and runtime type services (RTTS) from a practical perspective in a Netweaver 7 environment.
What is the ASSIGN statement?
The ASSIGN statement is used in conjunction with FIELD-SYMBOLS. I must confess to always being a little wary of FIELD-SYMBOLS and always have thought of them as basically pointers – as the official help says “dereferenced pointers in C”. However technically this isn’t strictly correct as this presentation from TechEd a few years ago indicates:
The correct explanation is that they are aliases which represent fields dynamically. Aside from that however I don’t intend to cover all aspects of this syntax – there are several variants and parameters to both ASSIGN and FIELD-SYMBOLS. The online help is very comprehensive in this area:
This blog will look at both the basic form and the ASSIGN COMPONENT syntax for addressing components of structured data objects dynamically. For the purpose of this blog and context ASSIGN means to reference or transfer something else and a field-symbol is where the referenced data object will reside.
Using ASSIGN in a practical context</p><p>Within development work there is often a requirement to check whether a field contains data. In cases where a field isn’t populated you might want to fill it with data from an alternative source or issue a message to the user informing them. The obvious way to do this is by using a simple IF statement to check whether the field is initial. This works fine in simple one or “fixed” scenario’s but what if the list of fields to be checked is more dynamic e.g. different fields should be checked depending upon certain scenario’s or if the requirement changes. An alternative approach is to determine the conditions up front and build your own transparent table to store the list of fields and the accompanying ‘selection logic’. Assuming the ‘selection’ field data is available in your program you can then read from your configuration table and use a dynamic ASSIGN statement to access it and perform checks.</p><p>In my scenario I have created a configuration table with the following key fields:</p><ul><li>Client (MANDT)</li><li>Table name (DDOBJNAME)</li><li>Field name (FIELDNAME)</li><li>Operating concern (ERKRS)</li><li>Distribution channel (VTWEG)</li><li>Sales Organisation (VKORG)</li></ul><p>This is a simple transparent Z table created using SE11 that will be maintainable functionally via SM30/the IMG. The fields which I will check are DDOBJNAME & FIELDNAME and all other fields that make up the key will be my ‘selection logic’.</p><p>!https://weblogs.sdn.sap.com/weblogs/images/251897282/assign_pic2.JPG|height=328|alt=config table screenshot|width=478|src=https://weblogs.sdn.sap.com/weblogs/images/251897282/assign_pic2.JPG|border=0!</p><p>The table contains some other fields however they are not important right now. Within my BAdI I will select all the data in this table that meets the operating concern, distribution channel and sales organisation key.</p><p>The data within my enhancement is contained within a complex structure IS_IOBJECT_SINGLE. This structure is actually a set type and so each component of it is a dictionary object /DBM/IOBJ_DATA_SINGLE_COM_S which can be referenced in my configuration table by the DDOBJNAME & FIELDNAME fields. </p><p>The SE11 dictionary view of this data type is (first 15 components shown):</p><p>!https://weblogs.sdn.sap.com/weblogs/images/251897282/assign_pic3.JPG|height=379|alt=SE11 dictionary view|width=606|src=https://weblogs.sdn.sap.com/weblogs/images/251897282/assign_pic3.JPG|border=0!</p><p>In the debugger the data type is called IS_IOBJECT_SINGLE and appears as:</p><p>!https://weblogs.sdn.sap.com/weblogs/images/251897282/assign_pic4.JPG|height=349|alt=debugger data type view|width=474|src=https://weblogs.sdn.sap.com/weblogs/images/251897282/assign_pic4.JPG|border=0!</p><p>Within my enhancement I use RTTS to get a class containing all the dictionary details of this structure. The structure IS_IOBJECT_SINGLE has the dictionary reference /DBM/IOBJ_DATA_SINGLE_COM_S and this is passed into the static method DESCRIBE_BY_NAME.</p><p>!https://weblogs.sdn.sap.com/weblogs/images/251897282/assign_pic5.JPG|height=218|alt=RTTS debugger view|width=599|src=https://weblogs.sdn.sap.com/weblogs/images/251897282/assign_pic5.JPG|border=0!</p><p>The object LINETYPE contains a wealth of information; attribute COMPONENTS probably being one of the most useful:</p><p>!https://weblogs.sdn.sap.com/weblogs/images/251897282/assign_pic6.JPG|height=305|alt=Linetype components debugger view|width=504|src=https://weblogs.sdn.sap.com/weblogs/images/251897282/assign_pic6.JPG|border=0!</p><p>Having selected the appropriate configuration from my new Z table I now want to check whether each of the fields specified in the table is populated or not. This will be done by reading the COMPONENTS table (in my example represented by internal table LT_COPA_CONFIG) and using ASSIGN COMPONENT to lookup the value.</p><p>!https://weblogs.sdn.sap.com/weblogs/images/251897282/assign_pic7.JPG|height=237|alt=Linetype lookup|width=601|src=https://weblogs.sdn.sap.com/weblogs/images/251897282/assign_pic7.JPG|border=0!</p><p>Having determined that the table (structure) name does exist in my complex structure I perform the ASSIGN in routine CHECK_FIELD_SINGLE.</p><p>At this stage we have determined that the structure we wish to analyse is contained within the specified complex structure IS_IOBJECT_SINGLE however we now need to:</p><ol><li>Ensure that the field exists within the structure (so far we’ve only ascertained that the table existed!)</li><li>Determine whether the structure-field contains a value.</li></ol><p>The ASSIGN COMPONENT syntax is used in conjunction with a field-symbol to get a reference to the data in our specified structure in the complex structure. This is effectively like going to a library shelf and pulling out a specific book – in this case the book was specified in our configuration table and the library shelf is the complex structure.</p><p>Notice that within this routine no dictionary references or anything that could change is “hard coded”. The field symbol where the data will exist is of TYPE ANY meaning any format can be accommodated.</p><p>!https://weblogs.sdn.sap.com/weblogs/images/251897282/assign_pic8.JPG|height=286|alt=ASSIGN COMPONENT in the debugger|width=597|src=https://weblogs.sdn.sap.com/weblogs/images/251897282/assign_pic8.JPG|border=0!</p><p>The objects <LF_IOBJ> and IS_IOBJECT_SINGLE-DBM_V_IMODEL now represent the same data:</p><p>!https://weblogs.sdn.sap.com/weblogs/images/251897282/assign_pic9.JPG|height=326|alt=Assignment graphic|width=687|src=https://weblogs.sdn.sap.com/weblogs/images/251897282/assign_pic9.JPG|border=0!</p><p>Having got a reference to the data in field-symbol <LF_IOBJ> the next stage is to construct the full structure-field reference. The original structure was called DBM_V_IMODEL however that is now referenced in <LF_IOBJ> and so I concatenate the field I wish to get on the end into a local variable LV_TAB_FIELD. A second field-symbol is then used to reference this field i.e. the data from it is transferred into the field-symbol <LF_FIELD>.</p><p>As is then often the case the final bit of code then still comes down to an IF statement!</p><p>!https://weblogs.sdn.sap.com/weblogs/images/251897282/assign_pic10.JPG|height=248|alt=An IF statement as ever|width=598|src=https://weblogs.sdn.sap.com/weblogs/images/251897282/assign_pic10.JPG|border=0!</body>