web-dev-qa-db-ja.com

列番号(例:127)をExcel列(例:AA)に変換する方法

オートメーションを使用せずにExcelから直接値を取得することなく、数値をC#でExcelの列名に変換する方法。

Excel 2007には、1から16384の範囲で指定できます。これは、サポートしている列の数です。結果の値は、Excelの列名の形式になります。 A、AA、AAAなど.

431
robertkroll

これが私のやり方です。

private string GetExcelColumnName(int columnNumber)
{
    int dividend = columnNumber;
    string columnName = String.Empty;
    int modulo;

    while (dividend > 0)
    {
        modulo = (dividend - 1) % 26;
        columnName = Convert.ToChar(65 + modulo).ToString() + columnName;
        dividend = (int)((dividend - modulo) / 26);
    } 

    return columnName;
}
839
Graham

誰かがVBAなしでExcelでこれを実行する必要があるならば、ここに方法があります:

=SUBSTITUTE(ADDRESS(1;colNum;4);"1";"")

colNumは列番号です。

そしてVBAでは:

Function GetColumnName(colNum As Integer) As String
    Dim d As Integer
    Dim m As Integer
    Dim name As String
    d = colNum
    name = ""
    Do While (d > 0)
        m = (d - 1) Mod 26
        name = Chr(65 + m) + name
        d = Int((d - m) / 26)
    Loop
    GetColumnName = name
End Function
57
vzczc

申し訳ありませんが、これはC#ではなくPythonですが、少なくとも結果は正しいです。

def ColIdxToXlName(idx):
    if idx < 1:
        raise ValueError("Index is too small")
    result = ""
    while True:
        if idx > 26:
            idx, r = divmod(idx - 1, 26)
            result = chr(r + ord('A')) + result
        else:
            return chr(idx + ord('A') - 1) + result


for i in xrange(1, 1024):
    print "%4d : %s" % (i, ColIdxToXlName(i))
20
RoMa

AAZのようなExcelの列アドレスから整数への変換、および任意の整数からExcelへの変換など、両方向の変換が必要になる場合があります。以下の2つの方法でそれが可能になります。 1から始まるインデックスを作成すると仮定します。あなたの "配列"の最初の要素は要素番号1です。ここでサイズに制限はありません。

public static string ColumnAdress(int col)
{
  if (col <= 26) { 
    return Convert.ToChar(col + 64).ToString();
  }
  int div = col / 26;
  int mod = col % 26;
  if (mod == 0) {mod = 26;div--;}
  return ColumnAdress(div) + ColumnAdress(mod);
}

public static int ColumnNumber(string colAdress)
{
  int[] digits = new int[colAdress.Length];
  for (int i = 0; i < colAdress.Length; ++i)
  {
    digits[i] = Convert.ToInt32(colAdress[i]) - 64;
  }
  int mul=1;int res=0;
  for (int pos = digits.Length - 1; pos >= 0; --pos)
  {
    res += digits[pos] * mul;
    mul *= 26;
  }
  return res;
}
17
Arent Arntzen

私は最初の投稿で誤りを発見したので、私は座って数学をすることにしました。私が見つけたのは、他の人が投稿したように、Excelの列を識別するために使用されている数体系は基数26の体系ではないということです。ベース10で次のことを考慮してください。また、アルファベットの文字でこれを行うことができます。

スペース:......................... S1、S2、S3:S1、S2、S3
.......................................................................................................... 、AA、AAA
..................... 1、01、001:.. B 、AB、AAB
...................................... 、…、…
........................................................................................................................... 9、99、999:.. 、ZZ、ZZZ
空間の総状態数:10、100、1000:26、676、17576
合計の国:............... 1110 ................ 18278

Excelでは、基数26を使用して個々のアルファベット空間の列に番号が付けられています。一般に、基底aの状態空間数列はa、a ^ 2、a ^ 3、…であり、状態の総数はa + aです。 ^ 2 + a ^ 3 +…。

最初のN個のスペースに含まれる状態の総数Aを求めたいとします。そのための式は、A =(a)(a ^ N - 1)/(a-1)です。インデックスKに対応する空間Nを見つける必要があるので、これは重要です。Kが番号体系のどこにあるかを調べたい場合は、AをKに置き換えてNを求める必要があります。解はN = log {基底a}(A(a − 1)/ a + 1)。 a = 10とK = 192の例を使用すると、N = 2.23804とわかります。これは、Kが2より少し大きいので、Kが3番目のスペースの始めにあることを私に伝えています。

