web-dev-qa-db-fra.com

Moyen le plus rapide d'obtenir une plage de lignes Excel

Dans un projet VSTO C #, je souhaite obtenir une plage de lignes à partir d'un ensemble d'index de lignes.

Les index de lignes peuvent par exemple ressembler à "7,8,9,12,14".

Ensuite, je veux la plage "7: 9,12,14" lignes.

Je fais maintenant ceci:

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

Mais c'est un peu inefficace en raison de la gestion des chaînes dans la spécification de plage.

sheet.Rows["7:9"]

fonctionne mais je ne peux pas donner ceci

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

Essaye ça:

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

EDIT: Désolé si vous utilisez VSTO en C #, cela aurait dû être:

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

Voici le code que vous recherchez:

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;

Vous pouvez avoir une plage entière, qu’il s’agisse d’un tableau de cellules à 1 ou 2 dimensions.

Cette méthode est particulièrement utile lorsque vous parcourez l'intégralité de la feuille Excel et que vous remplissez des données là où vous le souhaitez.

6
SutharMonil

Je ne suis pas un expert en C #, mais autant que je sache, vous devez utiliser EntireRow comme vous l'avez fait ci-dessus. La chaîne que vous recherchez peut être obtenue à partir de la propriété .Address. Par exemple

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

Vous pouvez donc écrire ce qui précède

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

Voir la partie

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

La réponse modifiée de Reafidy est un bon début , mais je voulais développer plus que ce que je pourrais faire dans un commentaire. sheet.get_Range(rangeselect) est beaucoup plus rapide que d'aller ligne par ligne, mais une chose que je n'ai pas encore vue mentionnée est que le paramètre get_Range a une limite de 255 caractères.

Pour contourner cette limitation, construisez normalement un ensemble de plages du type "8: 8,10: 13,14: 55", puis utilisez une variante de ce code:

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

Cela sera beaucoup plus rapide que d'effectuer des opérations sur des lignes individuelles, mais n'échouera pas non plus lorsque les ensembles de lignes non contigus sont grands. 


Notez que La réponse de SutharMonil est bien plus rapide IFF définit des valeurs dans des plages rectangulaires contiguës. Le goulot d'étranglement allant de C # à Excel réside généralement dans les appels répétés via les objets COM qui se bloquent lors de la création et de la mise à jour, et sa réponse consolide parfaitement les appels.

Malheureusement, dans mes tests jusqu'à présent, essayer de l'utiliser avec des propriétés non-chaîne qui ne sont pas de type chaîne a entraîné une erreur de type. Par exemple:

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;

Je vais essayer de me rappeler de mettre à jour si je l'obtenir au travail.


Enfin, pour les opérations répétées, définissez Globals.ThisAddIn.Application.ScreenUpdating = false;, puis définissez-le sur true lorsque vous avez terminé. Sans cela, Excel arrête de mettre à jour l'écran après chaque mise à jour de chaque ensemble de propriétés de plage, ce qui peut ajouter beaucoup de temps à l'opération.

1
TheAtomicOption

Ce code attribue une couleur aux cellules de la plage en fonction de critères:

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