One topic that is important in SD, but is often overlooked is the use of units of measure in custom ABAP programming. In SAP, units of measure are stored in a series of tables that begin with T006:
The table which controls various language translations of a unit of measure is table T006A. I’ll explain more on that shortly.
SAP does a lot of work behind the scenes that most developers rarely ever see. When calling up any item in SAP, a delivery for example, SAP will perform conversions of their data before displaying it to the user. This is done for several fields, but one of those fields is the unit of measure of the delivery item. SAP will convert the unit into what’s known as the external, or commercial unit of measure. This is the unit of measure that is displayed to the user. On the flipside, when a user enters a unit of measure into the delivery item and saves that data, SAP assumes that the user is entering the unit as the external or commercial unit of measure and will convert that entry into the internal unit of measure, or the unit of measure that is stored in SAP.
The difference between the internal and external units of measure are sometimes very hard to distinguish as they often look the same in English. What it boils down to is that the internal unit of measure is language independent, meaning that it is the same in ALL languages. The external or commercial unit of measure varies depending upon the language it is being viewed from. A developer may never know this when dealing with units such as KG or M2 because these are typically stored the same way in all languages.
In the example above, the first unit is the internal unit, while the second unit (MSEH3) is the commercial unit. Both the internal and commercial units are the same in all languages. The problem begins to occur with units that vary in different languages.
One example is a crate. In German, a crate is “Kiste”, so the internal unit of measure is “KI”. Since SAP is a German system, the commercial unit is also “KI”. However, in English, we would not identify it as a “KI”, but rather something like “CRT”. We now have a difference. Also, in this example, the Japanese unit is in kanji:
One mistake a developer may do is create a custom field using the external, or commercial unit of measure. Another is to define a unit of measure variable as a CHAR3 with the intent of writing this value to a text file. This will cause the field to take the form of whatever is found in the table. If a user has pulled this data straight from a delivery and writes it directly to the CHAR3 variable, SAP hasn’t converted that text yet, and because the data has been assigned a variable without a conversion exit, it never will be converted.
For illustration purposes, I built a custom program and table. This program takes an input, and writes the data to the screen. Here are few examples.
Note that I’ve entered the commercial unit of measure here.
What just happened? The unit of measure was converted when assigned the field in the table to be added to the database, however, when it was written to a character variable, it was not converted back before output.
This example writes the unit of measure from the internal unit of measure field
Again, what happens here is that SAP converts it to the internal unit so that it can store the correct value in the table, however, before it is written to the screen, it is converted to the commercial unit of measure automatically.
Simply put, the reason this happened is because the commercial unit of measure (MSEH3) does not contain a user exit. Therefore, when the converted unit of measure is assigned to this field, it is currently in its internal format, and does not get converted to it external format. The issue is that SAP will not automatically perform this conversion when assigning values to variables without the proper conversion exit.
Let’s take another issue that can occur with improper conversions. This can be seen when a developer writes a custom program to mass load data into a table. As an example, I made modifications to my existing program to also store records.
As you can see, when you look at the records SE16N, the new record from the above example appears.
However, when attempting to find the record:
This is caused by storing the improper unit of measure here. The commercial unit was not converted before it was added to the database. So, when running SE16N, when the user enters the unit of measure in the search criteria, SAP automatically converts that into the internal unit of measure. Since the commercial unit is the one that got stored, SAP cannot find a match.
When writing custom programs, a developer must take caution when dealing with units of measure. In many cases, it will be responsibility of the developer to perform the conversion of the units manually, especially when failing to use the correct variable with the conversion exit built in. Fortunately, SAP is good at providing the needed tools to accomplish this. From SE11, the data element for the internal unit of measure(MSEHI) has the domain MEINS.
Double clicking the domain name and clicking on the definition tab will show the conversion routing of the data element.
In this example, it is “CUNIT”. Double-clicking the conversion routine name will show the INPUT and OUTPUT conversion routines for this field.
The typical naming convention of a conversion routine is “CONVERSION_EXIT_” followed by the conversion exit name, followed by a final piece to explain the purpose of the function.
For example, CONVERSION_EXIT_CUNIT_OUTPUT is the conversion exit used to convert an internal unit of measure to the commercial unit for user display, while CONVERSION_EXIT_CUNIT_INPUT is the conversion exit used to convert a commercial unit entered by the user to the SAP internal unit of measure when used for storage. As a rule of thumb, OUTPUT is used data is written to a screen, document, etc. While INPUT is used when using that data as input for interacting with SAP table data.
When using the conversion exit for units of measure, one key piece of information is the language. When using the conversion exits, it is best to avoid constants for the language and to use the system variable SY-LANGU. This will always provide the logon language when converting units of measure.
Going back to our example, I’ve added the needed conversion routines to my code. Now, let’s run the report again:
As you can see, both the internal and external units of measure show correctly, and SE16 is able to successfully find the record.
It’s a little confusing at first to distinguish between the internal and external units of measure, but after some time, this will become very clear and will allow for any custom development to handle unit of measure information coming and going.