次のステップは、現在の空間でどれだけ遠くにいるのかを正確に見つけることです。これを見つけるには、Nのフロアを使用して生成されたAをKから減算します。この例では、Nのフロアは2です。そのため、最初の2つのスペースの状態を組み合わせると予想されるように、A =(10)(10 ^ 2 - 1)/(10-1)= 110となります。これらの最初の110の状態はすでに最初の2つのスペースで説明されているため、これはKから減算する必要があります。これは私達に82の州を残します。したがって、この数体系では、10進法の192の表記は082です。

ゼロのベースインデックスを使用するC#コードは、

    private string ExcelColumnIndexToName(int Index)
    {
        string range = string.Empty;
        if (Index < 0 ) return range;
        int a = 26;
        int x = (int)Math.Floor(Math.Log((Index) * (a - 1) / a + 1, a));
        Index -= (int)(Math.Pow(a, x) - 1) * a / (a - 1);
        for (int i = x+1; Index + i > 0; i--)
        {
            range = ((char)(65 + Index % a)).ToString() + range;
            Index /= a;
        }
        return range;
    }

//古い投稿

C#のゼロベースの解決策。

    private string ExcelColumnIndexToName(int Index)
    {
        string range = "";
        if (Index < 0 ) return range;
        for(int i=1;Index + i > 0;i=0)
        {
            range = ((char)(65 + Index % 26)).ToString() + range;
            Index /= 26;
        }
        if (range.Length > 1) range = ((char)((int)range[0] - 1)).ToString() + range.Substring(1);
        return range;
    }
13
John

再帰が簡単

public static string GetStandardExcelColumnName(int columnNumberOneBased)
{
  int baseValue = Convert.ToInt32('A');
  int columnNumberZeroBased = columnNumberOneBased - 1;

  string ret = "";

  if (columnNumberOneBased > 26)
  {
    ret = GetStandardExcelColumnName(columnNumberZeroBased / 26) ;
  }

  return ret + Convert.ToChar(baseValue + (columnNumberZeroBased % 26) );
}
10
Peter
int nCol = 127;
string sChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string sCol = "";
while (nCol >= 26)
{
    int nChar = nCol % 26;
    nCol = (nCol - nChar) / 26;
    // You could do some trick with using nChar as offset from 'A', but I am lazy to do it right now.
    sCol = sChars[nChar] + sCol;
}
sCol = sChars[nCol] + sCol;

更新Peter のコメントは正しいです。それが私がブラウザでコードを書くために得るものです。 :-)私の解決策はコンパイルされていませんでした、それは一番左の文字を見逃していました、そしてそれは逆の順序で文字列を構築していました - すべて修正されました。

バグは別にして、このアルゴリズムは基本的に10から26までの数を変換しています。

Update 2Joel Coehoorn 正しい - 上記のコードは27のABを返します。実際の基数26の数であれば、 AAはAに等しくなり、Zの後の次の数はBAになります。

int nCol = 127;
string sChars = "0ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string sCol = "";
while (nCol > 26)
{
    int nChar = nCol % 26;
    if (nChar == 0)
        nChar = 26;
    nCol = (nCol - nChar) / 26;
    sCol = sChars[nChar] + sCol;
}
if (nCol != 0)
    sCol = sChars[nCol] + sCol;
10
Franci Penov

この答えはjavaScriptです。

function getCharFromNumber(columnNumber){
    var dividend = columnNumber;
    var columnName = "";
    var modulo;

    while (dividend > 0)
    {
        modulo = (dividend - 1) % 26;
        columnName = String.fromCharCode(65 + modulo).toString() + columnName;
        dividend = parseInt((dividend - modulo) / 26);
    } 
    return  columnName;
}
8
MaVRoSCy

私はこれまでのところすべての解決策が反復または再帰のどちらかを含んでいるのに驚いています。

これが一定時間で実行される私の解決策です(ループなし)。この解決策は、考えられるすべてのExcel列に対して機能し、入力がExcel列に変換できることを確認します。可能な列は[A、XFD]または[1、16384]の範囲です。 (これはExcelのバージョンによって異なります)

