How-To Avoid Prefixing Zeroes in OData NUMC Fields
Contents
Have you ever seen prefixing zeroes in a Fiori application?
NUMC Values
An IDoc number would work well as an example:
Prefixing zeroes in IDoc number
Since the ID of our IDoc is really just 4, it does not make sense to display it with 15 prefixing zeroes. The reason why it has those extra zeroes in the first place comes down to how IDoc numbers are technically defined in SAP:
IDoc number data element
IDoc numbers are NUMC values, ie. “numerical text”. NUMC values are essentially character strings with some special properties. Like normal character strings, NUMC values have a defined length. Unlike normal character strings, the set of valid characters in NUMC values is restricted: only characters 0123456789 are allowed.
This means that whereas an initial CHAR value would just be an empty string, an initial NUMC value with length 5 would be 00000. The character set restrictions are enforced when values are assigned to NUMC fields, although the rules are somewhat surprising:
|
|
According to ABAP documentation, the rules of assigning character strings to NUMC variables are:
The characters in the source field that represent digits are passed right-justified to the target field. Other characters are ignored. If the target field is longer than the number of digits in the source field, it is padded on the left with the character “0”. If the target field is shorter, the characters are cut off on the left.
Me, personally, would have expected to get an error when trying to assign invalid characters to a NUMC variable… What the readers with keen senses just heard was the monkey’s paw curling.
Because NUMC fields can, by definition, only contain numerical data, ABAP assumes that they should be compared to other character strings as numerical values. Ie, if NUMC and CHAR values are to be compared, both are converted to packed numbers and their values are compared. Insofar as this ignores any prefixing spaces and zeroes in the CHAR field, this will probably be the right thing to do. However, given that there’s absolutely no guarantee that CHAR field contains a valid numerical value, this can also be a source for crashes if one is not careful:
|
|
ABAP documentation presents the following table for comparing between types:
Comparison rules for character-like data
In practice these rules tend not to cause problems, since NUMC fields are mostly used in keys and keys are usually only ever compared to other keys.
The enforcement of digits-only values is not quite foolproof:
|
|
NUMC Values Cause Prefixing Zeroes in Fiori Applications
NUMC values are normally displayed without the prefixing zeroes in SAPGUI:
IDoc number in WE02
Although even this is not always consistent:
Prefixing zeroes appear in screen title and tree
While the OData framework converts some values for output (see How-To Enable Input Conversion for OData Function Parameters), somewhat perplexingly the prefixing zeroes of NUMC fields are left unaltered and returned to the caller. The value that we saw in our Fiori application (0000000000000004) was the exact value that SAP sent us:
SAP returns prefixing zeroes
This is strange, given that SAP has clearly tried to hide the in-memory representation of other values in OData and has also hidden the NUMC in-memory representation in SAPGUI.
Avoiding Prefixing Zeroes in Fiori
In the Fiori application, you can change the way that values are displayed by using formatters or expression bindings. For example, we could choose to use JavaScript function parseInt to get rid of the prefixing zeroes:
|
|
No more prefixing zeroes
This does not, of course, solve the root-cause of why we have the undesired prefixing zeroes in the first place. For that, we need to create a CHAR -type version of the IDoc number and we need to use that in our OData definition:
IDoc number as text
After we have changed our OData entity to use a data element based on this domain and re-imported the the property in SEGW, the OData framework will return the value without prefixing zeroes:
No more prefixing zeroes
Extra: Using WBS Element Number in OData
The ALPHA conversion routine performs fairly modest alterations on the value, pretty much just adding or removing prefixing zeroes. The conversion routine for WBS element numbers, ABPSP, represents the other extreme: the before-conversion and after-conversion values have seemingly nothing to do with one another:
No obvious connection between the two representations of the key
The only connection between 00003510 and L.0166.E.M.1.CE is the project structure stored in SAP database. The conversion exit is so complex because the numerical id needs to be converted into a form which represents the hierarchical structure of the project: the actual WBS element is actually just the last CE part of the converted key, the other parts representing the hierarchy.
However, using the standard data element for WBS element number produces some strange results in OData:
|
|
Clearly, 000000000000000000001661 matches neither 00003510 nor L.0166.E.M.1.CE. What is going on here?
The length, 24 characters, appears to come from the WBS element number domain:
WBS element number domain
Here the output length is defined as 24 characters. Also, because the value has prefixing zeroes, we can deduce that it was probably a NUMC variable in ABAP.
Finally, we note that the digits that actually appear in the value are those that also appeared in the converted WBS element number L.0166.E.M.1.CE, ie. 0, 1, 6, 6 and 1.
Putting all this together, it seems that:
- When performing output conversions, the OData framework takes the output length and data type from the domain -> WBS element number thus becomes a
NUMCfield with length 24 - But because of the assignment rules we already glanced through, trying to perform the WBS element number output conversion into a
NUMCfield results in only the digit characters being preserved, producing the corrupted value
Ie. it appears that in SAPGUI, the output conversion is always performed to a CHAR field of the specified length, whereas the OData framework incorrectly inherits the NUMC type when performing output conversions.
Creating a CHAR domain for WBS element numbers allows us to take advantage of the automatic input-output -conversion:
WBS element CHAR domain
|
|
This is another strange shortcoming of the OData framework. While preserving the prefixing zeroes of NUMC may be an intentional behavior, the way the conversion exit does not work strikes me more as a bug than anything intentional.