<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>SAP Experts: VMware Virtualization &#124; Consulting &#124; Integration - DataXstream &#187; SAP ABAP Blog</title>
	<atom:link href="http://www.dataxstream.com/category/sap-consultants-blog/sap-technical/sap-abap-blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.dataxstream.com</link>
	<description>SAP Certified Consultants</description>
	<lastBuildDate>Sat, 04 Feb 2012 05:00:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Web Dynpro Basics: Context and Binding</title>
		<link>http://www.dataxstream.com/2012/01/web-dynpro-basics-context-and-binding/</link>
		<comments>http://www.dataxstream.com/2012/01/web-dynpro-basics-context-and-binding/#comments</comments>
		<pubDate>Mon, 30 Jan 2012 21:22:04 +0000</pubDate>
		<dc:creator>Michael Champion</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[SAP ABAP Blog]]></category>
		<category><![CDATA[SAP ABAP Performance]]></category>
		<category><![CDATA[SAP Basis Blog]]></category>
		<category><![CDATA[SAP Basis Performance]]></category>
		<category><![CDATA[SAP Interface Blog]]></category>
		<category><![CDATA[SAP PI Blog]]></category>
		<category><![CDATA[SAP Technical]]></category>
		<category><![CDATA[DataXstream]]></category>
		<category><![CDATA[SAP]]></category>
		<category><![CDATA[Web Dynpro]]></category>

		<guid isPermaLink="false">http://www.dataxstream.com/?p=10302</guid>
		<description><![CDATA[This is for those who are new to Web Dynpro programming. Here is an explanation of how to set up a Web Dynpro application using the context and binding the context to User Interface (UI) elements of the application. This is only a basic explanation to help set a foundation for understanding Web Dynpro programming. [...]]]></description>
			<content:encoded><![CDATA[<p>This is for those who are new to Web Dynpro programming. Here is an explanation of how to set up a Web Dynpro application using the context and binding the context to User Interface (UI) elements of the application. This is only a basic explanation to help set a foundation for understanding Web Dynpro programming. The 3 basic elements of a Web Dynpro application are windows, views and the context. The window is simply a container for a view. To assign a view to a window expand the views and windows under the section labeled ‘Object Name.’ Double click on a window and then drag and drop the view into the window.<span id="more-10302"></span><br />
<a href="http://www.dataxstream.com/wp-content/uploads/1-web-dynpro.jpg" rel="shadowbox[sbpost-10302];player=img;"><img class="alignnone  wp-image-10315" title="1 web dynpro" src="http://www.dataxstream.com/wp-content/uploads/1-web-dynpro-1024x611.jpg" alt="" width="617" height="367" /></a><br />
The views hold the visual content (i.e. buttons, tables, headers). Once a view is created and populated with UI elements, the text values of some of these elements can be hard coded (via the UI element’s properties)<br />
<a href="http://www.dataxstream.com/wp-content/uploads/2-web-dynpro.jpg" rel="shadowbox[sbpost-10302];player=img;"><img class="alignnone  wp-image-10314" title="2 web dynpro" src="http://www.dataxstream.com/wp-content/uploads/2-web-dynpro-1024x554.jpg" alt="" width="617" height="334" /></a><br />
Or they can be populated dynamically during runtime. Certain elements can ONLY be populated during runtime, such as a table. The text of a button can be set by entering a string value into the ‘text’ property of the element when in the layout tab of the view, for example ‘Hello World’.</p>
<p><a href="http://www.dataxstream.com/wp-content/uploads/3-web-dynpro.jpg" rel="shadowbox[sbpost-10302];player=img;"><img class="alignnone  wp-image-10316" title="3 web dynpro" src="http://www.dataxstream.com/wp-content/uploads/3-web-dynpro-1024x666.jpg" alt="" width="617" height="402" /></a></p>
<p>For the element that’s text cannot be hardcoded or the element that’s visibility needs to change during runtime, the context needs to be used. The data that is seen on the screen is not stored within the web browser itself. The Web Dynpro application makes calls to the server to retrieve data to be displayed. This is where the context comes into play. The context is the memory on the server that stores data for the Web Dynpro application. When setup correctly a context can hold tables, structures or single element variables. Here is an example of how to build a context and then make method calls to read or set the context.</p>
<p>Select the ‘Context’ tab. Right click on the context node and select ‘Create’ -&gt; ‘Node’ and fill out the fields according to the picture below.<a href="http://www.dataxstream.com/wp-content/uploads/4-web-dynpro.jpg" rel="shadowbox[sbpost-10302];player=img;"><img class="alignnone  wp-image-10308" title="4 web dynpro" src="http://www.dataxstream.com/wp-content/uploads/4-web-dynpro-1024x682.jpg" alt="" width="617" height="411" /></a></p>
<p>Right click on the BUTTON_PROPERTIES node and select ‘Create’ -&gt; ‘Attribute.’<br />
<a href="http://www.dataxstream.com/wp-content/uploads/5-web-dynpro.jpg" rel="shadowbox[sbpost-10302];player=img;"><img class="alignnone  wp-image-10309" title="5 web dynpro" src="http://www.dataxstream.com/wp-content/uploads/5-web-dynpro-1024x682.jpg" alt="" width="617" height="410" /></a></p>
<p>Now we have created an attribute in the context that will hold a string value. By the names I have given to the node and the attribute you can guess that this node will hold any attributes related to the button we created. The attribute that we created will be used to hold text value of the button.</p>
<p>Now that the context attribute has been created, let’s fill it with a value. Go back to the button properties under the ‘Layout’ tab and find the ‘onAction’ properties under ‘Events.’ Click the create button, it looks like a white piece of paper with the top right edge folded down, and fill in the fields as below.<br />
<a href="http://www.dataxstream.com/wp-content/uploads/6-web-dynpro.jpg" rel="shadowbox[sbpost-10302];player=img;"><img class="alignnone  wp-image-10310" title="6 web dynpro" src="http://www.dataxstream.com/wp-content/uploads/6-web-dynpro-1024x666.jpg" alt="" width="617" height="401" /></a><br />
Double click on the name of the new action we just created, SHOW_TEXT and this will take you to the methods tab. Here we are going to use the Web Dynpro Code Wizard to set the value of the attribute.<br />
Click on the Web Dynpro Code Wizard icon (or Ctrl +F7), select ‘Read’, click and select the attribute that was created, TEXT. (Illustrated Below)<br />
<a href="http://www.dataxstream.com/wp-content/uploads/7-web-dynpro.jpg" rel="shadowbox[sbpost-10302];player=img;"><img class="alignnone  wp-image-10311" title="7 web dynpro" src="http://www.dataxstream.com/wp-content/uploads/7-web-dynpro-1024x611.jpg" alt="" width="617" height="368" /></a><br />
Now repeat the same steps starting with the Web Dynpro Code Wizard except this time select ‘Set’ instead of ‘Read.’ Each time the Web Dynpro Code Wizard is used DATA variables are created.</p>
<p><strong>Note: If there are multiple attributes within a node, all of the attributes can be read or set at once by selecting the node.</strong></p>
<p>After using the Web Dynpro Code Wizard the second time we now have two copies of the data variables that will not compile. Select the second set and delete them and in place put the following code:<br />
<a href="http://www.dataxstream.com/wp-content/uploads/7.1-web-dynpro.jpg" rel="shadowbox[sbpost-10302];player=img;"><img class="alignnone size-full wp-image-10313" title="7.1 web dynpro" src="http://www.dataxstream.com/wp-content/uploads/7.1-web-dynpro.jpg" alt="" width="717" height="693" /></a><br />
Now if the application was tested the value of the attribute TEXT would be changed  between ‘Hide Text’ and ‘Show Text’ every time the button is pushed.</p>
<p>That is the rundown of how to build, read and set the context’s nodes and attributes. Now the context needs to be linked or ‘bound’ to the UI elements. Go back to the Layout tab and select the button. Under the properties find the ‘Text’ property. Click the yellow box to the right of the property and select the attribute to create the binding .</p>
<p><strong>Binding</strong></p>
<p>Binding is linking the data in the context to the UI elements. Here we have created an attribute that holds text. The ‘Text’ property of the button is set to the value within that property. Activate the Web Dynpro Component, create an application and test it.</p>
<p>For a little extra practice, add a TextView by dragging and dropping into the layout or right clicking on ROOTUIELEMENTCONTAINER and selecting ‘Insert Element.’ In the properties section set the Text value to ‘Now you see me!’ Create another node and attribute for the TextView by going to the ‘Context’ tab and right clicking on the ‘Context’ node and selecting ‘Create’ -&gt; ‘Node’. Then create the attribute with the properties below.<br />
<a href="http://www.dataxstream.com/wp-content/uploads/8-web-dynpro.jpg" rel="shadowbox[sbpost-10302];player=img;"><img class="alignnone  wp-image-10312" title="8 web dynpro" src="http://www.dataxstream.com/wp-content/uploads/8-web-dynpro-1024x666.jpg" alt="" width="617" height="401" /></a></p>
<p>Go to the ‘Methods’ tab and go into the method we was worked on earlier, ONACTIONSHOW_TEXT. Place the cursor after the ‘if’ statement that was put in, approximately line 33. Use the code wizard to set the new context we made. Then cut and pasted the DATA declarations just created and move them up to the top of the code. Then edit the ‘if’ statement to look like this:<br />
<a href="http://www.dataxstream.com/wp-content/uploads/9-web-dynpro.png" rel="shadowbox[sbpost-10302];player=img;"><img class="alignnone  wp-image-10317" title="9 web dynpro" src="http://www.dataxstream.com/wp-content/uploads/9-web-dynpro.png" alt="" width="504" height="370" /></a></p>
<p>Return to the ‘Layout’ tab, select the TextView and set the ‘Visible’ property to the new attribute. Activate the Web Dynpro Component and test the application.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dataxstream.com/2012/01/web-dynpro-basics-context-and-binding/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>It&#8217;s SAP Upgrade Time! Do You Know Where Your Customizations Are? Part 3.</title>
		<link>http://www.dataxstream.com/2011/11/sap-upgrade-and-customizations-3/</link>
		<comments>http://www.dataxstream.com/2011/11/sap-upgrade-and-customizations-3/#comments</comments>
		<pubDate>Thu, 03 Nov 2011 14:15:54 +0000</pubDate>
		<dc:creator>Mike Salvo</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[SAP ABAP Blog]]></category>
		<category><![CDATA[SAP Functional]]></category>
		<category><![CDATA[SAP Project Management]]></category>
		<category><![CDATA[SAP Strategy]]></category>
		<category><![CDATA[SAP Technical]]></category>
		<category><![CDATA[SAP Testing]]></category>
		<category><![CDATA[DataXstream]]></category>
		<category><![CDATA[Mike Salvo]]></category>
		<category><![CDATA[SAP]]></category>
		<category><![CDATA[sap upgrade]]></category>
		<category><![CDATA[upgrade cost]]></category>
		<category><![CDATA[upgrade risk]]></category>

		<guid isPermaLink="false">http://www.dataxstream.com/?p=3141</guid>
		<description><![CDATA[In my final post on this topic, I will discuss some of the techniques that I use to “discover” information about customizations in an SAP system, even in the absence of any documentation.  The information available to be discovered may include such details as the object name, object type, user name of the person who [...]]]></description>
			<content:encoded><![CDATA[<p>In my final post on this topic, I will discuss some of the techniques that I use to “discover” information about customizations in an SAP system, even in the absence of any documentation.  The information available to be discovered may include such details as the object name, object type, user name of the person who made the last modification, date and time of the last modification, usage statistics, where-used, and for code-based objects, even the versions and their code differences.</p>
<p><span id="more-3141"></span></p>
<h3>Discovering Direct Modifications of SAP Standard Objects – One Example</h3>
<p>As I discussed in a previous post on this topic, direct modification of SAP standard objects within the SAP namespace carries a high risk in an upgrade project.  It would be very valuable to be able to identify some details about these objects, so that further analysis could be performed to determine their disposition in the upgrade.</p>
<p>Modification of standard SAP objects typically requires that a modification registration key be obtained for that object from the SAP SSCR facility.   The SSCR facility (SAP Software Change Registration) is a procedure which registers all manual changes to SAP sources and SAP Dictionary Objects.  With a valid and authorized OSS ID for an SAP system, you can go to the SAP Support Portal on the web and view the SAP objects that were registered for modification by that OSS ID.  If there are multiple OSS IDs for any SAP system, make sure that you check all of them to capture all objects registered by all of the authorized OSS IDs for an SAP system.  Press the “Objects Registered by Me” button to view a list of the registered objects.</p>
<p><img class="alignnone" title="SSCR - SAP Software Change Registration" src="http://www.dataxstream.com/wp-content/uploads/2009/11/11.bmp" alt="SSCR - SAP Software Change Registration" width="555" height="411" /></p>
<p>Another place that you can look for this information is directly within SAP.  Table ADIRACCESS stores the registration keys which were obtained from SAP, and which were entered by the developer when the object was to be modified for the very first time.  This entry shown below from table ADIRACCESS shows that function group SCPRPS was registered with SAP for modification.</p>
<p><img class="size-full wp-image-3145 alignnone" title="ADIRACCESS" src="http://www.dataxstream.com/wp-content/uploads/2009/11/21.bmp" alt="ADIRACCESS records" width="554" height="173" /></p>
<p>Registering an object for modification does not mean that the object was actually modified.<br />
What additional evidence can we discover that would show that the object was, in fact, modified?   And, since a function group contains many objects, can we determine exactly which object or objects were modified?</p>
<p>With a little bit of forensic analysis, we can discover the specific object within the function group that was modified, the user name of the programmer who last modified the object, date of the last modification, and the line-by-line source code differences.</p>
<p>If you are familiar with the structure of function groups, you already know that they may contain many function modules, and that the source code for each function module resides within its own include file.  At the moment, we know that the function group name is SCPRPS, but we do not have the list of function modules within that function group.</p>
<p>To obtain that list, we can use the SAP function module FUNCTION_SELECT_TFDIR.<br />
The result list is shown here:</p>
<p><img class="size-full wp-image-3146 alignnone" title="FUGR SCRPRS records" src="http://www.dataxstream.com/wp-content/uploads/2009/11/31.bmp" alt="FUGR SCRPRS records" width="624" height="453" /></p>
<p>So which, if any, of these has been modified?  To determine this, we need to find all of the rows in table TRDIR where the NAME field is equal to the PNAME entries listed above.</p>
<p>Here is an excerpt from SAP table TRDIR for SAP object names that begin with the characters LSCPRPSU:</p>
<p><img class="size-full wp-image-3148 alignnone" title="LSCRPR* objects" src="http://www.dataxstream.com/wp-content/uploads/2009/11/42.bmp" alt="LSCRPR* objects" width="624" height="302" /></p>
<p>Note that for all of these objects, which are not in the customer namespace, the Author Username field (TRDIR_CNAM) is ‘SAP’.  Also note that for most of the entries listed here, the Last Changed By user name field (TRDIR_UNAM) is also ‘SAP’, except for one row, where the Last Changed By username field is not ‘SAP’.  From this row, we can see that include file LSCPRPSU36 was last modified by user DXSDEV on 10/19/2009.</p>
<p>If we look back at the result list of FUNCTION_SELECT_TFDIR and find the row where the field PNAME is equal to LSCPRPSU36, we can see that the name of the modified function module is SCPR_PRSET_CT_IMPORT_INDUSTRY.</p>
<h3>Exactly What Changes Were Implemented?</h3>
<p>By going to the Version Management Utility for this function module, we can see what the various versions of the code contained.  The Version Management Utility will also show us the transport request numbers, date and time, and username for each version of the code.  The Version Management Utility also has a code comparison tool which will highlight the line-by-line differences between versions of the source code.</p>
<p>Here is an excerpt from the side-by-side source code comparison utility which shows the modified version on the left side and the original version on the right side.  Fortunately, in this instance, the programmer left excellent notes indicating that a correction instruction from an OSS note was being applied.</p>
<p><img class="size-full wp-image-3147 alignnone" title="Modified Code" src="http://www.dataxstream.com/wp-content/uploads/2009/11/51.bmp" alt="Modified Code" width="705" height="117" /></p>
<h3>What Are the Discovery Possibilities?</h3>
<p>The manual example described above showed how to discover and analyze customizations that had been applied to a single SAP standard object.  But what if the customizations number in the hundreds or even thousands?  What about all of the customizations that were built entirely within the customer namespace?</p>
<p>It is possible to discover hundreds or even thousands of customizations regardless of which namespace they were developed in.  The key is automation, understanding that this information already resides within SAP waiting to be discovered, and more importantly, understanding the meaning of the discovered information.  I have already developed an ABAP discovery program which will mine, analyze, and report data about the following customized objects:</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td width="319">ABAP Programs</td>
<td valign="top" width="319">Basic IDOCs</td>
</tr>
<tr>
<td valign="top" width="319">Function Modules</td>
<td valign="top" width="319">IDOC Extensions</td>
</tr>
<tr>
<td valign="top" width="319">Function Groups</td>
<td valign="top" width="319">Message Types</td>
</tr>
<tr>
<td valign="top" width="319">Class Definitions</td>
<td valign="top" width="319">Process Types Inbound</td>
</tr>
<tr>
<td valign="top" width="319">BADI Implementations</td>
<td valign="top" width="319">Process Types Outbound</td>
</tr>
<tr>
<td valign="top" width="319">Dictionary Domains</td>
<td valign="top" width="319">SAPSCRIPT FORMS</td>
</tr>
<tr>
<td valign="top" width="319">Dictionary Data Types</td>
<td valign="top" width="319">Smartforms Forms</td>
</tr>
<tr>
<td valign="top" width="319">Dictionary Transparent Tables</td>
<td valign="top" width="319">Smartforms Styles</td>
</tr>
<tr>
<td valign="top" width="319">Dictionary Structures</td>
<td valign="top" width="319">Packages</td>
</tr>
<tr>
<td valign="top" width="319">Dictionary Views</td>
<td valign="top" width="319">Logical Databases</td>
</tr>
<tr>
<td valign="top" width="319">Dictionary Append Structures</td>
<td valign="top" width="319">FICO Client Dependent and Independent Exits</td>
</tr>
<tr>
<td valign="top" width="319">Dictionary Append Fields</td>
<td valign="top" width="319">Message Classes and Messages</td>
</tr>
<tr>
<td valign="top" width="319">Search Helps</td>
<td valign="top" width="319">Number Ranges</td>
</tr>
<tr>
<td valign="top" width="319">CMOD User Exits</td>
<td valign="top" width="319">Authorization Objects</td>
</tr>
<tr>
<td valign="top" width="319">User Exits for the SD Module (MV45AF*)</td>
<td valign="top" width="319">Authorization Fields</td>
</tr>
<tr>
<td valign="top" width="319">Requirements Definitions (transaction VOFM)</td>
<td valign="top" width="319">SPA/GPA Parameters</td>
</tr>
</tbody>
</table>
<hr />
<h2>More Discovery – Usage Statistics and Where-Used</h2>
<h3>Customization Usage Statistics</h3>
<p>The goal of customization usage statistics analysis is to discover the usage frequency of customized objects.  The usage discovery may show usage anywhere from several times daily by key users, to none when analyzed over a long time period.   Since most companies really do not want to incur the cost and the risk of moving an unneeded customization into the upgrade system, objects which show no usage over long periods of usage history become targets.  Care must be used here, as some transactions are exercised only quarterly, semi-annually, or annually.  I always recommend letting the business process owner make the final decision to eliminate any customization object in the upgrade.</p>
<p>SAP keeps track of usage statistics, and this data is available for you to analyze.  You will need to check what facility is available for your particular SAP system, as the transaction codes and programs differ among various versions of SAP.   The amount of data stored within SAP is configurable, and is usually set to a small date range.  Some companies that want to analyze the statistics over longer time periods actually download and store the statistics data in their own external databases.</p>
<h3>Customization Where-Used</h3>
<p>Like usage statistics, the goal of customization where-used analysis is to discover customized objects that are orphan or not being used.  What about that custom data type that is not used in any table or structure?  What about that function module that shows an empty list when you click the where-used icon in the function builder?</p>
<p>To properly perform a where-used analysis, it is important to understand all of the various possible uses for an ABAP object.  For example, here is the selection screen of possible uses that is presented by the ABAP Dictionary when you click the where-used icon to determine the where-used list for a data table:</p>
<p><img class="size-full wp-image-3149 alignnone" title="Where-Used" src="http://www.dataxstream.com/wp-content/uploads/2009/11/61.bmp" alt="Where-Used" width="260" height="484" /></p>
<p>And what about that custom function module, which I alluded to earlier, which shows a completely empty where-used list?  Perhaps it is a remote-enabled function module that was installed by, and is currently being called by an external third-party package.   Or, perhaps it is linked to an SAP EDI inbound or outbound process code.  It is really important to be able to properly interpret the data being presented and to not draw any hasty conclusions.</p>
<h3>ABAP Programs Where-Used Analysis Example</h3>
<p>In the ABAP workbench, SAP provides a where-used facility, which reports the various areas where a single selected object is used.  For a discovery project, you may want to automate this facility to analyze groups of ABAP objects (e.g. all custom ABAP programs, all custom tables, etc.).</p>
<p>Here is an ABAP programs where-used analysis example to help illustrate how a where-used analysis might be utilized.</p>
<p>Your automated where-used analysis program to analyze custom ABAP programs reports fifteen custom programs which show no usage in any of the following areas:</p>
<p><img class="size-full wp-image-3150 alignnone" title="Where-Used ABAP Program" src="http://www.dataxstream.com/wp-content/uploads/2009/11/72.bmp" alt="Where-Used ABAP Program" width="287" height="234" /></p>
<p>A quick analysis shows that all of these fifteen programs are simple reports.  Since users typically execute their reports via transaction codes, you wonder how these fifteen programs could ever possibly be executed without transaction codes.</p>
<p>You further analyze the SAP job scheduler data as far back as possible and find that only ten of these ABAP programs were ever scheduled in a batch job.  Some of these were scheduled very recently, and some have not been scheduled for a long time (another thread of evidence that we will need to pursue).  This leaves five ABAP programs with no apparent means of being executed.</p>
<p>As further evidence, you perform a cross-check against the usage statistics report and find that two of these five ABAP programs show no usage.</p>
<p>Armed with this analysis, you are now ready to meet with the business process owners to discuss the disposition of the objects on your short list.</p>
<p>A salient point here is that you will need to gather your evidence from several different analysis sources to help paint the most accurate picture about the possible disposition of customized objects.</p>
<h2>Summary</h2>
<p>Throughout all three parts of this post, I have stressed that customizations, while necessary, add risk and cost to an upgrade project.  And customizations that are not necessary or built poorly without the constraints of best-practice controls can add high levels of risk and cost.  Here are some general guidelines to follow:</p>
<p>Many companies and their auditors consider a well-controlled and secure ERP system to be a fundamental component that is vital to the success of the business.   They recognize that an out-of-control ERP system can easily paralyze a company for extended periods of time.  With this in mind, implement and enforce best-practice controls and standards to make sure that future customizations are reviewed, approved, built, tested, documented, and implemented properly.  This may already be an internal or external audit requirement, so check with your inside and outside auditors to make sure that your controls meet the auditing requirements.</p>
<p>Periodically review, audit, and amend your best-practice controls to make sure that they are still effective in supporting the needs of the business; and that both internal staff and external consultants are in compliance of these controls.</p>
<p>Know your customizations.  Know where they are, why they are, and what they do.  Whenever feasible, it is most efficient to eliminate ABAP object customizations, especially any that were performed within the SAP namespace, and any that are not really needed because they can be implemented within standard SAP.</p>
<p>The degree of risk and cost depends on the specific type of customization that was performed.  Establish a formal review board to own the customization approval process.  Understand that approving a customization also means approving the risk and the cost burdens.  Some companies consider this to be so significant, that they include a high-level business executive as a default member of the review board.</p>
<p>Set and enforce a policy making ABAP object customization the last resort, only after all other options have been thoroughly researched and exhausted.  Here are some examples:</p>
<ol>
<li>Research forums, blogs, become active in user groups, etc. to see how other companies might also be implementing the business function that you require.</li>
<li>Find and use customer and user exits instead of directly modifying objects in the SAP namespace.</li>
<li>Determine, for example, how to implement and maintain that complex pricing procedure using the pricing condition tables instead of writing custom code and building custom tables.</li>
</ol>
<p><strong>Share Your Experience</strong>.</p>
<p>Once again, I look forward to hearing from our readers to reply to this post with their own experience with customizations, best-practice standard and policies, and success stories illustrating how your company transitioned to best-practice controls.</p>
<p style="padding-left: 30px; padding-right: 30px;"><em>[Editor's Note] This blog is third of a multi-part series:</em></p>
<ol>
<li><a href="http://www.dataxstream.com/2009/11/sap-upgrade-and-customizations-1/">Part 1</a></li>
<li><a href="http://www.dataxstream.com/2009/11/sap-upgrade-and-customizations-2/">Part 2</a></li>
<li><a href="http://www.dataxstream.com/2009/11/sap-upgrade-and-customizations-3/">Part 3</a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.dataxstream.com/2011/11/sap-upgrade-and-customizations-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>It&#8217;s SAP Upgrade Time!  Do You Know Where Your Customizations Are?  Part 2.</title>
		<link>http://www.dataxstream.com/2011/11/sap-upgrade-and-customizations-2/</link>
		<comments>http://www.dataxstream.com/2011/11/sap-upgrade-and-customizations-2/#comments</comments>
		<pubDate>Tue, 01 Nov 2011 14:15:43 +0000</pubDate>
		<dc:creator>Mike Salvo</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[SAP ABAP Blog]]></category>
		<category><![CDATA[SAP Upgrade Blog]]></category>
		<category><![CDATA[ABAP]]></category>
		<category><![CDATA[ABAP Code Objects]]></category>
		<category><![CDATA[ABAP development]]></category>
		<category><![CDATA[DataXstream]]></category>
		<category><![CDATA[Mike Salvo]]></category>
		<category><![CDATA[SAP]]></category>
		<category><![CDATA[sap upgrade]]></category>
		<category><![CDATA[Upgrade]]></category>
		<category><![CDATA[upgrade cost]]></category>
		<category><![CDATA[upgrade risk]]></category>
		<category><![CDATA[upgrade tips]]></category>

		<guid isPermaLink="false">http://www.dataxstream.com/?p=2983</guid>
		<description><![CDATA[In my last post on this topic, I discussed two negative effects of customizations in an upgrade project – risk and cost.  I also discussed an obvious reason to eliminate unnecessary customization – the mitigation of risk and cost. In this post, we will look at some of the customization areas which add risk and [...]]]></description>
			<content:encoded><![CDATA[<p>In my <a href="http://www.dataxstream.com/2009/11/sap-upgrade-and-customizations-1/">last post</a> on this topic, I discussed two negative effects of customizations in an upgrade project – risk and cost.  I also discussed an obvious reason to eliminate unnecessary customization – the mitigation of risk and cost.</p>
<p>In this post, we will look at <em><span style="text-decoration: underline;">some</span></em> of the customization areas which add risk and the cost to an upgrade project.</p>
<p><span id="more-2983"></span></p>
<h3>1. Direct Modifications to SAP Standard Objects</h3>
<p>Direct modifications to SAP standard objects bear the highest risk.  During the upgrade, these modifications will be lose&#8211;either because they will be overwritten by their respective upgraded SAP standard objects; or because these objects no longer exist and are not used by standard SAP in the upgrade system.</p>
<p><strong> <span style="font-weight: normal; background-color: #ffffff;">Typically, there are two reasons for performing direct modifications to SAP standard objects:</span></strong></p>
<ol>
<li>The application of authorized individual OSS corrections to fix problems.</li>
<li>Direct customer modification to provide business process enhancements.</li>
</ol>
<h4 style="padding-left: 30px;">1.1. Application of Individual OSS Corrections and Support Packs</h4>
<p style="padding-left: 30px;">Individual OSS corrections are patches supplied by SAP to fix recognized problems with SAP objects.  Sometimes, individual OSS correction instructions are included and delivered within a specific level of support packs.   That means that applying support packs to the specified level will apply the desired correction, and manual intervention is not needed.  Sometimes OSS correction instructions are not yet included in any specific level of support packs, and these will need to be applied either manually or with the SAP Note Assistant.</p>
<p style="padding-left: 30px;">It is important to carefully analyze the validity range of an OSS note to determine both how it was applied in the legacy system, and how it is to be applied in the upgrade system.  This analysis will help determine how far to patch the upgrade system to make sure that the desired corrections are included in the upgrade system.   Any needed correction that exists at a patch level beyond the highest patch level in the upgrade system will need to be addressed  manually or with the SAP Note Assistant.</p>
<p style="padding-left: 30px;">The decision of which support pack levels should be applied to the upgrade system must be made carefully.  One approach is to apply the highest level of support packs that are available.    The rationale for applying the latest available support packs is to insure that the most recent problem fixes are applied to the upgrade system.  This is a two-edged sword, as the most recent  support packs may also introduce other problems into the upgrade system.</p>
<h4 style="padding-left: 30px;">1.2. Direct Customer Modification of SAP Standard Objects to Provide Business Process Enhancements</h4>
<p style="padding-left: 30px;">Direct modifications of SAP standard objects to provide enhancements are most costly and bear the highest level of risk.  While direct modifications of SAP standard objects may have been technically expedient at the time of implementing the enhancement, they will always require additional work effort and analysis at upgrade time to determine:</p>
<ol>
<li>Whether or not the functionality provided by the enhancement is still required by the business.</li>
<li>Whether or not the functionality provided by the enhancement is already included in the upgrade system as standard SAP.  You will need the help of functional subject matter experts here.</li>
<li>Whether or not the modified SAP object still exists in the upgrade system.</li>
<li>How to move these required enhancements into the customer namespace, using the SAP preferred enhancement procedures.  Moving these types of enhancements to the customer namespace also moves them from the very costly and highest risk category to a lower cost and lower risk category.</li>
</ol>
<h3>2. Custom Interfaces</h3>
<p>Custom interfaces are loaded with opportunity for high upgrade risk.  Take, for example, the SAP standard IDOC Basic Type, which was copied as the baseline for an enhanced customized basic type containing additional custom segments and fields.  In the upgrade system, a new version of this SAP standard IDOC Basic Type may now contain additional segments and fields.</p>
<p>Likewise, the associated standard processing module for that standard basic type, which was copied as the baseline for an enhanced processing module to handle the custom segments and fields of the enhanced custom basic type, may also have changed in the upgrade to accommodate the new standard IDOC version.</p>
<p>So, in the upgrade system, especially if you need to implement the new upgrade IDOC version, it may be necessary to start with the new standard basic type and standard processing module, and reapply the customizations.</p>
<h3>3. ABAP Code Objects</h3>
<p>Of all customized objects discovered in most SAP systems, ABAP Code objects are the most numerous.  These objects include classes, methods, function modules, report programs, dialog programs, and include files which support the all of the other ABAP object types.</p>
<p>At greatest risk are the SAP standard ABAP code objects which were modified directly in the SAP namespace; and those that were copied into the customer namespace and subsequently modified.<strong> </strong>This is because the standard SAP code objects may have changed in the upgrade.    These changes can range anywhere from simple error corrections to complete process and code redesigns.  In these instances, each modified object must be compared to its counterpart in the upgrade system to determine its existence, and the nature and extent of what might have changed.   If the customization is still needed in the upgrade system, and to stay current with the enhanced standard code, it is probably best to start with the upgrade standard code and reapply the customizations.</p>
<p>ABAP code objects that were developed entirely in the customer namespace (not copied from standard SAP code) are usually low on the risk ladder.  Problems occur when data selected by these objects has moved elsewhere or behaves differently in the upgrade system, when ABAP constructs used are now obsolete in the upgrade system, or when standard called functions are changed in the upgrade system.</p>
<p>Ultimately, the business must decide why SAP standard code was directly modified, why SAP standard code was copied into the customer namespace and modified, why custom code was developed entirely within the customer namespace, whether or not any of these modifications are needed, and how they might be implemented differently in the upgrade system.  This evaluation presents another opportunity to remove some rocks from the customization rock bag.</p>
<h3>4. Automated Standard SAP Transactions</h3>
<p>Custom ABAP programs which automate standard SAP transactions bear an above-average risk.  This is because the behavior of some SAP transactions may have changed in the upgrade.  These changes can be manifest in the functional performance of the transaction, the technical location and existence of data fields on screens, screen field properties, IMG configuration specific to the transaction, the transaction code associated with the transaction, or even the existence of the transaction or an equivalent in the upgrade system.  The nature and the extent of the changes to the transaction in the upgrade system will determine the amount of effort needed to automate it.</p>
<p>Also, if an “old” SAP transaction has been replaced by a “new” upgraded equivalent, it is usually wise to make the change to the new transaction at upgrade time.  At some point in the future, the “old” version of the transaction will become obsolete and no longer useable or supported.</p>
<h3>5. Data Dictionary Customizations</h3>
<p>Many customizing projects within SAP require the storage and manipulation of data that is not included in the standard SAP dictionary.   One way in which these requirements can be addressed is by building complete custom transparent tables and data structures.  Another way is by adding append structures and append fields to existing standard SAP tables.  With either approach, it is always an excellent idea to evaluate the need to move these customizations into the upgrade; and another opportunity to lighten the customizing bag of rocks.</p>
<h3>6. Customer and User Exits</h3>
<p>Customer and user exits are provided by SAP as the SAP-approved mechanism for enhancing standard functionality.  Enhancements performed within these boundaries are guaranteed by SAP to bear low technical risk in an upgrade situation.  While SAP guarantees that the custom code will arrive technically intact in the upgrade system, functional analysis must still be performed to determine the continued need for the enhancement in the upgrade system.</p>
<p>Any enhancement implemented in a customer or user exit that is either functionally covered or determined to be unnecessary in the standard upgrade system should be retired.  This is consistent with the goal of lightening the load in the bag of rocks.  Since a customer or user exits may implement several different enhancements, take extra care to make sure that only the right code or other objects are retired.</p>
<h3>7. The Environmental Effects &#8211; Operating System Change</h3>
<p>OK, changing the operating system during an upgrade project is not customization of SAP objects.  But it does add risk and cost to the project.</p>
<p>Why?</p>
<p>If the upgrade operating system changes from UNIX to Windows or vice versa, then any ABAP program or interface which reads or writes a data file to an operating system folder must be changed.  The changes needed to these ABAP programs are very narrow in scope,  and reflect the manner in which the operating system specifies its file paths.  Additional BASIS work, such as determining the proper file system authorizations, may also be needed.</p>
<p>Using the SAP logical file name facility can help enormously by removing the need to make changes to hard-coded file names and path names in many different ABAP programs.</p>
<h3>Share Your Experience</h3>
<p>At the top of this post, I stated that I would discuss <span style="text-decoration: underline;">some </span>of the customization areas which add risk and cost to an upgrade project.  I look forward to hearing from our readers to reply to this post with their own experience with customizations, how they were handled, and how this affected an upgrade project.</p>
<p>In my next post on this topic, I will reveal some of the techniques I use to &#8220;discover&#8221; customizations, even in the absence of documentation.</p>
<p style="padding-left: 30px; padding-right: 30px;"><em>[Editor's Note] This blog is the second of a multi-part series:</em></p>
<ol>
<li><a title="It’s SAP Upgrade Time!  Do You Know Where Your Customizations Are?  Part 1." href="http://www.dataxstream.com/2009/11/sap-upgrade-and-customizations-1/">Part 1</a></li>
<li><a href="http://www.dataxstream.com/2009/11/sap-upgrade-and-customizations-2/">Part 2</a></li>
<li>Part 3</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.dataxstream.com/2011/11/sap-upgrade-and-customizations-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Build an RFC Client with NCo 3.0 &#8211; A Step-By-Step Guide</title>
		<link>http://www.dataxstream.com/2011/08/nco-3-rfc-client-step-by-step/</link>
		<comments>http://www.dataxstream.com/2011/08/nco-3-rfc-client-step-by-step/#comments</comments>
		<pubDate>Tue, 16 Aug 2011 14:15:32 +0000</pubDate>
		<dc:creator>Craig Stasila</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[SAP ABAP Blog]]></category>
		<category><![CDATA[SAP Interface Blog]]></category>
		<category><![CDATA[SAP Technical]]></category>
		<category><![CDATA[.Net Connector]]></category>
		<category><![CDATA[Craig Stasila]]></category>
		<category><![CDATA[DataXstream]]></category>
		<category><![CDATA[NCo]]></category>
		<category><![CDATA[NCo 3.0]]></category>
		<category><![CDATA[SAP .Net Connector]]></category>

		<guid isPermaLink="false">http://www.dataxstream.com/?p=8576</guid>
		<description><![CDATA[The SAP .Net Connector 3.0 (NCo 3.0) offers many improvements over the 2.0 version of that product. Unfortunately, SAP no longer offers example .NET code.  This blog attempts to fill that gap by describing how to build a simple RFC Client using SAP .Net Connector (NCo) 3.0.  Click here to request a .zip file containing a [...]]]></description>
			<content:encoded><![CDATA[<p>The SAP .Net Connector 3.0 (NCo 3.0) offers many improvements over the 2.0 version of that product. Unfortunately, SAP no longer offers example .NET code.  This blog attempts to fill that gap by describing how to build a simple RFC Client using SAP .Net Connector (NCo) 3.0.  <a href="http://www.dataxstream.com/sap-nco-3-0-rfc-client-code/">Click here</a> to request a .zip file containing a copy of the source code.</p>
<p>The sample program displays details about companies defined by SAP. There are two BAPI calls involved, BAPI_COMPANY_GETLIST and BAPI_COMPANY_GETDETAIL.<br />
Along with the SAP .Net Connector 3.0, we are using Microsoft Visual Studio 2010 and the Microsoft .Net Framework 4.0 to build our sample.  Prior to starting, you will have to download and install <a href="http://service.sap.com/connectors" target="_blank">NCo 3.0</a> (OSS login required).<br />
<span id="more-8576"></span></p>
<h2>Setting up the Project</h2>
<p>Using Visual Studio 2010, create a new Windows Form project. In the project properties, be sure to set the Target Framework to .Net Framework 4.0.<a href="http://www.dataxstream.com/wp-content/uploads/RFC_Client01.png" rel="shadowbox[sbpost-8576];player=img;"><img class="alignnone size-full wp-image-8581" src="http://www.dataxstream.com/wp-content/uploads/RFC_Client01.png" alt="" width="564" height="332" /></a></p>
<p>Add references to the SAP .Net Connector 3.0. There are two DLLs, sapnco.dll and sapnco_utils.dll.</p>
<p><a href="http://www.dataxstream.com/wp-content/uploads/RFC_Client02.png" rel="shadowbox[sbpost-8576];player=img;"><img class="alignnone size-full wp-image-8582" src="http://www.dataxstream.com/wp-content/uploads/RFC_Client02.png" alt="" width="251" height="154" /></a></p>
<h2>Design the Form</h2>
<p>Add two controls to the form. The first is a List Box, which will contain the list of available SAP companies. The second control to add is a Property Grid control, which is used to display the details of a particular SAP company when the user selects one from the List Box.</p>
<p><a href="http://www.dataxstream.com/wp-content/uploads/RFC_Client03.png" rel="shadowbox[sbpost-8576];player=img;"><img class="alignnone size-full wp-image-8583" src="http://www.dataxstream.com/wp-content/uploads/RFC_Client03.png" alt="" width="575" height="454" /></a></p>
<h2>Using App.Config to define the SAP Connections</h2>
<p>There are several methods you can use in your solutions to define a particular SAP host. For this example, we are using an app.config file to define our SAP host.<br />
The SAP .Net Connector 3.0 includes sample app.config files. For the RFC client, be sure there is a sectionGroup definition for <span style="font-family: Consolas, Courier, monospace"><span style="color: #0000ff">&lt;</span><span style="color: #800000">ClientSettings</span><span style="color: #0000ff">&gt;</span></span>.<br />
The SAP host is defined by the destinations section. Within the destination, the Name field identifies this app.config entry to our program code. Specify the appropriate user name, password, SAP host name, client and system number in the destination section.</p>
<p><a href="http://www.dataxstream.com/wp-content/uploads/RFC_Client04.png" rel="shadowbox[sbpost-8576];player=img;"><img class="alignnone size-full wp-image-8584" src="http://www.dataxstream.com/wp-content/uploads/RFC_Client04.png" alt="" width="688" height="347" /></a></p>
<h2>The BAPIs</h2>
<p>Use the SAP transaction SE37 to determine the parameters for functions BAPI_COMPANY_GETLIST and BAPI_COMPANY_GETDETAIL. This will tell us what parameters need to be passed in and where to find the results that are returned to our code.</p>
<h2>The Code</h2>
<p>During the form load event, we want to populate our List Box with the defined companies from SAP.</p>
<ol>
<li>Acquire a valid RfcDestination to use. Use method <span style="font-family: Consolas, Courier, monospace">RfcDestinationManager.GetDestination()</span> to do this. <span style="font-family: Consolas, Courier, monospace">GetDestination()</span> requires a parameter to determine which SAP host to refer to. Pass in the Name of the SAP host you previously defined in the app.config file. (Line 60)</li>
<li>Now that we have a valid <span style="font-family: Consolas, Courier, monospace">RfcDestination</span> object, we need access to the SAP Repository. The repository contains information about the BAPI calls we are going to make. The <span style="font-family: Consolas, Courier, monospace">RfcRepository</span> is an attribute of an <span style="font-family: Consolas, Courier, monospace">RfcDestination</span> object. (Line 62)</li>
<li>Using the <span style="font-family: Consolas, Courier, monospace">RfcRepository</span> object, acquire a reference to the SAP BAPI by calling method <span style="font-family: Consolas, Courier, monospace">RfcRepository.CreateFunction()</span> method. Pass in the name of the desired function as a string parameter to <span style="font-family: Consolas, Courier, monospace">CreateFunction()</span>. This method returns an object we can use to setup parameters, invoke the function, and retrieve results.</li>
<li>Now we can make the RFC calls into SAP. Using the <span style="font-family: Consolas, Courier, monospace">IRfcFunction</span> object returned by <span style="font-family: Consolas, Courier, monospace">CreateFunction()</span>, call the <span style="font-family: Consolas, Courier, monospace">Invoke()</span> method, passing in our <span style="font-family: Consolas, Courier, monospace">RfcDestination</span> object as parameter. This will make the RFC call into SAP, and provides the results via our <span style="font-family: Consolas, Courier, monospace">IRfcFunction</span> object. (Line 68)</li>
<li>SAP function BAPI_GET_COMPANYLIST returns a table of company records. We use an instance of an <span style="font-family: Consolas, Courier, monospace">IRfcTable</span> object that we retrieve by calling the <span style="font-family: Consolas, Courier, monospace">GetTable()</span> method on the <span style="font-family: Consolas, Courier, monospace">IRfcFunction</span> object. To get a desired table, pass in the table name to the <span style="font-family: Consolas, Courier, monospace">GetTable()</span> method. (Line 70)</li>
<li>We now have an instance of an <span style="font-family: Consolas, Courier, monospace">IRfcTable</span> object that contains company information through which we can iterate. It is possible to iterate through the data by setting the <span style="font-family: Consolas, Courier, monospace">CurrentIndex</span> property on the returned table. For a particular row in the table, it is possible to access values using the <span style="font-family: Consolas, Courier, monospace">GetString()</span> method. (Lines 75-79)</li>
<li>For each company, get the CompanyNumber, and use that as a parameter to SAP function BAPI_COMPANY_GETDETAIL. BAPI_COMPANY_GETDETAIL returns detailed information about that particular SAP company. The techniques are the same as before, with the additional step of using the <span style="font-family: Consolas, Courier, monospace">SetValue()</span> method on the <span style="font-family: Consolas, Courier, monospace">IRfcFunction</span> object to pass in the company number as a parameter. (Lines 78-84)</li>
<li>BAPI_COMPANY_GETDETAIL returns data as an instance of the <span style="font-family: Consolas, Courier, monospace">IRfcStructure</span> interface. Access individual field data of the company record, using the <span style="font-family: Consolas, Courier, monospace">GetString()</span> method of the <span style="font-family: Consolas, Courier, monospace">IRfcStructure</span> object instance. (Lines 88-99)</li>
<li>Extract the company details as desired. Add them to some object you create and then add that object to the List Box control. (Line 101)</li>
</ol>
<p><a href="http://www.dataxstream.com/wp-content/uploads/RFC_Client05.png" rel="shadowbox[sbpost-8576];player=img;"><img class="alignnone size-full wp-image-8585" src="http://www.dataxstream.com/wp-content/uploads/RFC_Client05.png" alt="" width="665" height="547" /></a></p>
<p>The rest of the code is regular Windows Forms programming. Your code will need to wire up the List Box changed events so that the Property Grid will display the details of the selected company.</p>
<h2>Additional Information</h2>
<p>Follow these links for more information about NCo 3.0 programming:</p>
<ul>
<li>Webinar: <a href="http://www.dataxstream.com/sap_webinars/sap-nco-3-0-best-practice-guide-for-upgrade-from-net-connector-2-0/">SAP NCo 3.0 – Best Practice Guide for Upgrade from .NET Connector 2.0</a></li>
<li>Source Code: <a href="http://www.dataxstream.com/sap-nco-3-0-rfc-client-code/">RFC Client with NCo 3.0</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.dataxstream.com/2011/08/nco-3-rfc-client-step-by-step/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>SAP Data Migration – Dealing With Fallout (Part 3)</title>
		<link>http://www.dataxstream.com/2010/08/sap-data-migration-dealing-with-fallout/</link>
		<comments>http://www.dataxstream.com/2010/08/sap-data-migration-dealing-with-fallout/#comments</comments>
		<pubDate>Thu, 26 Aug 2010 14:15:25 +0000</pubDate>
		<dc:creator>Mike Salvo</dc:creator>
				<category><![CDATA[SAP ABAP Blog]]></category>
		<category><![CDATA[SAP Functional]]></category>
		<category><![CDATA[SAP Technical]]></category>
		<category><![CDATA[ABAP]]></category>
		<category><![CDATA[ALE]]></category>
		<category><![CDATA[Basis/Netweaver]]></category>
		<category><![CDATA[Data Migration]]></category>
		<category><![CDATA[DataXstream]]></category>
		<category><![CDATA[Integration]]></category>
		<category><![CDATA[Mike Salvo]]></category>
		<category><![CDATA[NetWeaver]]></category>
		<category><![CDATA[Project Management]]></category>
		<category><![CDATA[SAP]]></category>
		<category><![CDATA[SAP ABAP]]></category>
		<category><![CDATA[upgrades]]></category>

		<guid isPermaLink="false">http://www.dataxstream.com/?p=5591</guid>
		<description><![CDATA[One of the inevitable aspects of data migration is dealing with fallout from automated data loads.  Typically, this process includes identifying the data that will not load, analyzing the error messages to determine the root cause, formatting a readable report that can be used as a tool in the cleanup process, and fixing the root [...]]]></description>
			<content:encoded><![CDATA[<p>One of the inevitable aspects of data migration is dealing with fallout from automated data loads.  Typically, this process includes identifying the data that will not load, analyzing the error messages to determine the root cause, formatting a readable report that can be used as a tool in the cleanup process, and fixing the root cause of the problem so that it does not happen again.</p>
<h2>Why the data will not load correctly.</h2>
<p>There is a litany of reasons why some data records will load correctly while others will not.  Here is a list of some common root causes:</p>
<p>&nbsp;</p>
<ol>
<ol>
<li><strong>Poor quality legacy data.</strong><br />
Legacy systems which are not as tightly integrated as SAP, and are not under master data control allow the end user a bit of freedom when entering data.  A zip code may contain too little or too many characters; the email address is not properly formatted; numeric fields have transposed digits; various forms of abbreviations (especially in the city field), a quantity of zero (0) permitted by the legacy system and uploaded into a field where SAP will not accept a quantity of 0 and even simple misspellings  all can cause stringent validation checks to trigger an error and prevent the record from loading at all.  A more sinister type of error occurs when the data is functionally incorrect, but good enough to pass all of the SAP validity checks.  In this case, the data record will technically load into SAP, but will not be functionally correct.  Duplicate customers, duplicate vendors, and the data entry error for a quantity of 1000 instead of 100, and the wrong pricing condition applied to a sales order line are examples of this scenario.</li>
</ol>
</ol>
<p>&nbsp;</p>
<p>&nbsp;</p>
<ol>
<li><strong>Functional configuration and supporting data effects.</strong><br />
Many times I have watched the load statistics for a data object plummet from near 100% in the cycle two test load to near 0% in the cycle three test load.  This is very unnerving to the client because the cycle three test load is getting rather close to the go-live date, and “by the way, shouldn’t the statistics be getting better rather than worse?”  Functional configuration changes can wreak havoc on any data load.  Flipping the switch on a data field from optional to required; turning on batch management or serialization for materials for the first time; changes in the handling of tax, tax codes, and tax jurisdiction codes; that account determination entry that is missing or not set up correctly; a missing unit of measure or unit or measure conversion factor; the storage location in the upload file which does not exist in SAP – any of these can cause a load to drop mostly or completely onto the floor.While change is inevitable on any project, it is important to control and communicate the change so that the downstream impact can be recognized and understood.   Controlled change and communication always works better than total surprise.  Perhaps if we all know ahead of time about that data field that is now required, we can impose a requirement on the data extract side to make sure that the data field is populated before it enters the upload file.&nbsp;</li>
<li><strong>Additional data in the upload file.</strong><br />
Inserting a new field in the middle of the upload file data structure might be necessary for the business to close a gap, but if that change is not communicated to the technical team so that appropriate adjustments can be made to the load object’s input structures and processing logic, the new data will surely never load, and may cause misalignment of the data fields which follow it in the upload structure.</li>
</ol>
<p><span id="more-6104"></span></p>
<h2>The Finger Pointing Game</h2>
<blockquote><p>It’s the load program!  No, it’s the data!  No, it’s the configuration!  No, it’s … (fill in your favorite finger pointing game excuse explaining why data will not load).</p></blockquote>
<p>If you ever find yourself in the midst of this type of finger-pointing game, immediately stop the madness.  For this and similar situations, I apply a simple litmus test which has never failed me yet – manually enter the EXACT upload data into SAP for the transaction which has failed.  If one can be entered manually, then the program will be able to automatically load thousands with similar upload data and functional configuration.</p>
<p>I have lead many a functional analyst &#8211; kicking, screaming, and ranting about how terrible the load program is – to the terminal to play “let’s enter one manually”.  Typically, the result is that one cannot be entered manually due to configuration issues or the lack of supporting values data.  Once these issues are cleaned up, the load program “magically” begins to process thousands of records with no trouble at all.</p>
<p>Sometimes, the load object appears to be the cause, but is not the root cause.  The important data item not being handled by the load object (which was not called out in the functional specification document), the data item which turns blue (because the functional specification document explicitly stated “put this data item into the blue category”), the formula which is not calculating the desired result (but is indeed the exact formula found in the functional specification document) – all are examples of the load object adhering accurately to an incorrect functional specification document.  The root cause, then, is the functional specification document which must first be revised and checked into the controlled document repository before making any code modifications.</p>
<h2>It’s the Program</h2>
<p>Well, OK, sometimes the load object is at fault.  But it is extremely rare.</p>
<h2>Collecting and Reporting the Technical Load Statistics</h2>
<p>Load statistics are an important <span style="text-decoration: underline;">technical</span> metric, indicating what percentage of the upload file has successfully posted a transaction into SAP.  This is a basic and simple record count check.  How many records were presented in the upload file, how many records posted successfully to SAP, and how many records failed to post.  Also, does the number of successful transaction plus the number of failed transactions equal the total number of records presented in the upload file.</p>
<p>Here is how I communicate this technical metric:</p>
<table>
<tbody>
<tr>
<td>Total records in the upload file</td>
<td>100</td>
<td></td>
</tr>
<tr>
<td>Successful technical transactions</td>
<td>90</td>
<td>90% success</td>
</tr>
<tr>
<td>Failed technical transactions</td>
<td>10</td>
<td>10% fail</td>
</tr>
</tbody>
</table>
<p>This technical metric indicates only that all of the SAP validation rules for posting the transaction have passed.  It does not indicate that the master or transactional data posted to SAP is actually correct in functional terms.</p>
<h2>The Functional Review</h2>
<p>It is very possible for an entire upload file to technically load at 100%; while at the same time, functionally fail at 100%.  The customer may be missing a partner, the material or article may be categorized incorrectly, the pricing conditions on a sales order may not have the desired validity date range, the GL posting may be to the wrong accounts.  Hence, the need a functional review and validation of the data transacted into SAP.  The data type &#8211; master or transactional &#8211; determines the type of functional review and metrics to be employed here.</p>
<p>For master data, such as of materials, customers, vendors, etc., it is impossible to individually validate the many thousands of entries in your SAP system.  But statistical methods can be employed which will guide you through a random sampling of the data, while at the same time assuring accuracy at a high degree of confidence levels.</p>
<p>For transactional data, such as inventory, open sales orders, open AR, etc., direct mathematical comparisons can be employed.  On a grand scale, if an inventory value of $15,246,321.44 is being moved from your legacy system to SAP, then that exact amount must arrive in SAP when the migration task is complete.  It may be a bit more difficult to do this mathematical comparison at a more granular level.   If, in the move to SAP you are also redesigning your material/storage location combinations, a direct comparison between the legacy system and SAP may not be possible without a translation factor.  The same scenario exists if you redesign your GL chart of accounts, where one legacy GL account now maps to several SAP GL accounts, or vice versa.</p>
<h2>Reporting the Fallout</h2>
<p>If an automated data load was not technically 100% successful, a clear set of error messages complete with a link back to the legacy data must be mined, formatted, and presented to the business for analysis.  Such a report really helps to facilitate the fallout cleanup.  The link back to the legacy data must be carefully designed into the load process to make sure that, for example, the legacy customer number, legacy vendor number, legacy sales order number, legacy purchase order number, etc. is included as part of the data being handled.  Without the link back to the legacy data, it becomes very difficult to identify which data record needs to be fixed.</p>
<p>The error message mining technique that I use depends on the load method.  I will describe two here – one for a BDC load method and one for an IDOC load method.</p>
<h2>Mining Meaningful Error Messages from a BDC Session Log</h2>
<p>At the completion of a batch input session, the batch input session overview screen (SM35) displays the technical load statistics.  In this example, out of a total of 229 transactions, 13 failed and 216 succeeded.</p>
<p><a href="http://www.dataxstream.com/wp-content/uploads/dm3-1.jpg" rel="shadowbox[sbpost-6104];player=img;"><img class="size-full wp-image-5594 alignnone" title="dm3-1" src="http://www.dataxstream.com/wp-content/uploads/dm3-1.jpg" alt="" width="203" height="61" /></a></p>
<p>The session log shows the status of all 229 transactions.  This screen snapshot is a fragment of the complete session log for the batch input session.  It shows many successful transactions (Type = S) and one failed transaction (Type = E).  The error message here is clear – the article does not exist or is not activated.</p>
<p><a href="http://www.dataxstream.com/wp-content/uploads/dm3-2.jpg" rel="shadowbox[sbpost-6104];player=img;"><img class="size-full wp-image-5596 alignnone" title="dm3-2" src="http://www.dataxstream.com/wp-content/uploads/dm3-2.jpg" alt="" width="623" height="216" /></a></p>
<p>But as you can imagine, the 13 failed transactions with error type = E are sprinkled throughout the many pages of this log file.  With only 229 transactions, this log file is quite easy to pick through to find the 13 errors.  But imagine if the number of transactions were in the thousands or tens of thousands.  How do we extract only the failed transactions and present a concise report of the failed transactions?</p>
<p>To do this, I use SAP transaction SM35P – Batch Input Log Overview.  This transaction has the ability to set a filter on any field in the batch input log file, display the filtered results, and then to export the results to a local file.</p>
<p>To enter the mode where this is possible, first press the PRINT icon.</p>
<p><a href="http://www.dataxstream.com/wp-content/uploads/dm3-3.jpg" rel="shadowbox[sbpost-6104];player=img;"><img class="size-full wp-image-5597 alignnone" title="dm3-3" src="http://www.dataxstream.com/wp-content/uploads/dm3-3.jpg" alt="" width="441" height="95" /></a></p>
<p>Next, set the filter.  The appropriate filter field here is SESS. TYPE.</p>
<p><a href="http://www.dataxstream.com/wp-content/uploads/dm3-4.jpg" rel="shadowbox[sbpost-6104];player=img;"><img class="size-full wp-image-5598 alignnone" title="dm3-4" src="http://www.dataxstream.com/wp-content/uploads/dm3-4.jpg" alt="" width="449" height="66" /></a></p>
<p><a href="http://www.dataxstream.com/wp-content/uploads/dm3-5.jpg" rel="shadowbox[sbpost-6104];player=img;"><img class="size-full wp-image-5599 alignnone" title="dm3-5" src="http://www.dataxstream.com/wp-content/uploads/dm3-5.jpg" alt="" width="570" height="459" /></a></p>
<p>We only want the errors, so set the filter for field SESS. TYPE = E.</p>
<p><a href="http://www.dataxstream.com/wp-content/uploads/dm3-6.jpg" rel="shadowbox[sbpost-6104];player=img;"><img class="size-full wp-image-5600 alignnone" title="dm3-6" src="http://www.dataxstream.com/wp-content/uploads/dm3-6.jpg" alt="" width="328" height="91" /></a></p>
<p>The display now shows only the 13 rows containing the error messages.  This can be exported directly to a local spreadsheet for further analysis.</p>
<p><a href="http://www.dataxstream.com/wp-content/uploads/dm3-7.jpg" rel="shadowbox[sbpost-6104];player=img;"><img class="size-full wp-image-5601 alignnone" title="dm3-7" src="http://www.dataxstream.com/wp-content/uploads/dm3-7.jpg" alt="" width="625" height="146" /></a></p>
<h2>Mining Meaningful Error Messages from IDOCs</h2>
<p>Depending on the IDOC and the processing module, mining the error status messages from IDOCs can be very easy or somewhat challenging.  For the more difficult scenarios, you probably will need to hone your EXCEL skills to properly join several extracts together into one complete picture.</p>
<p>When creating IDOCs with a load object, I always note the date, time, and IDOC basic type.  I will use this information as the selection criteria for transaction WE05, which is going to locate the IDOCs and display the results information I need after the IDOCs are processed.  The results that I usually collect are the error status messages, and some data content from a segment or two to illustrate exactly where the problem is in the legacy data.</p>
<p>While the background job is busy processing the IDOCs, I usually take a peek, using transaction WE05, to see how the load is progressing.  If I see that most of the IDOCs are falling onto the floor (IDOC status 51) rather than moving into the database (IDOC status 53), I usually stop the background job and begin an immediate analysis of the fallout.  If the fallout solution does not require a change to the IDOC data content (e.g. a configuration change), then I can replay the fallout using SAP transaction BD87.  If the fallout solution does require a change to the IDOC data content, then the complete set of IDOCs must be regenerated again.</p>
<p>Let’s see what WE05 can tell us about a completed Article Master load.</p>
<p>On the WE05 screen below, we can see that of the total of 14,005 IDOCs, 11,412 have processed successfully and 2,593 have failed to process.  By double clicking the Status 51 folder, the display will show only the Status 51 IDOCs – the fallout.</p>
<p><a href="http://www.dataxstream.com/wp-content/uploads/dm3-8.jpg" rel="shadowbox[sbpost-6104];player=img;"><img class="size-full wp-image-5603 alignnone" title="dm3-8" src="http://www.dataxstream.com/wp-content/uploads/dm3-8.jpg" alt="" width="618" height="278" /></a></p>
<p>By pressing the “status list” icon (shown above), the display will show the status messages for the fallout.    Once these messages are displayed, pressing the “export” icon allows me to save the screen contents to a spreadsheet.</p>
<p><a href="http://www.dataxstream.com/wp-content/uploads/dm3-9.jpg" rel="shadowbox[sbpost-6104];player=img;"><img class="size-full wp-image-5604 alignnone" title="dm3-9" src="http://www.dataxstream.com/wp-content/uploads/dm3-9.jpg" alt="" width="624" height="331" /></a></p>
<p>Now it would be really nice if I could have the article number in the spreadsheet right next to the error message.  The article number in the ARTMAS IDOC is stored in segment E1BPE1MATHEAD.  The segment content for each IDOC can be displayed by pressing the “list specific segment” icon and entering the segment name in the box.</p>
<p><a href="http://www.dataxstream.com/wp-content/uploads/dm3-10.jpg" rel="shadowbox[sbpost-6104];player=img;"><img class="size-full wp-image-5605 alignnone" title="dm3-10" src="http://www.dataxstream.com/wp-content/uploads/dm3-10.jpg" alt="" width="623" height="256" /></a></p>
<p>The segment display will show all fields in the segment, so I usually hide all of the columns that I don’t want to see.  Here is the E1BPE1MATHEAD segment display showing only the article number.  I can use the export icon to save the list of article numbers to another spreadsheet.</p>
<p><a href="http://www.dataxstream.com/wp-content/uploads/dm3-11.jpg" rel="shadowbox[sbpost-6104];player=img;"><img class="size-full wp-image-5606 alignnone" title="dm3-11" src="http://www.dataxstream.com/wp-content/uploads/dm3-11.jpg" alt="" width="326" height="373" /></a></p>
<p>Here is a portion of the complete spreadsheet showing the error messages and the article numbers side by side.</p>
<p><a href="http://www.dataxstream.com/wp-content/uploads/dm3-12.jpg" rel="shadowbox[sbpost-6104];player=img;"><img class="size-full wp-image-5607 alignnone" title="dm3-12" src="http://www.dataxstream.com/wp-content/uploads/dm3-12.jpg" alt="" width="625" height="250" /></a></p>
<p>A filter applied to the spreadsheet shows that the 2,593 errors are all grouped into one of three error status categories.  By selecting a single category, Excel will also show me the number of records within that failure category.</p>
<p><a href="http://www.dataxstream.com/wp-content/uploads/dm3-13.jpg" rel="shadowbox[sbpost-6104];player=img;"><img class="size-full wp-image-5608 alignnone" title="dm3-13" src="http://www.dataxstream.com/wp-content/uploads/dm3-13.jpg" alt="" width="208" height="235" /></a></p>
<p>Sometimes it is easier to mine the status messages directly from the IDOC status table EDIDS.  This is especially true where the processing module is a BAPI which returns an error table rather than a single error message.  In this case, when you press the “status list” icon in WE05, only the first error status message of several is displayed for each IDOC.  I find that the first message is not very helpful (as shown below).  I also find that typically the second or third message in the return status table is usually the important one.  You won’t see it displayed on the WE05 screen, but you can mine it from the EDIDS table.</p>
<p><a href="http://www.dataxstream.com/wp-content/uploads/dm3-14.jpg" rel="shadowbox[sbpost-6104];player=img;"><img class="size-full wp-image-5609 alignnone" title="dm3-14" src="http://www.dataxstream.com/wp-content/uploads/dm3-14.jpg" alt="" width="629" height="220" /></a></p>
<p>SAP transactions SE11 or SE16 both support this activity.  For the selection criteria I use the IDOC number range, status 51, and status type E.  On the display screen, choose only the relevant fields for display – the IDOC number (DOCNUM), IDOC status (STATUS), status message (STATXT), the four substitution parameters for the status message (STAPA1, STAPA2, STAPA3, STAPA4) and the message type (STATYP).  All of this can be exported into a spreadsheet.  If you really want to test your Excel skills, you can write code that will move the substitution parameters into their placeholders in the status text.</p>
<h2>Preparing for the next data migration cycle &#8211; Let the fallout analysis and cleanup begin.</h2>
<p>Presenting the fallout report to the business with a set of clear error reasons and links back to the legacy data is key to enabling the legacy data cleanup process to proceed.  In the iterative process of data migration cycles, cleansing the legacy data is a step in the right direction towards an improved next conversion cycle.</p>
<p>I hope you enjoyed this blog series on data migration.  Please feel free to send comments or questions.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dataxstream.com/2010/08/sap-data-migration-dealing-with-fallout/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Coming Soon: SAP .NET Connector (NCo) 3.0</title>
		<link>http://www.dataxstream.com/2010/07/sap-net-connector-nco-3-0-overview/</link>
		<comments>http://www.dataxstream.com/2010/07/sap-net-connector-nco-3-0-overview/#comments</comments>
		<pubDate>Wed, 21 Jul 2010 13:40:15 +0000</pubDate>
		<dc:creator>Craig Stasila</dc:creator>
				<category><![CDATA[SAP ABAP Blog]]></category>
		<category><![CDATA[SAP Basis Blog]]></category>
		<category><![CDATA[SAP Interface Blog]]></category>
		<category><![CDATA[SAP Technical]]></category>
		<category><![CDATA[.Net Connector]]></category>
		<category><![CDATA[Craig Stasila]]></category>
		<category><![CDATA[DataXstream]]></category>
		<category><![CDATA[Integration]]></category>
		<category><![CDATA[NCo]]></category>
		<category><![CDATA[SAP .Net Connector]]></category>
		<category><![CDATA[Xstream Connector]]></category>
		<category><![CDATA[XstreamConnector]]></category>

		<guid isPermaLink="false">http://www.dataxstream.com/?p=5499</guid>
		<description><![CDATA[SAP is announcing a new version of SAP Connector for Microsoft .NET 3.0 (now called &#8220;NCo 3.0&#8243;). A beta program for selected customers and partners is currently underway (Q3, 2010) with the general release of the software coming soon thereafter.  I will highlight some of the major differences between the SAP Connector for Microsoft .NET [...]]]></description>
			<content:encoded><![CDATA[<p>SAP is announcing a new version of SAP Connector for Microsoft .NET 3.0 (now called &#8220;NCo 3.0&#8243;). A beta program for selected customers and partners is currently underway (Q3, 2010) with the general release of the software coming soon thereafter.  I will highlight some of the major differences between the SAP Connector for Microsoft .NET 2.0 and NCo 3.0 (besides the obvious, and much-needed name-shortening).</p>
<blockquote><p>EDITOR&#8217;S NOTE: NCo 3.0 has now been released.  <a href="http://www.dataxstream.com/2011/01/introducing-sap-net-connector-nco-3-0/">Read more details here.</a></p></blockquote>
<p><span id="more-5499"></span></p>
<h2>NCo 3.0 Logon</h2>
<div>Security got vital improvements in NCo 3.0.  The component handling logon and authentication was redesigned to thwart the following attacks:</div>
<div>
<ul>
<li>The unauthorized reading of sensitive logon data from the .NET configuration file (e.g. app.config).</li>
<li>The potential to create a malevolent application which replaces the customized logon data with it’s own logon data to obtain backend user sessions with different authorizations.</li>
<li>The potential to create a malevolent application which gains access to an open connection that was originally intended for a different application.</li>
</ul>
</div>
<p>One of the new features implemented to combat the malevolent for RFC client attacks is the interface <span style="font-family: Courier;">IDestinationConfiguration</span>.  This interface contains method <span style="font-family: Courier;">IDestinationConfiguration.GetParameters(string destinationName)</span> which allows .NET programmers to provide their own secure method for storing and retrieving logon information, be it encrypted database, encrypted file, or even LDAP.  There is also a corresponding interface and method to secure NCo 3.0 RFC servers.</p>
<p>Additionally, there is updated functionality to support single sign-on (SSO) and X.509 certificates.</p>
<h2>Say Goodbye to Data Containers and Generated Code</h2>
<p>In SAP Connector 2.0, working with RFCs required the generation of proxy code via the SAP .NET Connector design-time tool.  This tool would convert the IMPORTING, EXPORTING, CHANGING, and TABLES parameters from the RFC you were calling/serving to .NET representations of the same.  With NCo 3.0 there is no longer any kind of generated code.  Instead of one generated proxy method for each function module, there is one single <span style="font-family: Courier;">RfcFunction</span> class, whose <span style="font-family: Courier;">Invoke()</span> method dynamically executes every given ABAP function module.  Additionally, all ABAP parameters will be represented by the class <span style="font-family: Courier;">RfcStructure</span> instead of a dedicated generated class for every structure; All tables will be represented by class <span style="font-family: Courier;">RfcTable</span>.  So, instead of hard-coding all of the data and variable bindings statically at design time, NCo 3.0 now handles everything dynamically at runtime.</p>
<p>NCo 3.0 uses SAP&#8217;s data dictionary to determine the function interface for the called RFCs.  While this data is cached locally for performance reasons, NCo 3.0 is robust enough to detect changes in RFC interface signatures so your code will still execute if you&#8217;ve added, deleted, or changed RFC parameters.  If there arises a situation where the dynamic lookup of RFC interface signature is not wanted, there is also an option to hard code the RFC parameter metadata.</p>
<p>The biggest benefit of NCo 3.0&#8242;s new dynamic function handling is that NCo 3.0 no longer has a design-time component.  This releases the Visual Studio version restriction that .NET 2.0 had.  Let me rephrase that, <strong>NCo 3.0 will work with any version of Visual Studio you like!</strong> The only requirement is that at runtime, a .NET Framework version is installed that is compatible with the NCo 3.0 libraries.</p>
<h2>Anxiously Waiting</h2>
<p>NCo 3.0 figures to be a much-needed update to a vital SAP integration technology.  I, for one, cannot wait for the new functionality to be generally released.  Once NCo 3.0 is released we&#8217;ll be posting blogs highlighting the new features.  We&#8217;ll also include helpful information regarding a .NET Connector 2.0 to NCo 3.0 upgrade.  In the meantime, if you have any leave any questions or comments you have regarding NCo 3.0 below.  You may also email me directly at <span class="mh-email">csta<a href='http://www.google.com/recaptcha/mailhide/d?k=01NvHbOaIcE_hinzIpcpzZQQ==&amp;c=2sqVLQgd7lYWASsTIrUumIH5gCbE09il9SNcQyxGWDs=' onclick="window.open('http://www.google.com/recaptcha/mailhide/d?k=01NvHbOaIcE_hinzIpcpzZQQ==&amp;c=2sqVLQgd7lYWASsTIrUumIH5gCbE09il9SNcQyxGWDs=', '', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=500,height=300'); return false;" title="Reveal this e-mail address">...</a>@dataxstream.com</span> if you&#8217;d like to set up a detailed conversation.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dataxstream.com/2010/07/sap-net-connector-nco-3-0-overview/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>SAP Data Migration &#8211; Answering the Important Questions (Part 1)</title>
		<link>http://www.dataxstream.com/2010/07/sap-data-migration-and-data-conversion-1/</link>
		<comments>http://www.dataxstream.com/2010/07/sap-data-migration-and-data-conversion-1/#comments</comments>
		<pubDate>Tue, 13 Jul 2010 14:00:20 +0000</pubDate>
		<dc:creator>Mike Salvo</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[SAP ABAP Blog]]></category>
		<category><![CDATA[SAP Project Management]]></category>
		<category><![CDATA[SAP Strategy]]></category>
		<category><![CDATA[SAP Technical]]></category>
		<category><![CDATA[SAP Testing]]></category>
		<category><![CDATA[ABAP]]></category>
		<category><![CDATA[Data Migration]]></category>
		<category><![CDATA[DataXstream]]></category>
		<category><![CDATA[Integration]]></category>
		<category><![CDATA[Mike Salvo]]></category>
		<category><![CDATA[NetWeaver]]></category>
		<category><![CDATA[Project Management]]></category>
		<category><![CDATA[SAP]]></category>
		<category><![CDATA[SAP programming]]></category>
		<category><![CDATA[SAP testing]]></category>
		<category><![CDATA[upgrades]]></category>

		<guid isPermaLink="false">http://www.dataxstream.com/?p=5138</guid>
		<description><![CDATA[It is data migration time on your SAP business project.  Whether your project is implementation, acquisition, or merger, the goal is pretty much the same: the seamless inbound acquisition of master and transactional data from one or more external data sources while ensuring that this activity has minimal impact on the rest of the business.  [...]]]></description>
			<content:encoded><![CDATA[<p>It is data migration time on your SAP business project.  Whether your project is implementation, acquisition, or merger, the goal is pretty much the same: the seamless inbound acquisition of master and transactional data from one or more external data sources while ensuring that this activity has minimal impact on the rest of the business.  This is where we attempt to move years of neglected master and transactional data from a loosely structured, anything-goes legacy system into a very tightly integrated and highly structured SAP system.  You must consider the likelihood that the concept of master data management had not been invented yet when the legacy or source system providing your data was implemented.</p>
<p>How much data to move? How much data to leave behind? What to automate, and what to execute manually?  How to gracefully orchestrate and execute a data migration cutover from one system to another?  Where and how to fit the data migration plan into the overall business implementation plan?  How to continue to run the business during the data migration phase of the business project implementation? These questions are all part of the planning fun!</p>
<p><span id="more-5138"></span></p>
<h2>Data Migration Testing</h2>
<p>Processes that we have exercised and continue to exercise on a regular basis are no big deal, do not cause anxiety, or raise any blood pressures.  The daily report, the custom transaction, the interface that runs several hundred times a week – they are all second nature now.  They happen, and no one notices.</p>
<p>But reflect back to the very first time these processes went live.  This is precisely where you are with data migration.  For most, it is a once in a lifetime event.  It is important, then, to raise confidence levels, and reduce anxiety levels surrounding this activity.  This is achieved by practice, practice, practice.</p>
<p>Typically, I like to see at least three data migration test cycles executed in an isolated data migration client.  This allows for several attempts at exercising and fine-tuning the data migration plan; collecting nominal run time statistics to have some idea of how long the data migration might take; identifying and fixing any data migration program object defects; identifying and fixing any data mapping and content defects; and identifying and fixing any functional configuration issues. Each of these tasks are done with the goal of significantly improving the fallout rate with each data migration test cycle.  These data migration test cycles also give us the opportunity to practice our legacy extract skills, our fallout analysis skills, and our fallout manual cleanup skills.</p>
<h2>Source Data Quality</h2>
<p>Each data migration test cycle begins with the legacy or source data extract.  An important activity between data migration test cycles is the cleanup of the legacy or source data.  The data migration process will most likely discover many data problems.  Customer and vendor address data alone are enough to bring your bolt-on tax jurisdiction determination software to its knees – that zip code that is too short, too long, or just plain incorrect when combined with the associated city and state; the various abbreviations used in place of the actual city name; the city and state entered in the same field when they should have been entered into separate fields; etc.   If the source data is not fixed, your data migration test cycles will begin to look like the movie Groundhog Day.</p>
<p>Source data provisioning and cleanup could very well be problematic, especially in an acquisition or merger scenario where the providers are part of a different organization and have no incentive to participate in your project.  If you encounter this scenario, you will most likely need to engage the appropriate management level from your organization to have a serious discussion with the appropriate management level from the providing organization.  Recognize this, be in control, and raise that flag early.    Do not sit around for several days waiting for data to arrive, as this will only set your project behind schedule.</p>
<h2>Data Migration Support for Other Testing</h2>
<p>In any business project scenario, the development team will salivate at the thought of testing their customizations against your real data in the conversion test cycle box.  Likewise, the functional team will be chomping at the bit to use your real data to test configuration scenarios.  And the interface team and the data warehouse team can’t ever get enough data to play with.</p>
<p>While working within your three data migration test cycles, just say NO.  You absolutely need a controlled environment for data migration test cycles, and these other teams will not respect that.  They have a different focus and purpose which requires changing and manipulating degrees of freedom that you need held constant.</p>
<p>But, we are all on the same team trying to move the project to the finish line within the expected project timeline.  So to help your other team members, plan for additional data migration cycles to provide this data to these teams.  That’s more data migration practice for you, and it gives everyone else what they need.</p>
<h2>The Perfect World of Data Migration</h2>
<p>In a perfect world, for each data object to be converted:</p>
<ol>
<li>The functional specification and mapping documents are well-written and clear.</li>
<li>A data load file is built exactly in conformity to the well-written functional specification and mapping documents.</li>
<li>The data migration ABAP objects are built exactly as specified by the well-written functional specification and data mapping documents.</li>
<li>No one is insisting that we move a square peg into a round hole.</li>
</ol>
<p>In a perfect world, for each set of data that is to be migrated:</p>
<ol>
<li>The legacy system data has been thoroughly cleansed.</li>
<li>The providers of the legacy data are genuinely interested in providing accurate data on time.</li>
<li>Server-resident load files in a Unicode system are correctly encoded to UTF-8.</li>
<li>A delimiter other than comma has been specified for the load file.</li>
</ol>
<p>In a perfect world, the data migration test cycle client:</p>
<ol>
<li>Is built in a box that is not the development box.</li>
<li>Is configured exactly like the client where the data migration ABAP objects were built and tested.</li>
<li>Is not open for configuration, unless by design.</li>
<li>Is not part of a transport path. to prevent the current cycle of conversion testing from being blindsided by any new configuration changes.</li>
<li>Is locked down so that only data migration and data validation tasks can be performed.</li>
<li>Is configured to handle a more background and update processes and fewer dialog processes.</li>
<li>Is built in a box that has enough disk space to be the repository for the primary load files and any intermediate processing files needed.</li>
</ol>
<p>In a perfect world, at the project level:</p>
<ol>
<li>There is an overall business cutover or implementation plan into which you can assimilate your data migration plan.</li>
<li>The data migration plan integrates nicely into the overall business cutover plan.</li>
<li>There is a strategy in place to bring the data current between the time the cutover freeze is enforced and the implementation date.</li>
</ol>
<h2>Stay Tuned!</h2>
<p>In the real world, the fun is just beginning.  Those perfect world scenarios just never seem to happen.   But stay tuned!  In my next blog post in this series, I will discuss the details of the Data Migration Plan.  After that, in subsequent posts, I will drill down into some real world scenarios that I have encountered and discuss how I dealt with them.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dataxstream.com/2010/07/sap-data-migration-and-data-conversion-1/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Using Native SQL in an ABAP Proxy</title>
		<link>http://www.dataxstream.com/2010/05/using-native-sql-in-an-abap-proxy/</link>
		<comments>http://www.dataxstream.com/2010/05/using-native-sql-in-an-abap-proxy/#comments</comments>
		<pubDate>Thu, 13 May 2010 13:30:22 +0000</pubDate>
		<dc:creator>Mike Salvo</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[SAP ABAP Blog]]></category>
		<category><![CDATA[SAP PI Blog]]></category>
		<category><![CDATA[SAP Technical]]></category>
		<category><![CDATA[ABAP]]></category>
		<category><![CDATA[ABAP development]]></category>
		<category><![CDATA[DataXstream]]></category>
		<category><![CDATA[Integration]]></category>
		<category><![CDATA[Mike Salvo]]></category>
		<category><![CDATA[SAP]]></category>
		<category><![CDATA[SAP ABAP]]></category>
		<category><![CDATA[SAP programming]]></category>

		<guid isPermaLink="false">http://www.dataxstream.com/?p=4929</guid>
		<description><![CDATA[To implement a case-insensitive WHERE clause in ABAP, you simply needed to use the native SQL UPPER() construct. The database system that is being used is Microsoft SQL Server, but the UPPER() function and its syntax is similar across different database platforms. This seemed like an easy nut to crack. But, as I soon found out, I actually had a lot to learn.]]></description>
			<content:encoded><![CDATA[<p>Recently, I was looking at a requirements document to build an interface to an external system that wants to query customer master data by the customer first name and last name.  As I read this, there were a cacophony of thoughts, all demanding equal attention, racing through my head:</p>
<blockquote>
<ul>
<li><span style="color: #0000ff;">How will I ever match the inbound interface parameter &#8220;Tom&#8221; with &#8220;TOM&#8221;, or &#8220;tom&#8221;?</span></li>
<li><span style="color: #0000ff;">How will I ever match the inbound interface parameter &#8220;Smith&#8221; with &#8220;SMITH&#8221; or &#8220;smith&#8221;?</span></li>
<li><span style="color: #0000ff;">The ABAP WHERE clause is <strong>not</strong> case-INsensitive.</span></li>
<li><span style="color: #0000ff;">There could be hundreds of customers named Tom Smith.</span></li>
<li><span style="color: #0000ff;">KNA1-NAME1 and KNA1-NAME2 are not indexed fields.</span></li>
<li><span style="color: #0000ff;">And no, we are not storing any portion of either first or last name in an existing indexed field like SORTL.</span></li>
<li><span style="color: #0000ff;">There are well over one million customers in the database.</span></li>
<li><span style="color: #0000ff;">We have already decided to use PI for all interfaces.</span></li>
<li><span style="color: #0000ff;">I will have to buy the BASIS team a case of beer to get them to agree to create indices on the fields KNA1-NAME1 and KNA1-NAME2 in a table with over one million records</span>.</li>
</ul>
</blockquote>
<p>I arrived at the conclusion that I need a case-insensitive database query, along with database indices created for the fields KNA1-NAME1 and KNA1-NAME2.</p>
<p>But, what is a case-insensitive WHERE clause?  A little research and help from colleagues revealed that many had gone before me, and this was nothing new.  To implement a case-insensitive WHERE clause in ABAP, you simply needed to use the native SQL UPPER() construct.  The database system that is being used is Microsoft SQL Server, but the UPPER() function and its syntax is similar across different database platforms.  This seemed like an easy nut to crack.  But, as I soon found out, I actually had a lot to learn.<br />
<span id="more-4929"></span></p>
<h3>Take 1</h3>
<p>The examples I found were very explicit, showing actual code snippets.  Using my research examples as a template, I built what was to be my first attempt at using native SQL in a ZTEST ABAP program:</p>
<pre style="background-color: #eaeaea; color: #222;">exec sql.
  select kunnr name1 name2
    from kna1
    into table i_cust
    where upper(name1) like :l_name1
      and upper(name2) like :l_name2
endexec.</pre>
<p>Well, as a native SQL rookie, I was stopped dead in my tracks.  Native SQL does not allow a select into a table – you can only select into a work area.</p>
<h3>Take 2</h3>
<p>In my ZTEST ABAP program, I changed the code to SELECT into a work area and append the work area to an internal table in a subroutine:</p>
<pre style="background-color: #eaeaea; color: #222;">exec sql performing append_cust.
  select kunnr, name1, name2
    from kna1
    into :wa_cust
    where upper(name1) like :l_name1
      and upper(name2) like :l_name2
endexec.

form append_cust.
  append wa_cust to i_cust.
endform.</pre>
<p>I really thought that this would work.  But, I was getting a syntax error from native SQL – the table name was not being recognized.  A little more research revealed that, in <em>some</em> cases, only UPPER CASE is valid for table names and field names.  OK.  I can handle that.</p>
<h3>Take 3</h3>
<p>I changed the native SQL statement to all UPPER CASE in my ZTEST ABAP program:</p>
<pre style="background-color: #eaeaea; color: #222;">EXEC SQL PERFORMING APPEND_CUST.
  SELECT KUNNR, NAME1, NAME2
    FROM KNA1
    INTO :WA_CUST
    WHERE UPPER(NAME1) LIKE :L_NAME1
      AND UPPER(NAME2) LIKE :L_NAME2
ENDEXEC.

form append_cust.
  append wa_cust to i_cust.
endform.</pre>
<p>This <em>appeared</em>to work just fine&#8230;  Except, I noticed that too many records were being returned.  A little more analysis showed that I was getting records from ALL clients, not just my logon client.</p>
<h3>Take 4</h3>
<p>Again, in my ZTEST ABAP program, specify the client:</p>
<pre style="background-color: #eaeaea; color: #222;">EXEC SQL PERFORMING APPEND_CUST.
  SELECT KUNNR, NAME1, NAME2
    FROM KNA1
    INTO :WA_CUST
    WHERE UPPER(NAME1) LIKE :L_NAME1
      AND UPPER(NAME2) LIKE :L_NAME2
      <span style="color: #ff0000;">AND MANDT = :L_MANDT</span>
ENDEXEC.

form append_cust.
  append wa_cust to i_cust.
endform.</pre>
<p>Now I was getting the results that I wanted!!!!  So, I pasted this ZTEST ABAP code into the ABAP proxy.</p>
<p>A syntax check of the code immediately rejected the use of subroutines &#8211; they are not allowed in OO ABAP.  I suppose I should have known that.  The error message indicated that I needed to use a cursor instead of the subroutine.  So, I started cursing – a lot!!!</p>
<h3>Take 5 (The Final Version)</h3>
<p>Here is the final version of the code which works for OO ABAP, and, hence, the ABAP proxy:</p>
<pre style="background-color: #eaeaea; color: #222;">EXEC SQL.
  OPEN CUSTCURSOR FOR
    SELECT KUNNR, NAME1, NAME2
      FROM KNA1
      WHERE UPPER(NAME1) LIKE :L_NAME1
        AND UPPER(NAME2) LIKE :L_NAME2
        AND MANDT = :L_MANDT
ENDEXEC.

DO.
  EXEC SQL.
    FETCH NEXT CUSTCURSOR INTO :WA_CUST
  ENDEXEC.

  IF SY-SUBRC NE 0.
    EXIT.
  ELSE.
    APPEND WA_CUST TO I_CUST.
  ENDIF.
ENDDO.

EXEC SQL.
  CLOSE CUSTCURSOR
ENDEXEC.</pre>
<p>Well, I finally got it right after five tries.  As mentioned before, I found many explicit code examples, but none were for OO ABAP with a database  requiring UPPER CASE be used, so that the table and field names would be recognized in the native SQL SELECT statement.</p>
<p>I learned something new about SAP.  I hope that I never stop learning.  I also hope that this blog might save someone a bit of distress in trying to work through a similar situation.  Now, I just need to figure out what kind of beer to buy the BASIS team to get those indexes created&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dataxstream.com/2010/05/using-native-sql-in-an-abap-proxy/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>The Art of Writing an SAP Functional Specification</title>
		<link>http://www.dataxstream.com/2010/04/writing-sap-functional-spec/</link>
		<comments>http://www.dataxstream.com/2010/04/writing-sap-functional-spec/#comments</comments>
		<pubDate>Tue, 20 Apr 2010 13:00:25 +0000</pubDate>
		<dc:creator>Mike Salvo</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[SAP ABAP Blog]]></category>
		<category><![CDATA[SAP Functional]]></category>
		<category><![CDATA[SAP Technical]]></category>
		<category><![CDATA[ABAP]]></category>
		<category><![CDATA[DataXstream]]></category>
		<category><![CDATA[functional specification document]]></category>
		<category><![CDATA[Mike Salvo]]></category>
		<category><![CDATA[Project Management]]></category>
		<category><![CDATA[RICEF]]></category>
		<category><![CDATA[SAP]]></category>
		<category><![CDATA[upgrades]]></category>

		<guid isPermaLink="false">http://www.dataxstream.com/?p=4599</guid>
		<description><![CDATA[Overview I am currently working on an SAP implementation project that is just starting its realization phase.  One of my first tasks, as a member of the technical implementation team, is to review completed functional specification documents for RICEF objects.  These documents, written by functional subject matter experts, are supposed to detail business requirements that [...]]]></description>
			<content:encoded><![CDATA[<h3>Overview</h3>
<p>I am currently working on an SAP implementation project that is just starting its realization phase.  One of my first tasks, as a member of the technical implementation team, is to review completed functional specification documents for RICEF objects.  These documents, written by functional subject matter experts, are supposed to detail business requirements that address gaps, and which need to be incorporated into the system being implemented. The purpose of the review is to make sure that the functional specification documents are complete, accurate, and contain the approval signatures required to move on to the technical design phase.</p>
<p><span id="more-4599"></span><br />
In my career, I have had the pleasure of working with some first-rate functional analysts who know how to draft an excellent functional specification document in a timely manner.  It is this type of performance that helps to move a project along in the right direction, on schedule, and within budget.  Likewise, I have had the not-so-pleasant task of working with not-so-first-rate functional analysts, who draft functional specification documents that are not clear, inaccurate, and incomplete.  The risks here are ultimately manifest as project delays and cost overruns.</p>
<h3>The Good…</h3>
<p>A really good functional specification document contains enough detailed information about the business process to enable a technical designer to use it as the foundation for drafting a complete and accurate technical design document.  The functional specification document should not only highlight the presence of a gap, but should demonstrate how the business process, accompanied by automation, will close the gap.  This document must also indicate the abnormal processing requirements – what should happen when that report or interface does not run, what are the recovery steps, how are key employees notified of the problem, etc.  The content of a functional specification document must be tuned to the flavor of the RICEF object that it is describing.  Since they perform very different tasks, a report specification document should be very much different from an interface, conversion, enhancement, or form functional specification document.  Using functional specification templates helps to insure the appropriate content for each type of RICEF object.</p>
<h3>… and the Not-So-Good.</h3>
<p>I am sometimes astonished by the sparse content that is actually offered up for review.  “We need a report” really does not tell me a whole lot about the business process that I am supposed to automate.  Nor does it even hint at the report purpose, content, layout, user interface, execution mode, authorization requirements, or error handling.  And likewise, “Build me an interface” does not even begin to describe the direction, payload content, mapping, frequency, error handling and recovery steps.  It would be so wrong for me to attempt to build a technical design on such meager functional definitions.   One of my favorite cartoons shows a development manager standing in front of rows of programmers saying “You guys start coding.  I’ll go and find out what they want”.</p>
<p>I am further astonished by:</p>
<p style="padding-left: 30px;">a)      the project managers who apply pressure to accept inaccurate and incomplete functional specification documents, to give the impression that the project is actually moving forward and making meaningful progress.</p>
<p style="padding-left: 30px;">b)      the functional analysts who whine incessantly when their paltry functional specification document is not accepted.</p>
<p>A functional specification document that does not meet expectations must be upgraded until it does.  But bouncing a functional specification document back and forth like a ping pong ball between the functional team and a technical reviewer is inefficient and wasteful.  I find that the best way to quickly firm up a weak functional specification document is to thoroughly research all of the issues that I found in the document, formulate proposed solutions where possible, and then schedule a face to face collaborative meeting with the functional analyst and the business process owner(s).  This type of collaboration can save hours, days, or even weeks of wasted ping-pong posturing, and that is always best outcome for the project.</p>
<h3><a href="http://www.dataxstream.com/2010/03/sap-upgrades-offshore-resources/">Off-Shore Technical Resources</a></h3>
<p>This face-to-face quick resolution scenario typically cannot happen if you have an off-shore technical contingent in play.  In this case, it is absolutely imperative that the functional specification document be most accurate and complete to mitigate the risk of excessive time loss.   Why is that?</p>
<p>Off-shore resources are sometimes time zone shifted eight or more hours ahead of where the project is located.  If a functional specification document is released for review, it will not be analyzed until we have left for the day.  If the off-shore reviewer has questions or raises issues, we will not see these questions or issues until the next day when we arrive at the project site.  When we respond to the questions or issues, the off-shore team will not see our response until we have left for the day.  And so on.</p>
<p>Under these conditions, a poorly written functional specification document with issues takes days instead of hours to resolve.  This leads to unnecessary project delays and cost overruns.</p>
<h3>When One is Really Many</h3>
<p>That 3PL interface, which was scoped and planned by the business process owners as a single RICEF object named “The 3PL Interface”; and for which only one interface functional specification document is written, is actually many RICEF objects.  We need to move purchase orders, inventory receipts, advance ship notices, inventory picks, and cycle counts between the two interfacing partners.  Each of these represents a different payload, different mapping, is triggered by a different point in the business process, has separate error handling and recovery procedures, and requires a separate RICEF development object.</p>
<p>That single enhancement functional specification document, which addresses all of SD pricing, has the potential to extend into many different user exits.  I just finished coding an ABAP proxy that was functionally specified as one interface.  In fact it was four.  The requirement was to search the database for sales and invoice data starting with either an invoice number, sales order number, customer name, or company name.  Each of these search techniques required the development of a separate method.  The only pieces of code that were shared among the four search techniques were the input parameters and the output return table.</p>
<p>The point here is to make sure that the project planners understand the real complexity and effort required on the development side, and to make sure that the project plan and budget reflects these more realistic metrics.  This really goes a long way to stop everyone from wondering, “It’s only one interface!  What is taking development so long?”</p>
<h3>Great Expectations</h3>
<p>So what is a reasonable set of expectations for a really good functional specification document?  What is it that we are asking the business analyst to do?</p>
<p>First, let me describe what I do not expect.  I do not expect a business analyst to write code, build tables, design efficient database retrievals, or to decide that one BAPI, function module, class, or IDOC is better than another.</p>
<p>Here is what I do expect:</p>
<p style="padding-left: 30px;">A clear definition of a business process that is repeatable, and which actually works.  As a pre-automation test for data conversions, I always require the functional analyst to manually enter one of whatever, using the standard SAP transaction for which a conversion program is to be built. Many times, they can’t because the system is not configured correctly, the supporting data is not present, or any number of other reasons which cause the transaction to fail.  An interesting observation is that there is much indignant huffing and puffing during this manual entry “test” process.  But when the manual test fails, I simply remind them that I cannot automate a broken or non-existent business process.</p>
<p style="padding-left: 30px;">A clear definition of what should happen under abnormal or failure circumstances.  This must include error handling, notification, recovery and reprocessing steps.</p>
<p style="padding-left: 30px;">A business process that can efficiently be automated.  Requiring a search of sales order header text for the phrase “This is a red order” is a very bad design for automation purposes.  While such a design is technically possible to build, it will certainly be inefficient at run time, and may not always produce all of the red orders.  This is because the key value is a free-form phrase that can and will be misspelled, and abbreviated, along with countless other mutilations of the key phrase “This is a red order”.  There are much better business processes and technical implementations that will more efficiently and more accurately find all of the red orders in your system.</p>
<p style="padding-left: 30px;">An explanation of the need for development.  Exactly what is the gap, and how will automating the business process close the gap?</p>
<p style="padding-left: 30px;">Screen shots from SAP transactions depicting data that is to be retrieved or stored.  From the screen shot in the transaction, I can usually determine the exact table and field in the SAP database.  Note that some business analysts are very adept at identifying the actual underlying table and field name.</p>
<p style="padding-left: 30px;">Clear and concise details with respect to data mappings, formulae, data transformations, conditional processing, etc.  If I come to an intersection and it is unclear whether I should continue to go straight, turn left, or turn right, then the functional specification document needs a bit more detail behind it.</p>
<p style="padding-left: 30px;">
<h3>How to insure Consistency in Functional Specification Document Review</h3>
<p>Design a separate functional specification document review checklist for each flavor of RICEF object.  Distribute these checklists to the functional specification writers so that they know what the expectations are.  Using a checklist will help to make sure that your review process is consistent and accurate.  Improve these checklists over time.  My Form functional specification checklist document now includes the following check:</p>
<p style="padding-left: 30px;">Is it physically possible to print the specified content on the specified form using the specified font style and size?  Was an actual printed mock-up provided as proof?</p>
<p>- but only after I had received a functional spec for a form that required four inches of print content on a one inch label.  And somehow, the business analyst who wrote this particular request erroneously thought that it was my problem to solve.   After all, writing code is magic!  Isn’t it?  In this case, I pushed back and insisted that an actual printed mock-up be produced &#8211; one that I would then agree to automate.</p>
<h3>Summary</h3>
<p>A good functional specification document will help tremendously in moving a project forward in the right direction with minimal cost and risk.  A poor functional specification document has serious potential to cause project delays, and  schedule and cost overruns.  The best goal for the project is to achieve a good functional specification document, using whatever means required.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dataxstream.com/2010/04/writing-sap-functional-spec/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Too Many Developers Spoil The Code</title>
		<link>http://www.dataxstream.com/2010/03/too-many-developers-spoil-the-code/</link>
		<comments>http://www.dataxstream.com/2010/03/too-many-developers-spoil-the-code/#comments</comments>
		<pubDate>Wed, 31 Mar 2010 13:24:42 +0000</pubDate>
		<dc:creator>Craig Stasila</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[SAP ABAP Blog]]></category>
		<category><![CDATA[SAP Interface Blog]]></category>
		<category><![CDATA[SAP Technical]]></category>
		<category><![CDATA[ABAP]]></category>
		<category><![CDATA[ABAP development]]></category>
		<category><![CDATA[BADI]]></category>
		<category><![CDATA[Basis/Netweaver]]></category>
		<category><![CDATA[Craig Stasila]]></category>
		<category><![CDATA[DataXstream]]></category>
		<category><![CDATA[Integration]]></category>
		<category><![CDATA[NetWeaver]]></category>
		<category><![CDATA[Project Management]]></category>
		<category><![CDATA[SAP ABAP]]></category>

		<guid isPermaLink="false">http://www.dataxstream.com/?p=4689</guid>
		<description><![CDATA[You may have heard the following idiom before: Too many cooks spoil the broth The common meaning extracted from this saying is that too many people working on a single task tend to make a mess of it.  But, what happens when you have too many developers working in a single piece of ABAP code? [...]]]></description>
			<content:encoded><![CDATA[<p>You may have heard the following idiom before:</p>
<blockquote><p>Too many cooks spoil the broth</p></blockquote>
<p>The common meaning extracted from this saying is that too many people working on a single task tend to make a mess of it.  But, what happens when you have too many developers working in a single piece of ABAP code?  That&#8217;s right, you get a big mess.  This issue is especially difficult to deal with when there are multiple functional requirements leveraging the same custom code object, form-based user-exit, or function-based user-exit.</p>
<p>While current releases of SAP (those built on SAP NetWeaver 2004s and later) have good built-in handling of enhancements and customizations via implicit and explicit enhancement points and BADIs, there still exists many old-school user-exits.</p>
<h2>Multiple Developers; One Code Object</h2>
<p>I recently worked on a project where three separate developers were creating three separate interfaces based on the outbound delivery IDOC.  While the development for all three interfaces was occurring at the same time, the go-live date for each of the interfaces were different (we&#8217;ll discuss that project management glitch at another time).  Each interface required a separate set of custom fields and, therefore, it&#8217;s own IDOC extension.  The problem is there is only one appropriate user-exit in IDOC_OUTPUT_DELVRY and three developers needed to be developing in it at the same time!</p>
<p>How did we solve this problem?<br />
<span id="more-4689"></span></p>
<h2>An Object To Call One&#8217;s Own</h2>
<p>To allow each developer his own development object and transport timeline, I decided to implement a custom multiple-use, filtered BADI <em>inside</em> the SAP user-exit function EXIT_SAPLV56K_002.  Actually, you can implement your own BADI almost anywhere you need alternate logic execution&#8211;even custom code!</p>
<p>So you might be saying, &#8220;Create my own multi-use, filtered BADI definition? Sounds complicated.&#8221; Well, it&#8217;s easier than you think!</p>
<p>NOTE: This solution was done on an ECC6 system based on SAP NetWeaver 2004s.  The steps to implement this type of solution in ECC5 (SAP NetWeaver 2004) are very similar.</p>
<h2>Create A Custom BADI Definition</h2>
<ol>
<li>To create a new enhancement spot definition, use transaction SE18.  I named my enhancement spot Z_EXIT_SAPLV56K_002 because the enhancement spot will be used in user-exit function EXIT_SAPLV56K_002.<br />
<a href="http://www.dataxstream.com/wp-content/uploads/2010/03/BADI-01.jpg" rel="shadowbox[sbpost-4689];player=img;"><img class="alignnone size-full wp-image-4694" title="BADI 01" src="http://www.dataxstream.com/wp-content/uploads/2010/03/BADI-01.jpg" alt="" width="399" height="179" /></a></li>
<li>In the ensuing dialog box, enter a description and choose <em>BAdi</em> <em>Definition</em> for the Technology<br />
<a href="http://www.dataxstream.com/wp-content/uploads/2010/03/BADI-02.jpg" rel="shadowbox[sbpost-4689];player=img;"><img class="alignnone size-full wp-image-4695" title="BADI 02" src="http://www.dataxstream.com/wp-content/uploads/2010/03/BADI-02.jpg" alt="" width="646" height="149" /></a></li>
<li>Next, create a new BADI definition.<br />
<a href="http://www.dataxstream.com/wp-content/uploads/2010/03/BADI-03.jpg" rel="shadowbox[sbpost-4689];player=img;"><img class="alignnone size-full wp-image-4696" title="BADI 03" src="http://www.dataxstream.com/wp-content/uploads/2010/03/BADI-03.jpg" alt="" width="614" height="191" /></a></li>
<li>Specify that the new BADI definition will be multiple use and limited to filtered use.<br />
<a href="http://www.dataxstream.com/wp-content/uploads/2010/03/BADI-04.jpg" rel="shadowbox[sbpost-4689];player=img;"><img class="alignnone size-full wp-image-4697" title="BADI 04" src="http://www.dataxstream.com/wp-content/uploads/2010/03/BADI-04.jpg" alt="" width="538" height="95" /><br />
</a>Making the BADI definition multiple use means that each developer can create his or her own BADI implementation.  Each BADI is implemented in its own class.  This promotes code separation and the proper reuse of shared development objects.<br />
Making the BADI definition limited to filter use ensures that the BADI implementations are separate and cannot affect every interface using the user-exit.</li>
<li>Now, create a new filter.<br />
<a href="http://www.dataxstream.com/wp-content/uploads/2010/03/BADI-05.jpg" rel="shadowbox[sbpost-4689];player=img;"><img class="alignnone size-full wp-image-4698" title="BADI 05" src="http://www.dataxstream.com/wp-content/uploads/2010/03/BADI-05.jpg" alt="" width="262" height="102" /></a><br />
BADI filtering in SAP NetWeaver 2004s is much more powerful than in previous versions of SAP.  Read more about BADI filtering <a href="http://help.sap.com/saphelp_nw04/helpdata/en/eb/3e7cf7940e11d295df0000e82de14a/frameset.htm" target="_blank">here</a>.</li>
<li><a href="http://www.dataxstream.com/wp-content/uploads/2010/03/BADI-05.jpg" rel="shadowbox[sbpost-4689];player=img;"></a> The BADI we are defining will be used to populate IDOC extensions.  Each IDOC extension has its own message type (e.g. ZMHL_DESADV, ZQTC_DESADV, ZMHL_SHPORD), therefore the message type of the IDOC being processed is a good value to filter on.  I named my BADI filter EDI_MESTYP.<br />
<a href="http://www.dataxstream.com/wp-content/uploads/2010/03/BADI-06.jpg" rel="shadowbox[sbpost-4689];player=img;"><img class="alignnone size-full wp-image-4710" title="BADI 06" src="http://www.dataxstream.com/wp-content/uploads/2010/03/BADI-06.jpg" alt="" width="588" height="288" /></a><br />
SAP allows for the automatic checking of BADI implementation filter values.  The standard domain EDI_MESTYP has a value range of table EDMSG attached to it.  This is exactly the range of values I want as allowable values, so I configure the BADI filter to automatically check the filter values against dictionary object EDI_MESTYP.</li>
<li>Next, create the BADI interface that will be inherited by each implementing class<br />
<a href="http://www.dataxstream.com/wp-content/uploads/2010/03/BADI-07.jpg" rel="shadowbox[sbpost-4689];player=img;"><img class="alignnone size-full wp-image-4700" title="BADI 07" src="http://www.dataxstream.com/wp-content/uploads/2010/03/BADI-07.jpg" alt="" width="572" height="149" /></a></li>
<li>The original user-exti function EXIT_SAPLV56K_002 is executed after each segment is added.  Our BADI will do the same.  Create a new public interface method SEGMENT_ADDED.<br />
<a href="http://www.dataxstream.com/wp-content/uploads/2010/03/BADI-08.jpg" rel="shadowbox[sbpost-4689];player=img;"><img class="alignnone size-full wp-image-4701" title="BADI 08" src="http://www.dataxstream.com/wp-content/uploads/2010/03/BADI-08.jpg" alt="" width="560" height="118" /></a></li>
<li>The BADI we are creating is replicating user-exit function EXIT_SAPLV56K_002.  Here is the function interface for EXIT_SAPLV56K_002:<br />
<a href="http://www.dataxstream.com/wp-content/uploads/2010/03/BADI-09_1.jpg" rel="shadowbox[sbpost-4689];player=img;"><img class="alignnone size-full wp-image-4711" title="BADI 09_1" src="http://www.dataxstream.com/wp-content/uploads/2010/03/BADI-09_1.jpg" alt="" width="602" height="383" /></a><br />
Here is the same data being passed via the interface method.<br />
<a href="http://www.dataxstream.com/wp-content/uploads/2010/03/BADI-09.jpg" rel="shadowbox[sbpost-4689];player=img;"><img class="alignnone size-full wp-image-4702" title="BADI 09" src="http://www.dataxstream.com/wp-content/uploads/2010/03/BADI-09.jpg" alt="" width="582" height="218" /></a></li>
<li>Lastly, the BADI has to be called from the existing user-exit.  I will not cover the steps required for implementing user-exit function EXIT_SAPLV56K_002 here, but once you have the user-exit implemented, add the following code.  This code should be the only logic directly inside the user-exit.  Any data processing logic should be implemented via a BADI implementation:
<pre style="background-color: #eaeaea; color: #222;">DATA: GO_BADI TYPE REF TO Z_EXIT_SAPLV56K_002.
DATA: L_STR TYPE STRING.
L_STR = MESSAGE_TYPE.

* Get BADI class based on IDOC message type
GET BADI GO_BADI
   FILTERS EDI_MESTYP = L_STR.

* Execute SEGMENT_ADDED BADI method
CALL BADI GO_BADI-&gt;SEGMENT_ADDED
   EXPORTING
     MESSAGE_TYPE       = MESSAGE_TYPE
     SEGMENT_NAME       = SEGMENT_NAME
     DATA               = DATA
     TAB_IDOC_REDUCTION = TAB_IDOC_REDUCTION
     FLT_VAL            = MESSAGE_TYPE
   CHANGING
     CONTROL_RECORD_OUT = CONTROL_RECORD_OUT
     IDOC_DATA          = IDOC_DATA[].</pre>
</li>
</ol>
<p>We&#8217;re done with creating the BADI definition!  Save and activate your work.  I bet you&#8217;re saying to yourself, &#8220;Wow, that was easy!&#8221;</p>
<h2>BADI Implementation</h2>
<p>Implementing the BADI you just created in the steps above is just like implementing any other BADI in SAP, so here are the Cliff Notes version of implementation instructions.</p>
<ol>
<li>Using transaction SE19, create a new enhancement spot implementation for Z_EXIT_SAPLV56K_002.<br />
<a href="http://www.dataxstream.com/wp-content/uploads/2010/03/BADI-10.jpg" rel="shadowbox[sbpost-4689];player=img;"><img class="alignnone size-full wp-image-4703" title="BADI 10" src="http://www.dataxstream.com/wp-content/uploads/2010/03/BADI-10.jpg" alt="" width="547" height="180" /></a></li>
<li>Enter the BADI implementation details.  This particular BADI implementation is for RICEF ID MHL-IO-007, so I added that identification to the BADI implementation name and implementing class name.<br />
<a href="http://www.dataxstream.com/wp-content/uploads/2010/03/BADI-12.jpg" rel="shadowbox[sbpost-4689];player=img;"><img class="alignnone size-full wp-image-4705" title="BADI 12" src="http://www.dataxstream.com/wp-content/uploads/2010/03/BADI-12.jpg" alt="" width="572" height="280" /></a></li>
<li>In the BADI definition, we required each BADI implementation to be filtered on message type. This particular BADI implementation is for message type ZMHL_SHPORD.  Create the filter combination for the BADI implementation.<br />
<a href="http://www.dataxstream.com/wp-content/uploads/2010/03/BADI-13.jpg" rel="shadowbox[sbpost-4689];player=img;"><img class="alignnone size-full wp-image-4706" title="BADI 13" src="http://www.dataxstream.com/wp-content/uploads/2010/03/BADI-13.jpg" alt="" width="586" height="149" /></a></li>
<li>This ensures that the other interfaces using this BADI (ZMHL_DESADV, ZQTC_DESADV) will not execute the code implemented with this BADI.<br />
<a href="http://www.dataxstream.com/wp-content/uploads/2010/03/BADI-14.jpg" rel="shadowbox[sbpost-4689];player=img;"><img class="alignnone size-full wp-image-4707" title="BADI 14" src="http://www.dataxstream.com/wp-content/uploads/2010/03/BADI-14.jpg" alt="" width="518" height="255" /></a></li>
<li>The final steps are to add the code to the SEGMENT_ADDED method just like you would in user-exit function EXIT_SAPLV56K_002.  Once you are done, save and activate your changes!</li>
</ol>
<h2>Summary</h2>
<p>As you can see, with a few extra steps, it is possible to have your cake and eat it, too, by create a custom BADI definition that can be used by other developers.  All this talk of food is making me hungry.  Is it lunchtime yet?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dataxstream.com/2010/03/too-many-developers-spoil-the-code/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

