1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[C#]Excelの列名のようなアルファベットと数値を相互変換する

Last updated at Posted at 2020-04-25

Excelの列名のようなアルファベットと数値を相互変換するメソッド

AtCoderのABC171を解いていて、もっと分かりやすい書き方があるなと思ったので修正しました (2020/6/28)。

        /// <summary>
        /// アルファベットを返す。
        /// 例えば、引数が1の時はA、2の時はB、27の時はAAとなる。
        /// 引数が不正な場合は<see cref="string.Empty"/>を返す。
        /// </summary>
        /// <param name="index">インデックス。1以上の値が有効</param>
        /// <returns>アルファベット</returns>
        public static string ToAlphabet(int index)
        {
            string alphabet = string.Empty;
            if (index < 1) return alphabet;

            while(index > 0)
            {
                // A-Zの変換を0-25にするため1を引く
                index--;
                // ASCIIではAは10進数で65
                alphabet = Convert.ToChar(index % 26 + 65) + alphabet; 
                index = index / 26;
            }

            return alphabet;
        }

        /// <summary>
        /// AからZのインデックスを返す。
        /// 例えば、引数がAの時は1、Bの時は2、AAの時は27となる。
        /// 引数が不正な場合は-1を返す。
        /// </summary>
        /// <param name="name">アルファベット。半角大文字のみ有効</param>
        /// <returns>インデックス</returns>
        public static int ToAlphabetIndex(string alphabet)
        {
            if (string.IsNullOrEmpty(alphabet))
            {
                return -1;
            }

            if (new Regex("^[A-Z]+$").IsMatch(alphabet))
            {
                int index = 0;
                for (int i = 0; i < alphabet.Length; i++)
                {
                    // ASCIIではAは10進数で65
                    int num = Convert.ToChar(alphabet[alphabet.Length - i - 1]) - 65;
                    // A-Zの変換が0-25になっているため1を足して、A-Zが1-26になるようにする
                    num++;

                    index += (int)(num * Math.Pow(26, i));
                }
                return index;
            }

            return -1;
        }


Excelの列名変換のようなアルファベットを数値から取得したり、アルファベットから数値に変換できるようにしたかったため作成しました。

        /// <summary>
        /// アルファベットを返す。
        /// 例えば、引数が1の時はA、2の時はB、27の時はAAとなる。
        /// 引数が不正な場合は<see cref="string.Empty"/>を返す。
        /// </summary>
        /// <param name="index">インデックス。1以上の値が有効</param>
        /// <returns>アルファベット</returns>
        public static string ToAlphabet(int index)
        {
            string alphabet = string.Empty;
            if (index < 1) return alphabet;

            index--;

            do
            {
                alphabet = Convert.ToChar(index % 26 + 0x41) + alphabet;
            }
            while
            ((index = index / 26 - 1) != -1);

            return alphabet;
        }

        /// <summary>
        /// AからZのインデックスを返す。
        /// 例えば、引数がAの時は1、Bの時は2、AAの時は27となる。
        /// 引数が不正な場合は-1を返す。
        /// </summary>
        /// <param name="name">アルファベット。半角大文字のみ有効</param>
        /// <returns>インデックス</returns>
        public static int ToAlphabetIndex(string alphabet)
        {
            if (string.IsNullOrEmpty(alphabet))
            {
                return -1;
            }

            if (new Regex("^[A-Z]+$").IsMatch(alphabet))
            {
                int index = 0;
                for (int i = 0; i < alphabet.Length; i++)
                {
                    int num = Convert.ToChar(alphabet[alphabet.Length - i - 1]) - 64;

                    index += (int)(num * Math.Pow(26, i));
                }
                return index;
            }

            return -1;
        }

@albireo さんより、拡張メソッドの方が使いやすいとのコメントをいただきましたので拡張メソッドバージョンも載せておきます。(2020/4/26 追記)

        /// <summary>
        /// アルファベットを返す。
        /// 例えば、引数が1の時はA、2の時はB、27の時はAAとなる。
        /// 引数が不正な場合は<see cref="string.Empty"/>を返す。
        /// </summary>
        /// <param name="index">インデックス。1以上の値が有効</param>
        /// <returns>アルファベット</returns>
        public static string ToAlphabet(this int index)
        {
            string alphabet = string.Empty;
            if (index < 1) return alphabet;

            index--;

            do
            {
                alphabet = Convert.ToChar(index % 26 + 0x41) + alphabet;
            }
            while
            ((index = index / 26 - 1) != -1);

            return alphabet;
        }

        /// <summary>
        /// AからZのインデックスを返す。
        /// 例えば、引数がAの時は1、Bの時は2、AAの時は27となる。
        /// 引数が不正な場合は-1を返す。
        /// </summary>
        /// <param name="name">アルファベット。半角大文字のみ有効</param>
        /// <returns>インデックス</returns>
        public static int ToAlphabetIndex(this string alphabet)
        {
            if (string.IsNullOrEmpty(alphabet))
            {
                return -1;
            }

            if (new Regex("^[A-Z]+$").IsMatch(alphabet))
            {
                int index = 0;
                for (int i = 0; i < alphabet.Length; i++)
                {
                    int num = Convert.ToChar(alphabet[alphabet.Length - i - 1]) - 64;

                    index += (int)(num * Math.Pow(26, i));
                }
                return index;
            }

            return -1;
        }

参考

https://memo-c-sharp.blogspot.com/2015/09/excel.html
http://devlabo.blogspot.com/2009/04/c.html

1
4
2

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
1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?