2010-01-21 44 views
5

我正在使用Microsoft.Office.Interop.Excel,並且找不到方法來返回選定的行。我所說的「被選中」的意思是,當你點擊左邊的排水溝並選擇一個或多個連續或不連續的行(這會突出顯示整行)時,行號本身。這與選擇區域不同或紙張本身的區域。Excel:將選定的行返回

到目前爲止,我已經看過app.Selection,app.Cells,app.Rows,並且這些都沒有給我這些行。 app.Selection給了我實際的單元格內容,這不是我想要的。

任何想法?謝謝!

回答

8

爲此,您需要枚舉範圍中的每個區域,然後枚舉每個區域內的行。有點令人困惑的是,Excel.Range.Rows屬性返回範圍的集合(每個代表一行),而Excel.Range.Row屬性返回範圍中左上角單元格的行號。

因此,要獲取行號,應該枚舉Areas和Rows集合,然後訪問Range.Row。例如:

Excel.Range range = (Excel.Range)excelApp.Selection; 

List<int> rowNumbers = new List<int>(); 

// Enumerate the Rows within each Area of the Range. 
foreach (Excel.Range area in range.Areas) 
{ 
    foreach (Excel.Range row in area.Rows) 
    { 
     rowNumbers.Add(row.Row); 
    } 
} 

// Report the results. 
foreach (int rowNumber in rowNumbers) 
{ 
    MessageBox.Show(rowNumber.ToString()); 
} 

如果您願意,您甚至可以使用Linq。

使用查詢語法:

IEnumerable<int> rowNumbers = 
    from area in range.Areas.Cast<Excel.Range>() 
    from row in area.Rows.Cast<Excel.Range>() 
    select row.Row; 

使用方法語法:

IEnumerable<int> rowNumbers = 
    range.Areas.Cast<Excel.Range>() 
    .SelectMany(area => area.Rows.Cast<Excel.Range>() 
         .Select(row => row.Row)); 

更新:如何返回鮮明行號:

要返回不同的行號(其當選擇多區域範圍的地方不包含整行時可能發生)。

(1)最簡單的方法是使用Linq並使用Distinct運算符。例如:

使用查詢語法:

IEnumerable<int> distinctRowNumbers = 
    (from area in range.Areas.Cast<Excel.Range>() 
    from row in area.Rows.Cast<Excel.Range>() 
    select row.Row) 
    .Distinct(); 

使用方法語法:

IEnumerable<int> distinctRowNumbers = 
    range.Areas.Cast<Excel.Range>() 
    .SelectMany(area => area.Rows.Cast<Excel.Range>() 
         .Select(row => row.Row)) 
    .Distinct(); 

(2)如果不是利用LINQ的,那麼你可以使用一個HashSet。例如:

Excel.Range range = (Excel.Range)excelApp.Selection; 

HashSet<int> distinctRowNumbers = new HashSet<int>(); 

// Enumerate the Rows within each Area of the Range. 
foreach (Excel.Range area in range.Areas) 
{ 
    foreach (Excel.Range row in area.Rows) 
    { 
     distinctRowNumbers.Add(row.Row); 
    } 
} 

// Report the results. 
foreach (int rowNumber in distinctRowNumbers) 
{ 
    MessageBox.Show(rowNumber.ToString()); 
} 

(3)也許是最直觀的方法就是你原來的範圍首先轉換爲整個行,然後重複的行。在這種情況下,行已經保證是唯一的,所以我們不需要使用HashSetDistinct運算符。

在這些實例中,注意使用Excel.Range.EntireRow,這是列舉的區域和行之前應用到原始範圍:

枚舉不使用LINQ:

List<int> distinctRowNumbers = new List<int>(); 

foreach (Excel.Range area in range.EntireRow.Areas) 
{ 
    foreach (Excel.Range row in area.Rows) 
    { 
     distinctRowNumbers.Add(row.Row); 
    } 
} 

LINQ的使用查詢語法:

IEnumerable<int> distinctRowNumbers = 
    from area in range.EntireRow.Areas.Cast<Excel.Range>() 
    from row in area.Rows.Cast<Excel.Range>() 
    select row.Row; 

LINQ的使用方法的語法:

IEnumerable<int> distinctRowNumbers = 
    range.EntireRow.Areas.Cast<Excel.Range>() 
    .SelectMany(area => area.Rows.Cast<Excel.Range>() 
         .Select(row => row.Row)); 

請注意, Range.EntireRow May Return Incorrect Result,但是,如果我正確理解這一點,這隻適用於Excel '95及以下,這是完全過時的。 (我不擔心Excel 97以下的任何版本的Excel。)但是,如果您擔心任何版本問題,並且沒有在所有Excel版本中進行測試的奢侈品,那麼您可能希望堅持使用HashSet ,或者與Distinct運算符一起使用Linq,以確保您的行號是唯一的。

希望這有助於!

邁克

+0

我建議你添加一個額外的測試,以避免在rowNumbers重複的條目。 – 2010-01-21 16:00:55

+0

好點,Doc布朗!現在添加上面... :-) – 2010-01-21 16:24:06

+0

邁克,那太棒了!非常感謝!!! – 2010-01-21 17:39:20

0

無需枚舉行,只是領域:

var rows = new SortedSet<int>();     // distinct and sorted 

foreach (Excel.Range a in app.Selection.Areas) 
    foreach (int r in Enumerable.Range(a.Row, a.Rows.Count)) 
     rows.Add(r); 
1

我攪拌龐大,在這裏加一點實際的信息:
現在我們可以只使用xlApp.ActiveCell.Row爲:)