private static string Turn(uint col)
{
    if (col < 1 || col > 16384) //Excel columns are one-based (one = 'A')
        throw new ArgumentException("col must be >= 1 and <= 16384");

    if (col <= 26) //one character
        return ((char)(col + 'A' - 1)).ToString();

    else if (col <= 702) //two characters
    {
        char firstChar = (char)((int)((col - 1) / 26) + 'A' - 1);
        char secondChar = (char)(col % 26 + 'A' - 1);

        if (secondChar == '@') //Excel is one-based, but modulo operations are zero-based
            secondChar = 'Z'; //convert one-based to zero-based

        return string.Format("{0}{1}", firstChar, secondChar);
    }

    else //three characters
    {
        char firstChar = (char)((int)((col - 1) / 702) + 'A' - 1);
        char secondChar = (char)((col - 1) / 26 % 26 + 'A' - 1);
        char thirdChar = (char)(col % 26 + 'A' - 1);

        if (thirdChar == '@') //Excel is one-based, but modulo operations are zero-based
            thirdChar = 'Z'; //convert one-based to zero-based

        return string.Format("{0}{1}{2}", firstChar, secondChar, thirdChar);
    }
}
8
user2023861

..そしてphpに変換:

function GetExcelColumnName($columnNumber) {
    $columnName = '';
    while ($columnNumber > 0) {
        $modulo = ($columnNumber - 1) % 26;
        $columnName = chr(65 + $modulo) . $columnName;
        $columnNumber = (int)(($columnNumber - $modulo) / 26);
    }
    return $columnName;
}
7
Stephen Fuhry

ここでのすべての答えは必要以上にはるかに複雑に思えるので、再帰を使用して単純な2行のC#実装を投入するだけです。

/// <summary>
/// Gets the column letter(s) corresponding to the given column number.
/// </summary>
/// <param name="column">The one-based column index. Must be greater than zero.</param>
/// <returns>The desired column letter, or an empty string if the column number was invalid.</returns>
public static string GetColumnLetter(int column) {
    if (column < 1) return String.Empty;
    return GetColumnLetter((column - 1) / 26) + (char)('A' + (column - 1) % 26);
}
7
Extragorey

Javaでの同じ実装

public String getExcelColumnName (int columnNumber) 
    {     
        int dividend = columnNumber;   
        int i;
        String columnName = "";     
        int modulo;     
        while (dividend > 0)     
        {        
            modulo = (dividend - 1) % 26;         
            i = 65 + modulo;
            columnName = new Character((char)i).toString() + columnName;        
            dividend = (int)((dividend - modulo) / 26);    
        }       
        return columnName; 
    }  
6
Balaji.N.S

