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:
- MANDT (
100
) - HUIDENT (
00000000000000000083
) - LGNUM (
0210
) and - VHI (``)
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
3100300030003000300030003000300030003000300030003000300030003000300030003000300030003800320030003200310030002000
Working (copied from SM12
)
310030003000300030003000300030003000300030003000300030003000300030003000300030003000380032003000320031003000FFFF
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
- ENQUEUE wildcard
@
→#
(SM12
) →￿
(CTRL+C
) →FFFF
(hex value) → invisible in debugger
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
0x0031
=0000 0000 0011 0001
(16 bits)
split to bytes
- High byte:
0000 0000
=0x00
- Low byte:
0011 0001
=0x31
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
.
3100
(LSB first) v0031
(MSB first)
With this knowledge we can figure out that the hex sequence of 310030003000
corresponds to "MANDT
= 100
":
3100
= '1' (0x31 + 0x00)3000
= '0' (0x30 + 0x00)3000
= '0' (0x30 + 0x00)
References/Links
Technical Context: On-Prem, SAP EWM