LoginSignup
3
2

Excelの列番号からそれが何列目かを求めるメソッド(C#)

Last updated at Posted at 2024-04-20

やりたいこと

"A"を投げると1を、"B"を投げると2を、…、"AA"を投げると27を、…、"BA"を投げると55を返す。作成時点では、Excelのシートの右端の列番号はXFDだったので、"XFD"にまで対応できていればOK。

表にまとめるとこんな感じ。

引数 戻り値 $26^n$ごとに分解
A 1 $1 *26^0$
Z 26 $26 *26^0$
AA 27 $1 *26^1+1 *26^0$
BA 53 $2 *26^1+1 *26^0$
ZZ 702 $26 *26^1+26 *26^0$
AAA 703 $1 *26^2+1 *26^1+1 *26^0$
XFD 16384 $24 *26^2+6 *26^1+4 *26^0$

どう実装すればいいか分からなくて悩むときは、このように表にしてます。すると、何かが見えてくるはずです。知らんけど。
というわけで、こんな感じで実装してみました。

列番号→列数

private static int ConvertExcelColumnToNumber(string eCol) {    
    var colNumber = 0;
    for (var textIndex = 0; textIndex < eCol.Length; textIndex++) {
        colNumber += (int)Math.Pow(26, eCol.Length - 1 - textIndex) * (eCol[textIndex] - 64);
    }
    return colNumber;
}
ConvertExcelColumnToNumber("XFD"); //16384

OKです。

なぜこれでいいか考えてみます。
例えば、"DB"について考えます。列番号"DB"は、"CZ"よりも右に、"EA"よりも左に存在します。言い換えると、$104$($4*26$)列目よりも右に、$131$ ($5 *26+1$)列目よりも左に存在します。このことから、列番号が2桁で、最高位がDの場合は、$105$~$130$の値をとり得ます。そして、Bには2列分の長さがあるので、$104+2$で"DB"→$106$という関係性が生まれるみたいです。
俺は、下図のような感じで$26^n$ごとに引き算をしていく考え方が一番腑に落ちました。皆さんはどうでしょうか。
qiita_1_1.png

ついでに、その逆も実装してみました。

列数→列番号

private static string ConvertNumberToExcelColumn(int num) {
    var eColNum = new StringBuilder();
    do {
        eColNum.Insert(0, (char)((num % 26) + 64));
        num /= 26;
    } while (num > 0);
    return eColNum.ToString();
}
ConvertExcelColumnToNumber(16384); //"XFD"

OKです。

なぜこれでいいか考えてみます。
例えば、$1729$について考えます。$26$を基準にして変形すると、$1729 = 2 * 26^2 + 14 * 26^1 + 13 * 26^0$となるので、先ほどの考え方を逆転させると、最高位から順番に、"B", "N", "M"と変換できるので、正解は"BNM"となることが分かります。

ちなみに、"列番号"という単語をこの記事を書く際に初めて知りました。
アルファベットやのに列"番号"なんや…って思ったんは俺だけじゃないはず。

参照

VLOOKUP関数の列番号ってなに?|数え方や指定の仕方 - 病院SEにゃんとのPCトラブル解決&Excel関数等活用術

追記(2024/4/23)

これが初記事でしたが、思ったより読まれるもんなんですね。というわけで、どう考え方でこういった実装に至ったかを追記しました。これからもうちょい気合入れて書きます。
あと、タグに26進数ってつけてたんですけど、しまった、27進数か?と思ったんですけど、厳密にいえば何進数でもないですね。そもそもExcelには0列目という考え方が無かったもので。タグ消しときました。
仮に27番目のアルファベットを@とすると、下のようになりますね。

10進数 26進数 27進数 Excelの列番号
$0$ A A -
$1$ B B A
$2$ C C B
$10$ K K J
$25$ Z Z Y
$26$ BA @ Z
$27$ BB BA AA
$51$ BZ BX AY
$52$ CA BY AZ
$54$ CC B@ BB
$55$ CD CA BC

まあ改めて見ると一応26進数の数の増え方と若干似ていましたが、どちらとも微妙に異なる動きを取る、曲者でしたね。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2