我正在使用Microsoft.Office.Interop.Excel,並且找不到方法來返回選定的行。我所說的「被選中」的意思是,當你點擊左邊的排水溝並選擇一個或多個連續或不連續的行(這會突出顯示整行)時,行號本身。這與選擇區域不同或紙張本身的區域。Excel:將選定的行返回
到目前爲止,我已經看過app.Selection,app.Cells,app.Rows,並且這些都沒有給我這些行。 app.Selection給了我實際的單元格內容,這不是我想要的。
任何想法?謝謝!
我正在使用Microsoft.Office.Interop.Excel,並且找不到方法來返回選定的行。我所說的「被選中」的意思是,當你點擊左邊的排水溝並選擇一個或多個連續或不連續的行(這會突出顯示整行)時,行號本身。這與選擇區域不同或紙張本身的區域。Excel:將選定的行返回
到目前爲止,我已經看過app.Selection,app.Cells,app.Rows,並且這些都沒有給我這些行。 app.Selection給了我實際的單元格內容,這不是我想要的。
任何想法?謝謝!
爲此,您需要枚舉範圍中的每個區域,然後枚舉每個區域內的行。有點令人困惑的是,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)也許是最直觀的方法就是你原來的範圍首先轉換爲整個行,然後重複的行。在這種情況下,行已經保證是唯一的,所以我們不需要使用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,但是,如果我正確理解這一點,這隻適用於Excel '95及以下,這是完全過時的。 (我不擔心Excel 97以下的任何版本的Excel。)但是,如果您擔心任何版本問題,並且沒有在所有Excel版本中進行測試的奢侈品,那麼您可能希望堅持使用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);
我攪拌龐大,在這裏加一點實際的信息:
現在我們可以只使用xlApp.ActiveCell.Row
爲:)
我建議你添加一個額外的測試,以避免在rowNumbers重複的條目。 – 2010-01-21 16:00:55
好點,Doc布朗!現在添加上面... :-) – 2010-01-21 16:24:06
邁克,那太棒了!非常感謝!!! – 2010-01-21 17:39:20