web-dev-qa-db-ja.com

行のExcel範囲を取得する最速の方法

VSTO C#プロジェクトで、一連の行インデックスから一連の行を取得します。

行インデックスは、たとえば「7,8,9,12,14」のようにすることができます。

次に、範囲「7:9、12、14」の行が必要です。

私は今これを行います:

Range rng1 = sheet.get_Range("A7:A9,A12,A14", Type.Missing);
rng1  = rng1.EntireRow;

しかし、範囲指定での文字列処理のため、少し非効率的です。

sheet.Rows["7:9"]

動作しますが、これを与えることはできません

sheet.Rows["7:9,12,14"] // Fails
8

これを試して:

Sheet.Range("7:9,12:12,14:14")

編集:C#でVSTOを使用している場合は申し訳ありませんが、

sheet.get_Range("7:9,12:12,14:14", Type.Missing)
13
Reafidy

ここにあなたが探しているコードがあります:

int startRow, endRow, startCol, endCol, row,col;
var singleData = new object[col];
var data = new object[row,col];
//For populating only a single row with 'n' no. of columns.
var startCell = (Range)worksheet.Cells[startRow, startCol];
startCell.Value2 = singleData;
//For 2d data, with 'n' no. of rows and columns.
var endCell = (Range)worksheet.Cells[endRow, endCol];
var writeRange = worksheet.Range[startCell, endCell];
writeRange.Value2 = data;

セルの1次元配列または2次元配列のいずれでも、範囲全体を使用できます。

この方法は、Excelシート全体をループし、必要なときに必要な場所にデータを入力するときに特に役立ちます。

6
SutharMonil

私はC#の専門家ではありませんが、上記のようにEntireRowを使用する必要があります。あなたが探している文字列は.Addressプロパティ。例えば

    private void button1_Click(object sender, EventArgs e)
    {
        Microsoft.Office.Interop.Excel.Application xlexcel;
        Microsoft.Office.Interop.Excel.Workbook xlWorkBook;
        Microsoft.Office.Interop.Excel.Worksheet xlWorkSheet;
        Microsoft.Office.Interop.Excel.Range xlRange;

        object misValue = System.Reflection.Missing.Value;
        xlexcel = new Excel.Application();

        xlWorkBook = xlexcel.Workbooks.Add();

        // Set Sheet 1 as the sheet you want to work with
        xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);

        xlRange = xlWorkSheet.get_Range("A7:A9,A12,A14", misValue);

        MessageBox.Show(xlRange.EntireRow.Address);

        xlRange = xlWorkSheet.get_Range(xlRange.EntireRow.Address, misValue);

        MessageBox.Show(xlRange.Address);
    }

したがって、上記のように書くことができます

    private void button1_Click(object sender, EventArgs e)
    {
        Microsoft.Office.Interop.Excel.Application xlexcel;
        Microsoft.Office.Interop.Excel.Workbook xlWorkBook;
        Microsoft.Office.Interop.Excel.Worksheet xlWorkSheet;
        Microsoft.Office.Interop.Excel.Range xlRange;

        object misValue = System.Reflection.Missing.Value;
        xlexcel = new Excel.Application();

        xlWorkBook = xlexcel.Workbooks.Add();

        // Set Sheet 1 as the sheet you want to work with
        xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);

        xlRange = xlWorkSheet.get_Range("$7:$9,$12:$12,$14:$14", misValue);

        MessageBox.Show(xlRange.Address);
    }

部分を見る

    xlRange = xlWorkSheet.get_Range("$7:$9,$12:$12,$14:$14", misValue);
2
Siddharth Rout

Reafidyの編集された回答は素晴らしいスタートです ですが、コメントで行うよりもさらに詳しく説明したいと思いました。 sheet.get_Range(rangeselect)は行ごとに移動するよりもはるかに高速ですが、まだ言及していないことの1つは、get_Rangeパラメータに255文字の制限があることです

この制限を回避するには、通常どおり「8:8,10:13,14:55」のような範囲のセットを作成してから、このコードのバリアントを使用します。

string rangeSelectPart;
while (rangeSelect.Length >= 255)
{
    rangeSelectPart = rangeSelect.Substring(0, rangeSelect.Substring(0,255).LastIndexOf(','));
    Range multiRangePart = sheet.get_Range(rangeSelectPart, Type.Missing);

    //do something with the range here using multiRangePart 

    rangeSelect= rangeSelect.Substring(rangeSelectPart.Length + 1);
}
Range multiRange = sheet.get_Range(rangeSelect, Type.Missing);
// do the same something with the last part of the range using multiRange 
// now that the remaining rows are described in less than 255 characters

これは、個々の行で操作を実行するよりも大幅に高速になりますが、連続しない大きな行セットが表示されても失敗しません。


SutharMonilの答えの方がはるかに高速です 隣接する長方形の範囲のIFF設定値。 C#からExcelへのボトルネックは通常、作成および更新中にブロックされるCOMオブジェクトを介した繰り返し呼び出しであり、彼の答えは呼び出しをうまく統合します。

残念ながら、これまでのテストでは、これを使用して文字列型ではない非文字列プロパティを操作しようとすると、型エラーが発生しました。例えば:

object[,] colors;
//use C# to set appropriate colors to each location in array...
for(int i = 0; i < colors.get_Length(0); i++){
    for(int j = 0; j < colors.get_Length(1); j++){
        colors[i,j] = XlThemeColor.xlThemeColorAccent6;
    }
}

//below causes a type error
formatRange.Interior.ThemeColor = color;

動作するようになったら、更新を忘れないようにします。


最後に、繰り返される操作のセットGlobals.ThisAddIn.Application.ScreenUpdating = false;し、完了したらtrueに設定します。これがないと、範囲プロパティの各セットが更新された後にExcelが画面の更新を停止し、操作に多くの時間を追加する可能性があります。

1
TheAtomicOption

このコードは、基準に基づいて範囲セルに色を割り当てます。

using Microsoft.Office.Interop.Excel;

(...)

var Excel = new Application { Visible = true };
Workbook workbook = Excel.Workbooks.Add(XlSheetType.xlWorksheet);
Worksheet sheet = workbook.Sheets[1];


var i = 2;
foreach (Data d in this.Datos)
{
    sheet.Cells[i, 1].Value = d.Fecha;
    sheet.Cells[i, 2].Value = d.Ubicacion;
    sheet.Cells[i, 3].Value = d.Lote;
    sheet.Cells[i, 4].Value = d.ArticuloId;
    sheet.Cells[i, 5].Value = d.Articulo;
    sheet.Cells[i, 6].Value = d.ColorId;
    sheet.Cells[i, 7].Value = d.Color;
    sheet.Cells[i, 8].Value = d.StockOriginal;
    sheet.Cells[i, 9].Value = d.Diferencia;
    sheet.Cells[i, 10].Value = d.StockFinal;
    if (d.BackGroundColor == "#FFA061")
        sheet.Range[sheet.Cells[i, 1], sheet.Cells[i, 10]].Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.FromArgb(255, 160, 97));
    i++;
}
0
Ángel Ibáñez