Edit 1 Thanks to Simon and whuber for pointing out that the original post contained an error. While the approach that I described yields the correct results for the test range, it produces wrong results for other ranges. For example, for Range[670, 680] the results are {"YU", "YV", "YW", "YX", "YY", "YZ", "A@A", "A@B", "A@C", "A@D", "A@E"}, which is clearly not as required.
Edit 2 As whuber points out, the problem with this base is that depending on the circumstances either a 0 or a 1 may correspond with A. For example, when the result of IntegerDigits[n, 26] is {1,0} the string should be AA.
I have adapted the function in such a way that all 0's are done away with, and 1 is set to always mean A. First I increment the input by 1, so the result for 0 becomes {1}, which equals A. Then all 0's which are not at the starting position are replaced by 26 while the preceding number is decremented by one. Then all 0 at the start of the list are simply removed.
This means that the previous result of "A@A" ({1,0,1}) becomes "ZA" ({26, 1}).
j[n_] := FromCharacterCode[64 + (IntegerDigits[n + 1, 26]
//. {
{s___, p_, 0, r___} -> {s, p - 1, 26, r},
{0, r___} -> {r}
})]
I have validated the results with the method of Simon up to 10^6.
Original post
This uses IntegerDigits with base 26 and a correction for the last digit:
FromCharacterCode[64 + (IntegerDigits[#, 26] /. {m___, n_} -> {m, n + 1})] & /@ (10^Range[8])
(* {"K", "CW", "ALM", "NTQ", "EQXE", "BDWGO", "UVXWK", "HJUNYW"} *)
FromCharacterCode, that should help you along the way. – jVincent Oct 25 '12 at 9:48