我使用的是Microsoft.Office.Interop.Excel,但是我找不到一种方法来返回选定的行。我所说的“选定”是指,当您单击左侧的行间距并选择一个或多个连续或不连续的行时,行号本身(这将突出显示整个行)。这与在图纸本身上选择区域或区域不同。
到目前为止,我已经研究了app.Selection、app.Cells、app.Rows,但似乎都没有给我提供行。app.Selection给了我实际的单元格内容,这并不是我想要的。
有什么想法吗?谢谢!
发布于 2010-01-21 23:57:10
为此,您需要枚举范围中的每个区域,然后枚举每个区域中的行。有点令人困惑的是,Excel.Range.Rows属性返回一个范围集合(每个范围代表一行),而Excel.Range.Row属性返回范围中左上角单元格的行号。
因此,要获得行号,您应该枚举Area和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));
更新:如何返回 Distinct 行号:
返回不同的行号(当选择区域不包括整行的多区域范围时,可能会发生这种情况)。
(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 May Return Incorrect Result,但是,如果我理解正确的话,它只适用于Excel95和更低版本,这是完全过时的。(我不担心任何低于Excel97的版本。)但是,如果您担心任何版本控制问题,并且没有在所有Excel版本中进行测试的余地,那么您可能希望坚持使用HashSet,或者使用Linq和Distinct运算符,以确保行号是唯一的。
希望这能有所帮助!
麦克
发布于 2017-05-10 23:49:31
不需要枚举行,只需要枚举区域:
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);
发布于 2018-01-30 04:44:23
我正在搅动这个庞然大物,并在这里添加一些实际的信息:
现在我们只需使用xlApp.ActiveCell.Row
就可以了:)
https://stackoverflow.com/questions/2110327
复制相似问题