wake-up-neo.net

Schnellster Weg, um eine Excel-Reihe von Zeilen zu erhalten

In einem VSTO-C # -Projekt möchte ich einen Zeilenbereich aus einem Satz von Zeilenindizes erhalten.

Die Zeilenindizes können beispielsweise "7,8,9,12,14" sein.

Dann möchte ich den Bereich "7: 9,12,14" reihen.

Ich mache das jetzt:

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

Aufgrund der String-Verarbeitung in der Range-Spezifikation ist dies jedoch etwas ineffizient.

sheet.Rows["7:9"]

funktioniert, aber ich kann das nicht geben

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

Versuche dies:

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

BEARBEITEN: Sorry wenn VSTO in C # verwendet wurde, hätte es sein sollen:

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

Hier ist der Code, nach dem Sie suchen:

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;

Sie können den gesamten Bereich haben, sei es 1-dimensionales oder 2-dimensionales Array von Zellen.

Diese Methode ist besonders hilfreich, wenn Sie die gesamte Excel-Tabelle durchlaufen und die Daten bei Bedarf auffüllen.

6
SutharMonil

Ich bin kein Experte für C #, aber AFAIK müssen Sie die EntireRow wie oben verwenden. Die gesuchte Zeichenfolge kann über die .Address-Eigenschaft ermittelt werden. Zum Beispiel

    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);
    }

So kannst du das oben als schreiben

    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);
    }

Siehe den Teil

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

Die bearbeitete Antwort von Reafidy ist ein großartiger Anfang , aber ich wollte mehr darauf eingehen, als ich es in einem Kommentar tun könnte. sheet.get_Range(rangeselect) ist viel schneller als zeilenweise zu gehen, aber ich habe bisher noch nicht erwähnt, dass der Parameter get_Range ein Limit von 255 Zeichen hat.

Konstruieren Sie eine Reihe von Bereichen wie "8: 8,10: 13,14: 55", um diese Einschränkung zu umgehen. Verwenden Sie dann eine Variante dieses Codes:

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

Dies ist wesentlich schneller als das Durchführen von Operationen für einzelne Zeilen, schlägt jedoch auch nicht fehl, wenn große, nicht zusammenhängende Zeilengruppen angezeigt werden. 


Beachten Sie, dass die Antwort von SutharMonil viel schneller ist IFF-Einstellwerte in benachbarten rechteckigen Bereichen. Der Engpass, der von C # bis Excel geht, sind in der Regel wiederholte Aufrufe durch die COM-Objekte, die während der Erstellung und Aktualisierung blockieren, und seine Antwort konsolidiert Aufrufe.

In meinen bisherigen Tests hat der Versuch, ihn mit Nicht-String-Eigenschaften zu arbeiten, die nicht vom Typ string sind, zu einem Typfehler geführt. Zum Beispiel:

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;

Ich werde versuchen, mich an das Update zu erinnern, wenn es funktioniert.


Als letztes für wiederholte Operationen setzen Sie Globals.ThisAddIn.Application.ScreenUpdating = false; und dann auf true, wenn Sie fertig sind. Andernfalls wird der Bildschirm von Excel nicht mehr aktualisiert, nachdem alle Bereichseigenschaften aktualisiert wurden. Dies kann den Vorgang erheblich verlängern.

1
TheAtomicOption

Dieser Code weist den Zellen nach Kriterien Farbe zu:

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