読者です 読者をやめる 読者になる 読者になる
ようこそ。睡眠不足なプログラマのチラ裏です。

数値をアルファベット(26進数ぽ)へ変換、それはExcelのカラム名的な何か。

プログラミング アルゴリズム C#3.0

Excelをごにょごにょしていると、Excelの79列目のカラム名が「CA」だとかってのを、
取得したくなることがある。そんなときのためのブツ。こーゆーのは再帰でうまく表現できますね(^ω^)

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication1
{
    static class Program
    {
        static void Main()
        {
            Enumerable.Range(1, 16384).Select(n => n.ToAlphabet()).ForEach(s => Console.WriteLine(s));
            Console.ReadLine();
        }

        /// <summary>
        /// Excelのカラム名的なアルファベット文字列へ変換します。
        /// </summary>
        /// <param name="self"></param>
        /// <returns>
        /// Excelのカラム名的なアルファベット文字列。
        /// (変換できない場合は、空文字を返します。)
        /// </returns>
        static string ToAlphabet(this int self)
        {
            if (self <= 0) return "";
            int n = self % 26;
            n = (n == 0) ? 26 : n;
            string s = ((char)(n + 64)).ToString();
            if (self == n) return s;
            return ((self - n) / 26).ToAlphabet() + s;
        }

        static void ForEach<T>(this IEnumerable<T> src, Action<T> action)
        {
            foreach (T item in src) { action(item); }
        }
    }
}

実行結果

A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z
AA
AB
AC
(中略)
XCZ
XDA
XDB
XDC
XDD
XDE
XDF
XDG
XDH
XDI
XDJ
XDK
XDL
XDM
XDN
XDO
XDP
XDQ
XDR
XDS
XDT
XDU
XDV
XDW
XDX
XDY
XDZ
XEA
XEB
XEC
XED
XEE
XEF
XEG
XEH
XEI
XEJ
XEK
XEL
XEM
XEN
XEO
XEP
XEQ
XER
XES
XET
XEU
XEV
XEW
XEX
XEY
XEZ
XFA
XFB
XFC
XFD

使ったことないけど、Excel2007は16384列(カラム名「XFD」)までイケルらしい。
カラムがそんなに必要になることなんてあるんか?w



(追記:2008/09/05)
ちなみにラムダ式で書くとこんな感じ

        /// <summary>
        /// Excelのカラム名的なアルファベット文字列へ変換します。
        /// </summary>
        /// <param name="self"></param>
        /// <returns>
        /// Excelのカラム名的なアルファベット文字列。
        /// (変換できない場合は、空文字を返します。)
        /// </returns>
        static string ToAlphabet(this int self)
        {
            Func<int, string> f = x =>
            {
                var s = ((char)(((x == 0) ? 26 : x) + 64)).ToString();
                return (self == x) ? s : ((self - x) / 26).ToAlphabet() + s;
            };
            return (self <= 0) ? "" : f(self % 26);
        }