2012-09-11 29 views
5

在VSTO C#項目中,我想從一組行索引中獲取一系列行。獲取Excel行範圍的最快方法

行索引可以例如像「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 
+0

您可以合併各個範圍,但這可能不會比使用具有連接地址的單一調用更有效。 –

回答

9

試試這個:

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

編輯:很抱歉,如果在C#中使用VSTO它應該是:

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

Yup'.get_Range'是正確的方法:) –

+0

我試圖展示的重要部分是,您可以在範圍方法中使用行號,並且不需要使用.entirerow。 OP已經有了.get_range,所以我猜希望他知道我的意思。鍵盤在大腦之前的齒輪。 ;) – Reafidy

+0

是的,這看起來像我的答案,但我現在就試一試。 –

2

我不是C#的專家,但AFAIK你必須使用Enti按照上面所做的操作重新進行。您正在尋找的字符串可以通過.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); 
5

這裏是代碼你正在尋找:

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表格並在需要時填充數據時特別有用。

0

Reafidy's edited answer is a great start,但是我想在評論中做更多的擴展。 sheet.get_Range(rangeselect)比逐行更快,但是我還沒有提到的一件事是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's answer is way faster 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將停止更新每個範圍屬性集更新後的屏幕,並且可能會爲操作增加大量時間。