Excel:获取选定的行

我正在使用Microsoft.Office.Interop.Excel,我找不到方法来返回选定的行。 我所说的“被选中”的意思是,当你点击左边的排水沟时,行号会自己select一个或多个相邻或不相邻的行(这将突出显示整行)。这与select区域不同表格本身的区域。

到目前为止,我已经看了app.Selection,app.Cells,app.Rows,这些都没有给我行。 app.Selection给了我实际的单元格内容,这不是我想要的。

有任何想法吗? 谢谢!

为此,您需要枚举范围中的每个区域,然后枚举每个区域内的行。 有些令人困惑的是, Excel.Range.Rows属性返回一个范围集合(每个表示一行),而Excel.Range.Row属性则返回范围中左上angular单元格的行号。

因此,要获得行号,应该枚举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)); 

更新:如何返回不同的行号:

返回不同的行号(当select区域不包含整行的多区域范围时可能会发生)。

(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)也许最直观的方法是先将原始范围转换为整个行,然后迭代行。 在这种情况下,行已经保证是唯一的,所以我们不需要使用HashSet或Distinct运算符。

在这些示例中,请注意使用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可能会返回不正确的结果 ,但是,如果我正确地理解这一点,这只适用于Excel '95及以下,这是完全过时的。 (我不担心Excel 97以下的任何版本的Excel。)但是,如果您担心任何版本问题,并且没有在所有Excel版本中进行testing,那么您可能需要坚持使用HashSet ,或者与Distinct运算符一起使用Linq,以确保您的行号是唯一的。

希望这可以帮助!

麦克风

不需要枚举行,只需要区域:

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