# 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
increments to →
 N … 3 2 1 B

#### Example 2

 N … 3 2 1 Z
increments to →
 N … 3 2 1 A A

#### Example 3

 N … 3 2 1 A Z
increments to →
 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.
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.
<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
to ASCII →
 N … 3 2 1 65
result →
65 x 1 = 65

#### Example 2

 N … 3 2 1 Z
to ASCII →
 N … 3 2 1 90
result →
90 x 1 = 90

#### Example 3

 N … 3 2 1 A B
to ASCII →
 N … 3 2 1 65 66
result →
65 x 2 + 66 x 1 = 196

#### Example 4

 N … 3 2 1 B A
to ASCII →
 N … 3 2 1 66 65
result →
66 x 2 + 65 x 1 = 197

## 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.