wridgeu

are they really the same?

problem

A colleague encountered an issue with ENQUEUE_READ where locks visible in SM12 couldn't be read programmatically. The lock argument built at runtime failed, but copying it from SM12 into the debugger worked.

The values appeared identical, but were they really?

It is important to note that all of this happened in the context of the SAPGUI. So regular SM12 and debugger.

additional context

We're in SAP EWM and want to lock a specific handling unit (HU). We make use of the SAP standard function module ENQUEUE_/SCWM/EHU (or maybe /SCWM/HU_READ with iv_lock = 'X').

The lock argument is a concatenation of:

resulting in: 100000000000000000000830210.

Pretty straight forward, right? The programmatically built argument appeared identical to what SM12 displayed, yet ENQUEUE_READ failed to find the lock.

So why didn't it work? And why did it work once the value was copy/pasted from SM12 into the debugger?

analyzing the lock argument values

Now comes the fun part. Were the values truly equal?

To figure this out I compared the hexadecimal value of the variables. For ease of reading I'll leave out the spaces/blanks at the end of the variables.

Not Working

Working (copied from SM12)

Notice something? There is an odd FFFF where, in the not working version, the blanks/spaces already start, as indicated by the value 2000.

When looking at the lock argument in SM12 you notice that the GUI displays an additional # at the end, resulting in 100000000000000000000830210#. Odd, isn't it?

But my colleague copied the "detail view" of the lock. In there, not a single additional character was added, or so he thought.

I checked his clipboard and noticed that there was an additional Unicode character which the debugger variable display cannot show. Making the copied value look like 100000000000000000000830210ï¿¿. We can confirm this by decoding the hex value of FFFF which results in ï¿¿ (= U+FFFF, undefined character).

Where did the additional character come from?

lock argument creation

Turns out there is something missing when creating the lock argument. So ... how does SAP do it?

The following code is an extract of the ENQUEUE_/SCWM/EHU function module.

The structure making up the lock argument is pre-filled with wildcard characters. When you look at it in the debugger, the character is a @-symbol.

DATA: BEGIN OF %a_/SCWM/S_HUHDR_INT,
*       Lock argument for table /SCWM/S_HUHDR_INT
            MANDT TYPE /SCWM/S_HUHDR_INT-MANDT,
            HUIDENT TYPE /SCWM/S_HUHDR_INT-HUIDENT,
            LGNUM TYPE /SCWM/S_HUHDR_INT-LGNUM,
            VHI TYPE /SCWM/S_HUHDR_INT-VHI,
      END OF %a_/SCWM/S_HUHDR_INT.
* Initialization of lock argument:
CALL 'C_ENQ_WILDCARD' ID 'HEX0' FIELD %a_/SCWM/S_HUHDR_INT.

Then, component for component, the actual values are moved into the structure but only if they're NOT INITIAL. Well ... a "real" HU in EWM does not have a VHI indicator and is therefore left empty/initial.

What happens is that all components but the last one are filled, leaving the VHI component untouched and therefore initialized with the wildcard character.

The following value assignment builds up the lock argument. Essentially creating 100000000000000000000830210@.

_seqta_tab-garg = %a/SCWM/S_HUHDR_INT.

The wildcard character cannot be shown in the GUI and is therefore displayed as # in SM12. When you manually copy the lock argument, this - depending on the Dynpro - "invisible" character is copied as well and therefore results in the correct working lock argument in the debugger.

solution

To now properly create the lock argument you'll have to consider the VHI indicator of the handling unit. If you're dealing with a "real" handling unit, you'll have to add the wildcard to the end of your lock argument to ensure that you can read the lock.

Character Transformation Chain

aside: hex values in the debugger, UTF-16, ASCII

The hex values in the debugger are UTF-16 where each character takes 2 bytes. That's why 1 becomes 3100 instead of just 31. The character 1 has a ASCII Unicode point of U+0031.

conv to binary

split to bytes

little-endian vs big-endian

The values are in little-endian, you can verify this by using the hex decode tool and choosing "UTF-16LE" as Input/Output encoding. Or by comparing the actual values of the debugger as they start with 3100 and not 0031.

With this knowledge we can figure out that the hex sequence of 310030003000 corresponds to "MANDT = 100":


References/Links

Technical Context: On-Prem, SAP EWM

#/SCWM/HU_READ #/SCWM/S_HUHDR_INT #ENQUEUE_/SCWM/EHU #abap #debugger #dequeue #enqueue #ewm #hex #hu #lock #sap #sapewm #sapgui #sm12 #unicode #utf-16