列挙子の使用方法と場所
列挙子は、コンテナやコレクションをトラバースする能力を提供するオブジェクトです。列挙子はコレクション内のデータを読むために使用できますが、基礎となるコレクションを変更することはできません。一方、IEnumerableは、GetEnumeratorメソッドを定義するインターフェースであり、これにより読み取り専用アクセスが可能なICollectionインターフェースが返されます。
Aspose.CellsのAPIはたくさんの列挙子を提供していますが、この記事では主に以下にリストされている3つのタイプについて説明しています。
- セル列挙子
- 行列挙子
- 列列挙子
列挙子の使用方法
セル列挙子
セル列挙子へのアクセス方法にはさまざまな方法があり、アプリケーションの要件に基づいてこれらのメソッドのいずれかを使用できます。セル列挙子を返すメソッドは次のとおりです。
上記のすべての方法は、初期化されたセルコレクションをトラバースする列挙子を返します。
以下のコード例は、CellsコレクションのIEnumeratorインターフェースの実装を示しています。
// For complete examples and data files, please go to https://github.com/aspose-cells/Aspose.Cells-for-.NET | |
// The path to the documents directory. | |
string dataDir = RunExamples.GetDataDir(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | |
// Load a file in an instance of Workbook | |
var book = new Workbook(dataDir + "sample.xlsx"); | |
// Get the enumerator from Cells collection | |
IEnumerator cellEnumerator = book.Worksheets[0].Cells.GetEnumerator(); | |
// Traverse cells in the collection | |
while (cellEnumerator.MoveNext()) | |
{ | |
var cell = cellEnumerator.Current as Aspose.Cells.Cell; | |
Console.WriteLine(cell.Name + " " + cell.Value); | |
} | |
// Get enumerator from an object of Row | |
IEnumerator rowEnumerator = book.Worksheets[0].Cells.Rows[0].GetEnumerator(); | |
// Traverse cells in the given row | |
while (rowEnumerator.MoveNext()) | |
{ | |
var cell = rowEnumerator.Current as Aspose.Cells.Cell; | |
Console.WriteLine(cell.Name + " " + cell.Value); | |
} | |
// Get enumerator from an object of Range | |
IEnumerator rangeEnumerator = book.Worksheets[0].Cells.CreateRange("A1:B10").GetEnumerator(); | |
// Traverse cells in the range | |
while (rangeEnumerator.MoveNext()) | |
{ | |
var cell = rangeEnumerator.Current as Aspose.Cells.Cell; | |
Console.WriteLine(cell.Name + " " + cell.Value); | |
} |
行列挙子
RowCollection.GetEnumeratorメソッドを使用しながら行列挙子にアクセスできます。次のコード例は、RowCollectionのIEnumeratorインターフェースの実装を示しています。
// For complete examples and data files, please go to https://github.com/aspose-cells/Aspose.Cells-for-.NET | |
// Load a file in an instance of Workbook | |
var book = new Workbook(dataDir + "sample.xlsx"); | |
// Get the enumerator for RowCollection | |
IEnumerator rowsEnumerator = book.Worksheets[0].Cells.Rows.GetEnumerator(); | |
// Traverse rows in the collection | |
while (rowsEnumerator.MoveNext()) | |
{ | |
var row = rowsEnumerator.Current as Aspose.Cells.Row; | |
Console.WriteLine(row.Index); | |
} |
列列挙子
列の列挙子は、ColumnCollection.GetEnumeratorメソッドを使用している間にアクセスできます。次のコード例では、ColumnCollectionのIEnumeratorインターフェイスの実装を示します。
// For complete examples and data files, please go to https://github.com/aspose-cells/Aspose.Cells-for-.NET | |
// Load a file in an instance of Workbook | |
var book = new Workbook(dataDir + "sample.xlsx"); | |
// Get the enumerator for ColumnsCollection | |
IEnumerator colsEnumerator = book.Worksheets[0].Cells.Columns.GetEnumerator(); | |
// Traverse columns in the collection | |
while (colsEnumerator.MoveNext()) | |
{ | |
var col = colsEnumerator.Current as Aspose.Cells.Column; | |
Console.WriteLine(col.Index); | |
} |
列挙子の使用場所
列挙子の利点を議論するために、実際の例を使って説明しましょう。
シナリオ
アプリケーションの要件は、与えられたWorksheet内のすべてのセルを走査してその値を読み取ることです。この目標を実装するための方法はいくつかあります。いくつかを以下で示します。
表示範囲を使用する
// For complete examples and data files, please go to https://github.com/aspose-cells/Aspose.Cells-for-.NET | |
// Load a file in an instance of Workbook | |
var book = new Workbook(dataDir + "sample.xlsx"); | |
// Get Cells collection of first worksheet | |
var cells = book.Worksheets[0].Cells; | |
// Get the MaxDisplayRange | |
var displayRange = cells.MaxDisplayRange; | |
// Loop over all cells in the MaxDisplayRange | |
for (int row = displayRange.FirstRow; row < displayRange.RowCount; row++) | |
{ | |
for (int col = displayRange.FirstColumn; col < displayRange.ColumnCount; col++) | |
{ | |
// Read the Cell value | |
Console.WriteLine(displayRange[row, col].StringValue); | |
} | |
} |
MaxDataRowおよびMaxDataColumnを使用する
// For complete examples and data files, please go to https://github.com/aspose-cells/Aspose.Cells-for-.NET | |
// Load a file in an instance of Workbook | |
var book = new Workbook(dataDir + "sample.xlsx"); | |
// Get Cells collection of first worksheet | |
var cells2 = book.Worksheets[0].Cells; | |
int maxDataRow = cells2.MaxDataRow; | |
int maxDataColumn = cells2.MaxDataColumn; | |
// Loop over all cells | |
for (int row = 0; row <= maxDataRow; row++) | |
{ | |
for (int col = 0; col <= maxDataColumn; col++) | |
{ | |
// Read the Cell value | |
var currentCell = cells2.CheckCell(row, col); | |
if (currentCell != null) | |
{ | |
Console.WriteLine(currentCell.StringValue); | |
} | |
} | |
} |
上記のアプローチのそれぞれがほとんど同じロジックを使用していることがわかります。つまり、コレクション内のすべてのセルをループしてセルの値を読み取ります。これにはいくつかの理由で問題が生じる可能性があります。
- MaxRow、MaxDataRow、MaxColumn、およびMaxDataColumn などのAPIは、対応する統計情報を収集するための追加時間を必要とします。データ行列(行×列)が大きい場合、これらのAPIを使用するとパフォーマンスにペナルティが課される場合があります。
- ほとんどの場合、指定された範囲内のすべてのセルがインスタンス化されていません。そのような状況では、行列内のすべてのセルを確認することは、初期化されたセルのみを確認する場合と比べて効率的ではありません。
- Cells row、columnとしてセルにアクセスすることは、範囲内のすべてのセルオブジェクトをインスタンス化することになり、最終的にOutOfMemoryExceptionを引き起こす可能性があります。
結論
上記の事実に基づいて、列挙子を使用すべき可能なシナリオが以下に示されています。
- セルコレクションの読み取り専用アクセスが必要な場合、つまり、セルの確認のみが必要な場合。
- 多数のセルを走査する必要がある場合。
- 初期化されたセル/行/列のみを走査する必要がある場合。