0

私のアプリケーションは、Interop ライブラリを使用して Excel ファイル データを読み取っています。私のコードは以下のとおりです。

string filepath = "C:\\SAddresses.xls";

XLApp=new Excel.Application();
XLBook = XLApp.Workbooks.Open(filepath, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
XLSheet = (Excel.Worksheet)XLBook.Worksheets.get_Item(1);
cRange = XLSheet.UsedRange;


for (int rowcnt = 2; rowcnt < cRange.Rows.Count; rowcnt++)
{
    for (int colidx = 1; colidx < cRange.Columns.Count; colidx++)
    {
        colvalue+=((cRange.Cells[rowidx,colidx] as Excel.Range).Value2);
    }
}

上記では、各行インデックスと列インデックスを使用してデータを取得できますが、列インデックスの代わりに列名を使用して列データを読み取りたいです。これを行う方法.

4

2 に答える 2

0

これは、私がしばらく使用してきた ExelTable クラスからの抜粋です。

class ExcelTable
{
    public const int SignificantCharsInVariableName = 10;

    private string[] columnNames = null;
    private string[,] data = null;

    private string[] DefineColumnNames(string[,] R)
    {
        string[] names = new string[R.GetLength(1)];

        for (int i = 0; i < R.GetLength(1); i++)
        {
            names[i] = R[0, i].Trim();
        }

        return names;
    }


    public string GetValue(int row, string varName)
    {
        string s;
        int col;

        try
        {
            col = GetColumn(varName);

            s = data[row, col].Trim();
        }
        catch (Exception)
        {
            s = "???";
        }

        return s;
    }


    private int GetColumn(string name)
    {
        return GetColumn(name, this.columnNames, obligatory: true);
    }

    private int GetColumn(string name, string[] names, bool obligatory = false)
    {
        string nameStart;

        //  first try perfect match
        for (int i = 0; i < names.Length; i++)
            if (names[i].Equals(name))
                return i;

        //  2nd try to match the significant characters only
        nameStart = name.PadRight(SignificantCharsInVariableName, ' ').Substring(0, SignificantCharsInVariableName);
        for (int i = 0; i < names.Length; i++)
            if (names[i].StartsWith(nameStart))
                return i;

        if (obligatory)
        {
            throw new Exception("Undefined Excel sheet column '" + name + "'");
        }

        return -1;
    }

}

データは名前付きの列に編成されます。名前は、データ配列の一番上の行の最初のセルです。サンプル コードは、不完全な名前の一致やその他のエラー状況に対処しようとします。Dictionary<string, int>列名と列インデックスの間のマッピングを格納するなど、より巧妙なコレクションを使用できます。

私の GetColumn() 関数は、必須ではない列を許可します。GetValue() によって使用され、指定された行の値を「名前で」返します。列が見つからない場合は、疑問符が返されます。

于 2012-12-29T01:35:29.790 に答える
0

ループ内の数値を列名 (質問から読み取ったもの) に変換するだけの場合は、次の静的メソッドをすべてのスプレッドシート ルーチンで使用します。

public static string ExcelColumnNumberToName(int columnNumber)
{
    int dividend = columnNumber;
    string columnName = string.Empty;
    int modulo;

    while (dividend > 0)
    {
        // Get the remainder of a division by 26 (we take one from the dividend as column "A" is not zero, but one).

        modulo = (dividend - 1) % 26;

        // Convert the remainder (plus 65 - the ASCII decimal code for "A") to a character and add it to the beginning of the string (since column names
        // increase by adding letters to the left hand side). 

        columnName = Convert.ToChar(65 + modulo).ToString() + columnName;

        // Set the dividend for the next iteration of the loop by removing the amount we just converted and dividing it by 26 (in effect treating it like
        // a base-26 number and dropping it by an order of magnitude)

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

    return columnName;
}

セルの参照方法を少し調整する必要があります。だから代わりに

cRange.Cells[rowidx,colidx]

あなたが使うだろう

cRange.get_Range(ExcelColumnNumberToName(colidx), rowidx)

しかし、それはあなたが現在行っている方法よりも実際には何の利点もありません。私がこれを使用する理由は、レポート目的でループ カウンターを列名に変換するためです。

于 2012-12-27T18:43:52.587 に答える