Для этого вам нужно перечислить каждую область в диапазоне, а затем перечислить строки в каждой области. Несколько странно, что свойство Excel.Range.Rows возвращает коллекцию диапазонов (каждый из которых представляет строку), а свойство Excel.Range.Row возвращает номер строки верхнего левая ячейка в диапазоне.
Поэтому, чтобы получить номера строк, вы должны перечислить коллекции областей и рядов, а затем получить доступ к 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) Возможно, самый интуитивный подход - сначала преобразовать исходный диапазон во все строки, а затем выполнить итерацию строк. В этом случае строки уже гарантированно будут уникальными, поэтому нам не нужно использовать оператор 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 ниже Excel '97.) Если, однако, вас беспокоят какие-либо проблемы с версиями, и вы не можете позволить себе роскошь тестирования во всех версиях Excel, вы можете использовать HashSet. или используйте Linq вместе с оператором Distinct, чтобы обеспечить уникальность номеров строк.
Надеюсь, это поможет!
Mike