エクセルの列名と列番号を変換するには
エクセルはセルを「A1」とか「AB10」のように英字の列と数字の行番号で指定するのだけど(A1スタイルと云うのかな)、たまに列番号で指定したいときもある。
ということで、列番号を渡すと列名を返すメソッドを作ってみる。このメソッドがあると、5列目を”E”列のように変換できるので、列番号で指定できるようになる。
この種のメソッドを作るときに間違いやすいのが、1で始まるデータであるところ。上のコードでいえばfor文の3番目の式「c = (c - 1) / 26」を「c /= 26」と書いてしまったりする。そうすると、26が渡されたときにループをもう1回まわってしまって、"AA"に変換されてしまう。正しくは"Z"です。
上のメソッドをテストするのが次のコード。
前の投稿で文字コードのことを調べていたのは、このテストでアルファベット26文字分のテストをループを回して済ませたかったからなのでした。
*
逆に”A”を渡すと1を返すメソッドも作ってみる。
作った時期が違うので、メソッド名も引数もローカル変数名もバラバラですな、なかなか恥ずかしい。
そして単体テストがこちら。
こうしてテストで確認できるようにしてあると、確かに安心。
ということで、列番号を渡すと列名を返すメソッドを作ってみる。このメソッドがあると、5列目を”E”列のように変換できるので、列番号で指定できるようになる。
- /// <summary>
- /// 列番号からエクセルの列名を得る (例 5 → "E")
- /// </summary>
- /// <param name="c"></param>
- /// <returns></returns>
- static public string GetCellA1(int c)
- {
- string alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- string s = "";
- for (; c > 0; c = (c - 1) / 26 )
- {
- int n = (c - 1) % 26;
- s = alpha.Substring(n, 1) + s;
- }
- return s;
- }
この種のメソッドを作るときに間違いやすいのが、1で始まるデータであるところ。上のコードでいえばfor文の3番目の式「c = (c - 1) / 26」を「c /= 26」と書いてしまったりする。そうすると、26が渡されたときにループをもう1回まわってしまって、"AA"に変換されてしまう。正しくは"Z"です。
上のメソッドをテストするのが次のコード。
- [TestMethod()]
- public void GetCellA1Test()
- {
- Assert.AreEqual(ExcelLib.Util.GetCellA1(1), "A");
- Assert.AreEqual(ExcelLib.Util.GetCellA1(26), "Z");
- Assert.AreEqual(ExcelLib.Util.GetCellA1(27), "AA");
- Assert.AreEqual(ExcelLib.Util.GetCellA1(702), "ZZ");
- Assert.AreEqual(ExcelLib.Util.GetCellA1(703), "AAA");
- for (int i = 1; i <= 26; i++)
- {
- string s = Convert.ToChar(Convert.ToInt32('A') + i - 1).ToString();
- Assert.AreEqual(ExcelLib.Util.GetCellA1(i), s);
- }
- }
前の投稿で文字コードのことを調べていたのは、このテストでアルファベット26文字分のテストをループを回して済ませたかったからなのでした。
*
逆に”A”を渡すと1を返すメソッドも作ってみる。
- /// <summary>
- /// エクセルの列名から列番号を得る(例:"A"→1)
- /// </summary>
- /// <param name="col"></param>
- /// <returns></returns>
- static public int getExcel列番号(string col)
- {
- string abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- int m = 0;
- for (int i = 0; i < col.Length; i++)
- {
- string c = col.Substring(i, 1);
- int n = abc.IndexOf(c) + 1;
- m += n * (int)Math.Pow(26, col.Length - i - 1);
- }
- return m;
- }
作った時期が違うので、メソッド名も引数もローカル変数名もバラバラですな、なかなか恥ずかしい。
そして単体テストがこちら。
- [TestMethod]
- public void Test_getExcel列番号()
- {
- Assert.AreEqual(mmExcel.getExcel列番号("A"), 1);
- Assert.AreEqual(mmExcel.getExcel列番号("B"), 2);
- Assert.AreEqual(mmExcel.getExcel列番号("C"), 3);
- Assert.AreEqual(mmExcel.getExcel列番号("AA"), 27);
- Assert.AreEqual(mmExcel.getExcel列番号("AAA"), 703); // 26 * 27 + 1 = 26 * (26 + 1) + 1
- int c = Convert.ToInt32('A');
- for (int i = 0; i < 26; i++)
- {
- string s = Convert.ToChar(c + i).ToString();
- Assert.AreEqual(mmExcel.getExcel列番号(s), i + 1);
- }
- }
こうしてテストで確認できるようにしてあると、確かに安心。
コメント
コメントを投稿