2012-09-11 17 views
5

In un progetto C# di VSTO voglio ottenere un intervallo di righe da un insieme di indici di riga.Il modo più veloce per ottenere un intervallo di righe di Excel

Gli indici di riga possono essere ad esempio "7,8,9,12,14".

Quindi voglio le righe "7: 9,12,14" righe.

io ora faccio questo:

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

ma è un po 'inefficiente a causa di gestione nella specifica gamma stringa.

sheet.Rows["7:9"] 

opere, ma non posso dare a questo

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

È possibile unire i singoli intervalli, ma ciò potrebbe non essere più efficiente rispetto all'utilizzo della singola chiamata con l'indirizzo concatenato. –

risposta

9

Prova questo:

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

EDIT: Scusate se utilizzando VSTO in C# che avrebbe dovuto essere:

sheet.get_Range("7:9,12:12,14:14", Type.Missing) 
+0

Yup '.get_Range' è il modo giusto :) –

+0

La parte importante che stavo cercando di mostrare era che puoi usare i numeri di riga nel metodo intervallo e non hai bisogno di usare .entirerow. L'OP aveva già .get_range quindi immagino che spero che capisca cosa intendo. Tastiera inserita prima del cervello. ;) – Reafidy

+0

Sì, questa sembra la mia risposta, ma ci proveremo ora. –

2

Non sono un esperto in C# ma AFAIK devi usare l'Enti ripeti come hai fatto sopra. La stringa che stai cercando può essere raggiunta dalla proprietà .Address. Per esempio

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

modo da poter scrivere quanto sopra come

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

Vedere la parte

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

Ecco il codice che si sta cercando:

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; 

È può avere un'intera gamma, sia 1 dimensionale o 2 dimensionale matrice di celle.

Questo metodo è particolarmente utile durante il looping dell'intero foglio excel e dei dati di popolamento dove e quando richiesto.

0

Reafidy's edited answer is a great start, ma volevo espanderci più di quanto avrei potuto fare in un commento. sheet.get_Range(rangeselect) è molto più veloce di una riga per riga, ma una cosa che non ho ancora visto è che il parametro get_Range ha un limite di 255 caratteri.

per aggirare questa limitazione, costruire una serie di intervalli come "8: 8,10: 13,14: 55" come normale quindi utilizzare una variante di questo codice:

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 

Questa volontà essere significativamente più veloce rispetto alle operazioni su singole righe, ma anche non avrà esito negativo se presentato con grandi serie di righe non contigue.


noti che SutharMonil's answer is way faster IFF impostazione dei valori in aree rettangolari contigui. Il collo di bottiglia che va da C# a excel è di solito le chiamate ripetute attraverso gli oggetti COM che si bloccano mentre vengono creati e aggiornati, e la sua risposta consolida piacevolmente le chiamate.

Sfortunatamente nei miei test fino ad ora, provare a utilizzarlo per lavorare con proprietà non stringa che non sono di tipo stringa ha provocato un errore di tipo. Ad esempio:

Cercherò di ricordarmi di aggiornare se riesco a farlo funzionare.


Infine per operazioni ripetute set Globals.ThisAddIn.Application.ScreenUpdating = false; e quindi impostare su true quando hai finito. Senza questo, Excel si interrompe per aggiornare lo schermo dopo che ogni serie di proprietà dell'intervallo viene aggiornata e ciò può aggiungere molto tempo all'operazione.

Problemi correlati