Aby to zrobić, należy wyliczyć każdy obszar w zakresie, a następnie wyliczyć wiersze w każdym obszarze. Nieco mylące, właściwość Excel.Range.Rows zwraca zbiór zakresów (każdy reprezentuje wiersz), podczas gdy właściwość Excel.Range.Row zwraca numer wiersza lewej górnej komórki w zakresie.
Dlatego, aby uzyskać numery wierszy, należy wyliczyć kolekcje Obszary i rzędy, a następnie uzyskać dostęp do Range.Row. Na przykład:
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());
}
Możesz nawet użyć Linq, jeśli chcesz.
Korzystanie Składnia zapytania:
IEnumerable<int> rowNumbers =
from area in range.Areas.Cast<Excel.Range>()
from row in area.Rows.Cast<Excel.Range>()
select row.Row;
Korzystanie Metoda Składnia:
IEnumerable<int> rowNumbers =
range.Areas.Cast<Excel.Range>()
.SelectMany(area => area.Rows.Cast<Excel.Range>()
.Select(row => row.Row));
Update: Jak Powrót różne numery rzędu:
Aby powrócić odrębne numery wierszy (co może wystąpić, gdy wybrany jest zakres wielu obszarów, w którym obszary nie obejmują całych rzędów).
(1) Najprostszym sposobem jest użycie Linq i skorzystanie z operatora Distinct. Na przykład:
Korzystanie Składnia zapytania:
IEnumerable<int> distinctRowNumbers =
(from area in range.Areas.Cast<Excel.Range>()
from row in area.Rows.Cast<Excel.Range>()
select row.Row)
.Distinct();
stosując metodę Składnia:
IEnumerable<int> distinctRowNumbers =
range.Areas.Cast<Excel.Range>()
.SelectMany(area => area.Rows.Cast<Excel.Range>()
.Select(row => row.Row))
.Distinct();
(2) Jeżeli nie wykorzystując Linq, a następnie można użyć HashSet. Na przykład:
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) Być może najbardziej intuicyjne podejście jest zamienić oryginalny asortyment do całych wierszy, a potem iteracyjne wierszy. W tym przypadku wiersze są już gwarantowane jako unikatowe, więc nie musimy używać operatora HashSet ani operatora Distinct.
W tych przykładów należy zwrócić uwagę na stosowanie Excel.Range.EntireRow, który jest stosowany do pierwotnego zakresu przed wyliczanie powierzchni i rzędach
wylicza bez 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 w składni zapytania:
IEnumerable<int> distinctRowNumbers =
from area in range.EntireRow.Areas.Cast<Excel.Range>()
from row in area.Rows.Cast<Excel.Range>()
select row.Row;
Linq stosując metodę Składnia
IEnumerable<int> distinctRowNumbers =
range.EntireRow.Areas.Cast<Excel.Range>()
.SelectMany(area => area.Rows.Cast<Excel.Range>()
.Select(row => row.Row));
Zauważ, że Range.EntireRow May Return Incorrect Result, ale jeśli rozumiem to poprawnie, dotyczy to tylko Excel '95 i poniżej, co jest całkowicie przestarzałe. (Nie martwiłbym się żadną wersją Excela poniżej Excela 97). Jeśli jednak obawiasz się problemów związanych z wersjami i nie masz luksusu testowania we wszystkich wersjach Excela, możesz chcieć trzymać się za pomocą HashSet lub użyj Linq razem z operatorem Distinct, aby upewnić się, że numery wierszy są unikalne.
Mam nadzieję, że to pomoże!
Mike
Proponuję dodać dodatkowy test, aby uniknąć duplikatów wpisów w wierszach. –
Dobra uwaga, Doc Brown! Teraz dodane powyżej ... :-) –
Mike, to było fantastyczne! Dziękuję bardzo!!! –