Introduction
An alphabetic counter is a counter that increments from A to B to C etc. through all letters of the alphabet. After Z the counter increases its length by one and increments from AA to AB to AC, etc. By applying this pattern recursively, an alphabetic counter may have an infinite number of values just like a numeric counter. An example with which you may be familiar is Microsoft Excel which uses an alphabetic counter to uniquely name columns.
Incrementing the Counter
An odometer is a useful model for incrementing an alphabetic counter. From right to left, each position increments from A to Z just as each position of an odometer increments from 0 to 9 (though each alphabetic position actually has blank as its starting value). When the final value is reached (Z or 9) the position rolls back to its starting value (A or 0) and the left-adjacent position is incremented. This algorithm can be applied recursively at each position along the alphabetic string.
Example 1
N | ... | 3 | 2 | 1 |
A |
N | ... | 3 | 2 | 1 |
B |
Example 2
N | ... | 3 | 2 | 1 |
Z |
N | ... | 3 | 2 | 1 |
A | A |
Example 3
N | ... | 3 | 2 | 1 |
A | Z |
N | ... | 3 | 2 | 1 |
B | A |
Translating this Algorithm to ABAP
The routine to implement this algorithm is recursive. It increments an alphabetic string at a specific position then, if that position has reached final character Z, increments the left-adjacent position by way of a recursive call to itself. In this demonstration, the algorithm is implemented as a method of a class, but it may also be implemented as a function module, form subroutine or other routine.
Create method increment_alpha with the following signature.
Parameter Declaration Type | Parameter Name | Parameter Typing |
Importing | value( position ) | type i |
Changing | alpha | type csequence |
Exception | non_alpha |
method increment_alpha. data offset type i. data character_tab type standard table of char1. field-symbols <char> type char1. * Split changing parameter alpha into a table of single characters to facilitate substring handling call function 'SWA_STRING_TO_TABLE' exporting character_string = alpha line_size = 1 importing character_table = character_tab exceptions others = 0. if position is initial. add 1 to position. endif. read table character_tab assigning <char> index position. check <char> is assigned. * An initial character is incremented to 'A' if <char> is initial. <char> = sy-abcde(1). " A * Reconstitute changing parameter alpha from the character table call function 'SWA_STRING_FROM_TABLE' exporting character_table = character_tab importing character_string = alpha exceptions others = 0. exit. " we're done elseif <char> cn sy-abcde. raise non_alpha. endif. " <char> * Increment the alphabetic counter string case <char>. when sy-abcde+25(1). " Z * Roll Z back to A at the current position <char> = sy-abcde(1). " A * Reconstitute changing parameter alpha from the character table call function 'SWA_STRING_FROM_TABLE' exporting character_table = character_tab importing character_string = alpha exceptions others = 0. * Increment the left-adjacent position by recursively calling this method increment_alpha( exporting position = ( position - 1 ) changing alpha = alpha ). when others. " A-Y * Increment the current alphabetic character find <char> in sy-abcde ignoring case match offset offset. add 1 to offset. <char> = sy-abcde+offset(1). * Reconstitute changing parameter alpha from the character table call function 'SWA_STRING_FROM_TABLE' exporting character_table = character_tab importing character_string = alpha exceptions others = 0. endcase. " <char> endmethod.
The initial call to increment_alpha method passes in the whole alphabetic counter string using its complete length as position. The method then recursively increments the alphabetic counter string one character at a time along the length of the string.
data alpha_counter type string value 'ABC'. " for example * Increment the alpha counter and assign equipment name. We extend the * length of the alpha string by 1 place to accommodate a potential additional * character, e.g., Z > AA. shift alpha_counter right. increment_alpha( exporting position = numofchar( alpha_counter ) changing alpha = alpha_counter ).
Sorting Counter Values
To correctly sort alphabetic counter values like A, Z, AB, BA, we cannot rely on a simple character sort because AA would come before Z which is not true in the odometer model. An algorithm which calculates the sum of each alphabetic character's ASCII numeric value multiplied by its odometer position provides a reliable sort value for alphabetic counter values.
Example 1
N | ... | 3 | 2 | 1 |
A |
N | ... | 3 | 2 | 1 |
65 |
Example 2
N | ... | 3 | 2 | 1 |
Z |
N | ... | 3 | 2 | 1 |
90 |
Example 3
N | ... | 3 | 2 | 1 |
A | B |
N | ... | 3 | 2 | 1 |
65 | 66 |
Example 4
N | ... | 3 | 2 | 1 |
B | A |
N | ... | 3 | 2 | 1 |
66 | 65 |
Translating this Algorithm to ABAP
data alpha_counter type string value 'ABC'. " for example data offset type i. data character_at_this_position type char1. data sort_value type i. do strlen( alpha_counter ) times. offset = strlen( alpha_counter ) - sy-index. character_at_this_position = alpha_counter+offset(1). sort_value = sort_value + ( cl_abap_conv_out_ce=>uccpi( character_at_this_position ) * sy-index ). enddo.
When applied to a table of alphabetic counter values, each record's sort value may be used to correctly sort the table according to the odometer model.