For one of our external systems we collect the data from both R/3 and APO and last week I had an interesting problem of potential conflict between document numbers. The planned orders that are created in APO but not published to R/3 are (hopefully) guaranteed to have different document numbers than those existing in R/3. I guess you can configure the systems so that they will be using the same number range. So, if you are transferring R/3 and APO planned orders, there should not be any problems in mixing documents.
Now, imagine we have to transfer the material reservations of the planned order. If not all BOM components are known to APO, R/3 does the BOM explosion when the APO order gets published into R/3. If the order is not published, I have to make the BOM explosion in R/3 myself. How do I assign reservation numbers in a safe way? My first idea was to simply use the planned order number as reservation number abd the BOM position and the reservation position number. Wrong way. This does not ensure that the reservation numbers you “simulate” this way differ from real ones from the RESB table, because planned orders and reservations use different number ranges.
What saved me was that the reservation number for my external system doesn’t have to be purely numeric. Actually, even in R/3 itself it’s defined as “character” of length 10, and it’s only number range logic that results in numeric reservation numbers. How can we encode the numbers easily so that they will be distinct? I started looking at hexadecimal encoding. I needed to squeeze ten decimal positions into less, to save at least one position to use it as a prefix, something like “A” at the beginning, to make the resulting number (ok, not the number but “identifier”) 100% distinct. For if left just hexadecimal, we can easily have a hexadecimal number consisting just of digits, and we may end up with conflicting document numbers again.
If we split the maximum document number into two parts, i.e. two of 99999, each part can be represented with a hex number of 1869F. Same five positions! But the first one needs only one bit, it’s either zero or one! Thus, taking last four positions of both parts, and combining first two positions together into one hex digit, I can encode the whole thing into exactly nine positions, leaving one for my prefix. For example, 9999999999 will be coded like 03869F869F, and the external system will get something like A3869F869F.
The rest is the ABAP code that does the encoding:
form encode_via_hex using pf_char10 changing pf_char10_out. data: lf_num51(5) type n, lf_hex4(4) type x, lf_num1(1) type n, lf_char8(8 ) type c. pf_char10_out = '0000000000'. * first part lf_num51 = pf_char10(5). lf_hex4 = lf_num51. write lf_hex4 to lf_char8. lf_num1 = lf_char8+3(1) * 2. pf_char10_out+6(4) = lf_char8+4(4). * second part lf_num51 = pf_char10+5(5). lf_hex4 = lf_num51. write lf_hex4 to lf_char8. lf_num1 = lf_num1 + lf_char8+3(1). pf_char10_out+2(4) = lf_char8+4(4). pf_char10_out+1(1) = lf_num1. endform.