少しゲームが遅れていますが、私が使用しているコードは次のとおりです(C#で)。

private static readonly string _Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static int ColumnNameParse(string value)
{
    // assumes value.Length is [1,3]
    // assumes value is uppercase
    var digits = value.PadLeft(3).Select(x => _Alphabet.IndexOf(x));
    return digits.Aggregate(0, (current, index) => (current * 26) + (index + 1));
}
5
Kelly L

私が使っている静的クラスを、col indexとcol Labelの間で相互運用するために投入したいと思いました。私のColumnLabelメソッドには修正済みの回答を使用しています

public static class Extensions
{
    public static string ColumnLabel(this int col)
    {
        var dividend = col;
        var columnLabel = string.Empty;
        int modulo;

        while (dividend > 0)
        {
            modulo = (dividend - 1) % 26;
            columnLabel = Convert.ToChar(65 + modulo).ToString() + columnLabel;
            dividend = (int)((dividend - modulo) / 26);
        } 

        return columnLabel;
    }
    public static int ColumnIndex(this string colLabel)
    {
        // "AD" (1 * 26^1) + (4 * 26^0) ...
        var colIndex = 0;
        for(int ind = 0, pow = colLabel.Count()-1; ind < colLabel.Count(); ++ind, --pow)
        {
            var cVal = Convert.ToInt32(colLabel[ind]) - 64; //col A is index 1
            colIndex += cVal * ((int)Math.Pow(26, pow));
        }
        return colIndex;
    }
}

こんな感じで….

30.ColumnLabel(); // "AD"
"AD".ColumnIndex(); // 30
5
t3dodson

ここで提供されているすべてのバージョンを見た後、私は再帰を使用して自分自身をすることにしました。

これが私のvb.netバージョンです。

Function CL(ByVal x As Integer) As String
    If x >= 1 And x <= 26 Then
        CL = Chr(x + 64)
    Else
        CL = CL((x - x Mod 26) / 26) & Chr((x Mod 26) + 1 + 64)
    End If
End Function
5
user932708

コードなしのセル式に使いたいだけの場合は、次のようになります。

IF(COLUMN()>=26,CHAR(ROUND(COLUMN()/26,1)+64)&CHAR(MOD(COLUMN(),26)+64),CHAR(COLUMN()+64))
4
Matt Lewis

Delphi(パスカル)の場合:

function GetExcelColumnName(columnNumber: integer): string;
var
  dividend, modulo: integer;
begin
  Result := '';
  dividend := columnNumber;
  while dividend > 0 do begin
    modulo := (dividend - 1) mod 26;
    Result := Chr(65 + modulo) + Result;
    dividend := (dividend - modulo) div 26;
  end;
end;
4
JRL
private String getColumn(int c) {
    String s = "";
    do {
        s = (char)('A' + (c % 26)) + s;
        c /= 26;
    } while (c-- > 0);
    return s;
}

その正確に基数26ではありません、システムには0がありません。もしあれば、 'Z'の後に 'AA'ではなく 'BA'が続きます。

3
rubberduckie

Perlでは、1(A)、27(AA)などの入力に対して.

sub Excel_colname {
  my ($idx) = @_;       # one-based column number
  --$idx;               # zero-based column index
  my $name = "";
  while ($idx >= 0) {
    $name .= chr(ord("A") + ($idx % 26));
    $idx   = int($idx / 26) - 1;
  }
  return scalar reverse $name;
}
2
Myforwik

JavaScriptソリューション

/**
 * Calculate the column letter abbreviation from a 1 based index
 * @param {Number} value
 * @returns {string}
 */
getColumnFromIndex = function (value) {
    var base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
    var remainder, result = "";
    do {
        remainder = value % 26;
        result = base[(remainder || 26) - 1] + result;
        value = Math.floor(value / 26);
    } while (value > 0);
    return result;
};
2
Ally

元のソリューションを改良する(C#で):

public static class ExcelHelper
{
    private static Dictionary<UInt16, String> l_DictionaryOfColumns;

    public static ExcelHelper() {
        l_DictionaryOfColumns = new Dictionary<ushort, string>(256);
    }

    public static String GetExcelColumnName(UInt16 l_Column)
    {
        UInt16 l_ColumnCopy = l_Column;
        String l_Chars = "0ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        String l_rVal = "";
        UInt16 l_Char;


        if (l_DictionaryOfColumns.ContainsKey(l_Column) == true)
        {
            l_rVal = l_DictionaryOfColumns[l_Column];
        }
        else
        {
            while (l_ColumnCopy > 26)
            {
                l_Char = l_ColumnCopy % 26;
                if (l_Char == 0)
                    l_Char = 26;

                l_ColumnCopy = (l_ColumnCopy - l_Char) / 26;
                l_rVal = l_Chars[l_Char] + l_rVal;
            }
            if (l_ColumnCopy != 0)
                l_rVal = l_Chars[l_ColumnCopy] + l_rVal;

            l_DictionaryOfColumns.ContainsKey(l_Column) = l_rVal;
        }

        return l_rVal;
    }
}
2
ShloEmi

これがActionscriptバージョンです。

private var columnNumbers:Array = ['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'];

    private function getExcelColumnName(columnNumber:int) : String{
        var dividend:int = columnNumber;
        var columnName:String = "";
        var modulo:int;

        while (dividend > 0)
        {
            modulo = (dividend - 1) % 26;
            columnName = columnNumbers[modulo] + columnName;
            dividend = int((dividend - modulo) / 26);
        } 

        return columnName;
    }
2
Rob

もう一つのVBA方法

Public Function GetColumnName(TargetCell As Range) As String
    GetColumnName = Split(CStr(TargetCell.Address), "$")(1)
End Function
2
Paul Ma

これはGrahamのコードによるとJavaScriptのバージョンです。

function (columnNumber) {
    var dividend = columnNumber;
    var columnName = "";
    var modulo;

    while (dividend > 0) {
        modulo = (dividend - 1) % 26;
        columnName = String.fromCharCode(65 + modulo) + columnName;
        dividend = parseInt((dividend - modulo) / 26);
    }

    return columnName;
};
1
Kevin

私はJavaで同じことをやろうとしています...私は以下のコードを書きました:

private String getExcelColumnName(int columnNumber) {

    int dividend = columnNumber;
    String columnName = "";
    int modulo;

    while (dividend > 0)
    {
        modulo = (dividend - 1) % 26;

        char val = Character.valueOf((char)(65 + modulo));

        columnName += val;

        dividend = (int)((dividend - modulo) / 26);
    } 

    return columnName;
}

ColumnNumber = 29で実行すると、result = "CA"( "AC"ではなく)が表示されます。足りないものはありますか。 StringBuilderでそれを元に戻すことができることを私は知っています....しかし、Grahamの答えを見て、私は少し混乱しています....

1
Hasan

これは、他のすべてのユーザーおよびGoogleのリダイレクト先の質問ですので、ここに掲載します。

これらの答えの多くは正しいですが、26列を超えない場合などの単純な状況では面倒です。あなたが二重文字の列に入るかもしれないかどうか疑いがあるならこの答えを無視してください、しかしあなたがそうしないと確信しているなら、あなたはそれをC#でこれと同じくらい簡単にすることができます:

public static char ColIndexToLetter(short index)
{
    if (index < 0 || index > 25) throw new ArgumentException("Index must be between 0 and 25.");
    return (char)('A' + index);
}

あなたが渡しているものに自信があるのであれば、検証を削除してこのインラインを使用することもできます。

(char)('A' + index)

これは多くの言語で非常によく似ていますので、必要に応じて調整することができます。

繰り返しになりますが、26列を超えないことが100%確実な場合にのみ使用してください

1

申し訳ありませんが、これはC#ではなくPythonですが、少なくとも結果は正しいです。

def Excel_column_number_to_name(column_number):
    output = ""
    index = column_number-1
    while index >= 0:
        character = chr((index%26)+ord('A'))
        output = output + character
        index = index/26 - 1

    return output[::-1]


for i in xrange(1, 1024):
    print "%4d : %s" % (i, Excel_column_number_to_name(i))

これらのテストケースに合格しました:

  • 列番号:494286 => ABCDZ
  • 列番号:27 => AA
  • 列番号:52 => AからZ
1
DataEngineer

私は試合に遅れていますが、 Graham's answer は最適ではありません。特に、moduloを使用してToString()を呼び出し、(int)キャストを適用する必要はありません。 C#の世界ではほとんどの場合、0から番号を付けることを考えると、これが私の改訂です。

public static string GetColumnName(int index) // zero-based
{
    const byte BASE = 'Z' - 'A' + 1;
    string name = String.Empty;

    do
    {
        name = Convert.ToChar('A' + index % BASE) + name;
        index = index / BASE - 1;
    }
    while (index >= 0);

    return name;
}
1
Herman Kan

これらの私のコードは、特定の番号(1から始まるインデックス)をExcelの列に変換します。

    public static string NumberToExcelColumn(uint number)
    {
        uint originalNumber = number;

        uint numChars = 1;
        while (Math.Pow(26, numChars) < number)
        {
            numChars++;

            if (Math.Pow(26, numChars) + 26 >= number)
            {
                break;
            }               
        }

        string toRet = "";
        uint lastValue = 0;

        do
        {
            number -= lastValue;

            double powerVal = Math.Pow(26, numChars - 1);
            byte thisCharIdx = (byte)Math.Truncate((columnNumber - 1) / powerVal);
            lastValue = (int)powerVal * thisCharIdx;

            if (numChars - 2 >= 0)
            {
                double powerVal_next = Math.Pow(26, numChars - 2);
                byte thisCharIdx_next = (byte)Math.Truncate((columnNumber - lastValue - 1) / powerVal_next);
                int lastValue_next = (int)Math.Pow(26, numChars - 2) * thisCharIdx_next;

                if (thisCharIdx_next == 0 && lastValue_next == 0 && powerVal_next == 26)
                {
                    thisCharIdx--;
                    lastValue = (int)powerVal * thisCharIdx;
                }
            }

            toRet += (char)((byte)'A' + thisCharIdx + ((numChars > 1) ? -1 : 0));

            numChars--;
        } while (numChars > 0);

        return toRet;
    }

私のユニットテスト:

    [TestMethod]
    public void Test()
    {
        Assert.AreEqual("A", NumberToExcelColumn(1));
        Assert.AreEqual("Z", NumberToExcelColumn(26));
        Assert.AreEqual("AA", NumberToExcelColumn(27));
        Assert.AreEqual("AO", NumberToExcelColumn(41));
        Assert.AreEqual("AZ", NumberToExcelColumn(52));
        Assert.AreEqual("BA", NumberToExcelColumn(53));
        Assert.AreEqual("ZZ", NumberToExcelColumn(702));
        Assert.AreEqual("AAA", NumberToExcelColumn(703));
        Assert.AreEqual("ABC", NumberToExcelColumn(731));
        Assert.AreEqual("ACQ", NumberToExcelColumn(771));
        Assert.AreEqual("AYZ", NumberToExcelColumn(1352));
        Assert.AreEqual("AZA", NumberToExcelColumn(1353));
        Assert.AreEqual("AZB", NumberToExcelColumn(1354));
        Assert.AreEqual("BAA", NumberToExcelColumn(1379));
        Assert.AreEqual("CNU", NumberToExcelColumn(2413));
        Assert.AreEqual("GCM", NumberToExcelColumn(4823));
        Assert.AreEqual("MSR", NumberToExcelColumn(9300));
        Assert.AreEqual("OMB", NumberToExcelColumn(10480));
        Assert.AreEqual("ULV", NumberToExcelColumn(14530));
        Assert.AreEqual("XFD", NumberToExcelColumn(16384));
    }
1
S_R

すでに30を超えるソリューションがありますが、これが私の1行のC#ソリューションです...

public string IntToExcelColumn(int i)
{
    return ((i<16926? "" : ((char)((((i/26)-1)%26)+65)).ToString()) + (i<2730? "" : ((char)((((i/26)-1)%26)+65)).ToString()) + (i<26? "" : ((char)((((i/26)-1)%26)+65)).ToString()) + ((char)((i%26)+65)));
}
1
AlishahNovin

これが私の超最近のPHP実装です。これは再帰的です。この記事を見つける直前に書いた。他の人がすでにこの問題を解決しているかどうか確認したいのですが….

public function GetColumn($intNumber, $strCol = null) {

    if ($intNumber > 0) {
        $intRem = ($intNumber - 1) % 26;
        $strCol = $this->GetColumn(intval(($intNumber - $intRem) / 26), sprintf('%s%s', chr(65 + $intRem), $strCol));
    }

    return $strCol;
}
1
Gordon Freeman

簡潔でエレガントRubyバージョン:

def col_name(col_idx)
    name = ""
    while col_idx>0
        mod     = (col_idx-1)%26
        name    = (65+mod).chr + name
        col_idx = ((col_idx-mod)/26).to_i
    end
    name
end
0
Iwan B.

NodeJSの実装

/**
* getColumnFromIndex
* Helper that returns a column value (A-XFD) for an index value (integer).
* The column follows the Common Spreadsheet Format e.g., A, AA, AAA.
* See https://stackoverflow.com/questions/181596/how-to-convert-a-column-number-eg-127-into-an-Excel-column-eg-aa/3444285#3444285
* @param numVal: Integer
* @return String
*/
getColumnFromIndex: function(numVal){
   var dividend = parseInt(numVal);
   var columnName = '';
   var modulo;
   while (dividend > 0) {
      modulo = (dividend - 1) % 26;
      columnName = String.fromCharCode(65 + modulo) + columnName;
      dividend = parseInt((dividend - modulo) / 26);
   }
   return columnName;
},

おかげで Excelの列のアルファベット(例:AA)を数字(例:25)に変換 。そして逆に:

/**
* getIndexFromColumn
* Helper that returns an index value (integer) for a column value (A-XFD).
* The column follows the Common Spreadsheet Format e.g., A, AA, AAA.
* See https://stackoverflow.com/questions/9905533/convert-Excel-column-alphabet-e-g-aa-to-number-e-g-25
* @param strVal: String
* @return Integer
*/
getIndexFromColumn: function(val){
   var base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', i, j, result = 0;
   for (i = 0, j = val.length - 1; i < val.length; i += 1, j -= 1) {
      result += Math.pow(base.length, j) * (base.indexOf(val[i]) + 1);
   }
   return result;
}
0
Rob Sawyer

別の解決策:

private void Foo()
{
   l_ExcelApp = new Excel.ApplicationClass();
   l_ExcelApp.ReferenceStyle = Excel.XlReferenceStyle.xlR1C1;
   // ... now reference by R[row]C[column], Ex. A1 <==> R1C1, C6 <==> R3C6, ...
}

ここでもっと見てください - 皆のためにExcelでセル参照!Dr Nitin Paranjapeによる

0
ShloEmi

私は今日この仕事をしなければなりませんでした、私の実装は再帰を使用します:

private static string GetColumnLetter(string colNumber)
{
    if (string.IsNullOrEmpty(colNumber))
    {
        throw new ArgumentNullException(colNumber);
    }

    string colName = String.Empty;

    try
    {
        var colNum = Convert.ToInt32(colNumber);
        var mod = colNum % 26;
        var div = Math.Floor((double)(colNum)/26);
        colName = ((div > 0) ? GetColumnLetter((div - 1).ToString()) : String.Empty) + Convert.ToChar(mod + 65);
    }
    finally
    {
        colName = colName == String.Empty ? "A" : colName;
    }

    return colName;
}

これは、文字列として来る番号をメソッドと、 "0"で始まる番号(A = 0)と見なします。

0
Madison Tobal

もう1つVBAの答えを見た - これは1行のUDFで Excel-vba で行うことができる:

Function GetColLetter(ByVal colID As Integer) As String
    GetColLetter = Split(Cells(1, colID).Address, "$")(1)
End Function
0
Sam

それが価値があるもののために、これはPowershellのGrahamのコードです:

function ConvertTo-ExcelColumnID {
param (
    [parameter(Position = 0,
        HelpMessage = "A 1-based index to convert to an Excel column ID. e.g. 2 => 'B', 29 => 'AC'",
        Mandatory = $true)]
    [int]$index
);

[string]$result = '';
if ($index -le 0 ) {
    return $result;
}

while ($index -gt 0) {
    [int]$modulo = ($index - 1) % 26;
    $character = [char]($modulo + [int][char]'A');
    $result = $character + $result;
    [int]$index = ($index - $modulo) / 26;
}

return $result;

}

0
user1098928

VB.Net 2005でこれを使う:

Private Function ColumnName(ByVal ColumnIndex As Integer) As String

   Dim Name As String = ""

   Name = (New Microsoft.Office.Interop.Owc11.Spreadsheet).Columns.Item(ColumnIndex).Address(False, False, Microsoft.Office.Interop.Owc11.XlReferenceStyle.xlA1)
   Name = Split(Name, ":")(0)

   Return Name

End Function
0
user121385

以前の答えのほとんどは正しいです。列番号をExcelの列に変換するもう1つの方法があります。これを基本変換と考えれば、解決策はかなり簡単です。 26文字しかないので、単純に列番号を26を基数に変換してください。これを行う方法は次のとおりです。

ステップ数:

  • 列を商として設定する

  • 97がaで、 ascii table になる必要があるため、(前のステップの)商変数から1を引いてください。

  • 26で割って余りを求めます。

  • +97を剰余に追加してcharに変換する(97はASCIIテーブルの "a"であるため)
  • 商が新しい商/ 26になります(26列を超える可能性があるため)
  • 商が0より大きくなるまでこれを続け、そして結果を返す

これはこれを行うコードです:)

def convert_num_to_column(column_num):
    result = ""
    quotient = column_num
    remainder = 0
    while (quotient >0):
        quotient = quotient -1
        remainder = quotient%26
        result = chr(int(remainder)+97)+result
        quotient = int(quotient/26)
    return result

print("--",convert_num_to_column(1).upper())
0
grepit
public static string ConvertToAlphaColumnReferenceFromInteger(int columnReference)
    {
        int baseValue = ((int)('A')) - 1 ;
        string lsReturn = String.Empty; 

        if (columnReference > 26) 
        {
            lsReturn = ConvertToAlphaColumnReferenceFromInteger(Convert.ToInt32(Convert.ToDouble(columnReference / 26).ToString().Split('.')[0]));
        } 

        return lsReturn + Convert.ToChar(baseValue + (columnReference % 26));            
    }
0
Daniel

ここに答えてくれてありがとう!私がElixir/Phoenixで作業しているGoogle Sheets APIとの対話のためのこれらのヘルパー関数を思いつく手助け

これが私が思いついたものです(おそらく追加の検証とエラー処理を使うことができるでしょう)。

エリクシルでは:

def number_to_column(number) do
  cond do
    (number > 0 && number <= 26) ->
      to_string([(number + 64)])
    (number > 26) ->
      div_col = number_to_column(div(number - 1, 26))
      remainder = rem(number, 26)
      rem_col = cond do
        (remainder == 0) ->
          number_to_column(26)
        true ->
          number_to_column(remainder)
      end
      div_col <> rem_col
    true ->
      ""
  end
end

そして逆関数:

def column_to_number(column) do
  column
    |> to_charlist
    |> Enum.reverse
    |> Enum.with_index
    |> Enum.reduce(0, fn({char, idx}, acc) ->
      ((char - 64) * :math.pow(26,idx)) + acc
    end)
    |> round
end

そしていくつかのテスト:

describe "test Excel functions" do
  @excelTestData [{"A", 1}, {"Z",26}, {"AA", 27}, {"AB", 28}, {"AZ", 52},{"BA", 53}, {"AAA", 703}]

  test "column to number" do
    Enum.each(@excelTestData, fn({input, expected_result}) ->
      actual_result = BulkOnboardingController.column_to_number(input)
      assert actual_result == expected_result
    end)
  end

  test "number to column" do
    Enum.each(@excelTestData, fn({expected_result, input}) ->
      actual_result = BulkOnboardingController.number_to_column(input)
      assert actual_result == expected_result
    end)
  end
end
0
phlare

Pythonでこれを行う方法は次のとおりです。そのアルゴリズムを以下に説明します。

alph = ('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')
def labelrec(n, res):
    if n<26:
        return alph[n]+res
    else:
        rem = n%26
        res = alph[rem]+res
        n = n/26-1
        return labelrec(n, res)

関数labelrecは、数字と空の文字列を使って呼び出すことができます。

print labelrec(16383, '')

これが機能する理由は次のとおりです。10進数がExcelシートの列と同じ方法で書かれている場合、数字0-9は通常どおりに書かれますが、10は '00'となり、20は '10'となります。少数の数をマッピングする:

0 - 0

9 - 9

10 - 00

20 - 10

100〜90

110 - 000

1110 - 0000

だから、パターンは明らかです。単位の位置から始めて、数字が10より小さい場合、それは数字そのものと同じです。それ以外の場合は、残りの数字を1減算して再帰する必要があります。数が10未満になったら停止できます。

上記の解決策では、基数26の数に同じ論理が適用されます。

P.S数字を1から始めたい場合は、1を減らした後にinput numberに対して同じ関数を呼び出します。

0
lambdapilgrim

セルをプログラムで参照したい場合は、シートのCellsメソッドを使用すれば、もっと読みやすいコードになります。従来のセル参照ではなく、行と列のインデックスを取ります。これはオフセット法とよく似ています。

0
pipTheGeek

(質問がC#に関連していることがわかりました。ただし、Javaを使って同じことを行う必要がある場合は、次のようにしてください。)

これは Jakarta POI の "CellReference"クラスを使って簡単にできることがわかりました。また、変換は両方の方法で行うことができます。

// Convert row and column numbers (0-based) to an Excel cell reference
CellReference numbers = new CellReference(3, 28);
System.out.println(numbers.formatAsString());

// Convert an Excel cell reference back into digits
CellReference reference = new CellReference("AC4");
System.out.println(reference.getRow() + ", " + reference.getCol());
0
Ian

それぞれのF#バージョン

let rec getExcelColumnName x  = if x<26 then int 'A'+x|>char|>string else (x/26-1|>c)+ c(x%26)

最小化を許して、 https://stackoverflow.com/a/4500043/5788 のより良いバージョンに取り組んでいました


// return values start at 0
let getIndexFromExcelColumnName (x:string) =
    let a = int 'A'
    let fPow len i =
        Math.Pow(26., len - 1 - i |> float)
        |> int

    let getValue len i c = 
        int c - a + 1 * fPow len i
    let f i = getValue x.Length i x.[i]
    [0 .. x.Length - 1]
    |> Seq.map f
    |> Seq.sum
    |> fun x -> x - 1
0
Maslow

私はVB.NET 2003でこれを使っています、そしてそれはうまく働きます...

Private Function GetExcelColumnName(ByVal aiColNumber As Integer) As String
    Dim BaseValue As Integer = Convert.ToInt32(("A").Chars(0)) - 1
    Dim lsReturn As String = String.Empty

    If (aiColNumber > 26) Then
        lsReturn = GetExcelColumnName(Convert.ToInt32((Format(aiColNumber / 26, "0.0").Split("."))(0)))
    End If

    GetExcelColumnName = lsReturn + Convert.ToChar(BaseValue + (aiColNumber Mod 26))
End Function
0
Manuel

Objective-Cの実装

-(NSString*)getColumnName:(int)n {
     NSString *name = @"";
     while (n>0) {
     n--;
     char c = (char)('A' + n%26);
     name = [NSString stringWithFormat:@"%c%@",c,name];
     n = n/26;
  }    
     return name;

}

迅速な実装

func getColumnName(n:Int)->String{
 var columnName = ""
 var index = n
 while index>0 {
     index--
     let char = Character(UnicodeScalar(65 + index%26))
     columnName = "\(char)\(columnName)"
     index = index / 26
 }
 return columnName

}

答えはに基づいています。 https://stackoverflow.com/a/4532562/2231118

0
bpolat