スプレッドシート ドキュメントの非表示の行または列のリストを取得する
このトピックでは、ドキュメントを Excel に読み込むことなく、Open XML SDK 2.0 for Microsoft Office のクラスを使用して、Microsoft Office Excel 2007 または Microsoft Excel 2010 ワークシートの非表示の行あるいは列のリストをブログラムで取得する方法を示します。このトピックでは、この作業を説明するために GetHiddenRowsOrCols メソッドの例を使用しています。
適用対象: Excel 2010 | Office 2010 | PowerPoint 2010 | Word 2010
この記事の内容
GetHiddenRowsOrCols メソッド
GetHiddenRowsOrCols メソッドの呼び出し
コードの動作のしくみ
非表示の行または列のインデックス値のリストの取得
サンプル コード
このトピックのサンプル コードを使用するには、Open XML SDK 2.0 をインストールする必要があります。プロジェクトで次のアセンブリを明示的に参照する必要があります。
WindowsBase
DocumentFormat.OpenXml (Open XML SDK によってインストールされます)
このトピックのコードをコンパイルするには、次の using ディレクティブまたは Imports ステートメントも使用する必要があります。
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
Imports System.IO
Imports DocumentFormat.OpenXml.Packaging
Imports DocumentFormat.OpenXml.Spreadsheet
GetHiddenRowsOrCols メソッド
GetHiddenRowsOrCols メソッドを使用して、ワークシートの非表示の行または列のリストを取得できます。GetHiddenRowsOrCols メソッドは、次のことを示す 3 つのパラメーターを受け取ります。
確認するドキュメントの名前 (文字列)。
確認するシートの名前 (文字列)。
行 (true) と列 (false) のどちらを検出するか (ブール型)。
public static List<uint> GetHiddenRowsOrCols(
string fileName, string sheetName, bool detectRows)
Public Function GetHiddenRowsOrCols(
ByVal fileName As String, ByVal sheetName As String,
ByVal detectRows As Boolean) As List(Of UInteger)
GetHiddenRowsOrCols メソッドの呼び出し
指定されたワークシートに非表示の行または列 (行と列の番号は 0 ではなく 1 から始まります) が含まれている場合、メソッドは、非表示の行または列の各インデックスが含まれる符号なし整数のリストを返します。このメソッドを呼び出すには、次のコード例に示すように、パラメーター値をすべて渡します。
const string fileName = @"C:\users\public\documents\RetrieveHiddenRowsCols.xlsx";
List<uint> items = GetHiddenRowsOrCols(fileName, "Sheet1", true);
var sw = new StringWriter();
foreach (var item in items)
sw.WriteLine(item);
Console.WriteLine(sw.ToString());
Const fileName As String = "C:\Users\Public\Documents\RetrieveHiddenRowsCols.xlsx"
Dim items As List(Of UInteger) =
GetHiddenRowsOrCols(fileName, "Sheet1", True)
Dim sw As New StringWriter
For Each item In items
sw.WriteLine(item)
Next
Console.WriteLine(sw.ToString())
コードの動作のしくみ
このコードでは、まず、戻り値を格納するための変数 itemList を作成します。
List<uint> itemList = new List<uint>();
Dim itemList As New List(Of UInteger)
次に、SpreadsheetDocument.Open メソッドを使用し、(最後のパラメーター値を false に設定して) 読み取り専用でドキュメントを開きます。さらに、ドキュメントの WorkbookPart プロパティを使用して、ブック パーツへの参照を取得します。
using (SpreadsheetDocument document =
SpreadsheetDocument.Open(fileName, false))
{
WorkbookPart wbPart = document.WorkbookPart;
// Code removed here...
}
Using document As SpreadsheetDocument =
SpreadsheetDocument.Open(fileName, False)
Dim wbPart As WorkbookPart = document.WorkbookPart
' Code removed here...
End Using
非表示の行または列を検出するには、まず、対象となるシートの名前を指定してシートへの参照を取得します。これは、一般に考えるほど簡単ではありません。ブック パーツの Workbook プロパティからシートの種類の子をすべて検出し、各シートの Name プロパティを調べます。この検索では、ブックの関係を調べるだけで、ワークシート パーツを実際に検出するわけではありません。シートの名前および Id プロパティなどの情報を含む Sheet オブジェクトへの参照のみを検出します。この検索は、LINQ クエリを使用すると最も簡単に実行できます。
Sheet theSheet = wbPart.Workbook.Descendants<Sheet>().
Where((s) => s.Name == sheetName).FirstOrDefault();
if (theSheet == null)
{
throw new ArgumentException("sheetName");
}
Dim theSheet As Sheet = wbPart.Workbook.Descendants(Of Sheet)().
Where(Function(s) s.Name = sheetName).FirstOrDefault()
If theSheet Is Nothing Then
Throw New ArgumentException("sheetName")
FirstOrDefault メソッドは、最初に一致する参照 (この例ではシート) または null 参照 (一致が見つからない場合) を返します。コードは null 参照かどうかを確認し、無効なシート名が渡されている場合は、例外をスローします。シートの情報を取得したら、対応するワークシート パーツへの参照を取得します。取得したシート情報には Id プロパティがあり、その Id プロパティを使用して、WorkbookPart オブジェクトの GetPartById メソッドを呼び出すと、対応する WorksheetPart プロパティへの参照を取得できます。
else
{
// The sheet does exist.
WorksheetPart wsPart =
(WorksheetPart)(wbPart.GetPartById(theSheet.Id));
Worksheet ws = wsPart.Worksheet;
// Code removed here...
}
Else
' The sheet does exist.
Dim wsPart As WorksheetPart =
CType(wbPart.GetPartById(theSheet.Id), WorksheetPart)
Dim ws As Worksheet = wsPart.Worksheet
' Code removed here...
End If
非表示の行または列のインデックス値のリストの取得
コードでは、メソッドを呼び出したときに指定した detectRows パラメーターを使用して、行と列のどちらの情報を取得するかを判別します。
if (detectRows)
{
// Retrieve hidden rows.
// Code removed here...
}
else
{
// Retrieve hidden columns.
// Code removed here...
}
If detectRows Then
' Retrieve hidden rows.
' Code removed here...
Else
' Retrieve hidden columns.
' Code removed here...
End If
非表示の行のリストは、実際には 1 行のコードで取得できます。
itemList = ws.Descendants<Row>().
Where((r) => r.Hidden != null && r.Hidden.Value).
Select(r => r.RowIndex.Value).ToList<uint>();
itemList = ws.Descendants(Of Row).
Where(Function(r) r.Hidden IsNot Nothing AndAlso
r.Hidden.Value).
Select(Function(r) r.RowIndex.Value).ToList()
ただし、この 1 行のコードで多くの処理を実行できます。まず、ワークシートの Descendants メソッドを呼び出して、すべての行のリストを取得します。Where メソッドを使用して、その結果を、アイテムの Hidden プロパティが null ではなく、Hidden プロパティの値が True である行のみに絞り込みます。Select メソッドでは、各行の戻り値を使用して RowIndex プロパティの値を返します。最後に、ToList<TSource> メソッドで、返された IEnumerable<T> インターフェイスを符号なし整数の List<T> オブジェクトに変換します。非表示の行がない場合は、返されるリストは空になります。
非表示の列のリストの取得は、行の場合より複雑です。Excel では、非表示の列のグループは 1 つの要素にまとめられ、グループ内の先頭の列と末尾の列がそれぞれ Min プロパティと Max プロパティで示されるからです。したがって、非表示の列のリストを取得する場合、コードの冒頭は非表示の行を取得する場合と同じですが、インデックス値の反復処理が必要になります (非表示の列のコレクション内の各アイテムをループ処理し、Min 値から Max 値までの各インデックスを追加します)。
var cols = ws.Descendants<Column>().
Where((c) => c.Hidden != null && c.Hidden.Value);
foreach (Column item in cols)
{
for (uint i = item.Min.Value; i <= item.Max.Value; i++)
{
itemList.Add(i);
}
}
Dim cols = ws.Descendants(Of Column).
Where(Function(c) c.Hidden IsNot Nothing AndAlso
c.Hidden.Value)
For Each item As Column In cols
For i As UInteger = item.Min.Value To item.Max.Value
itemList.Add(i)
Next
Next
サンプル コード
以下に、C# と Visual Basic の完全な GetHiddenRowsOrCols コード サンプルを示します。
public static List<uint> GetHiddenRowsOrCols(
string fileName, string sheetName, bool detectRows)
{
// Given a workbook and a worksheet name, return
// either a list of hidden row numbers, or a list
// of hidden column numbers. If detectRows is true, return
// hidden rows. If detectRows is false, return hidden columns.
// Rows and columns are numbered starting with 1.
List<uint> itemList = new List<uint>();
using (SpreadsheetDocument document =
SpreadsheetDocument.Open(fileName, false))
{
WorkbookPart wbPart = document.WorkbookPart;
Sheet theSheet = wbPart.Workbook.Descendants<Sheet>().
Where((s) => s.Name == sheetName).FirstOrDefault();
if (theSheet == null)
{
throw new ArgumentException("sheetName");
}
else
{
// The sheet does exist.
WorksheetPart wsPart =
(WorksheetPart)(wbPart.GetPartById(theSheet.Id));
Worksheet ws = wsPart.Worksheet;
if (detectRows)
{
// Retrieve hidden rows.
itemList = ws.Descendants<Row>().
Where((r) => r.Hidden != null && r.Hidden.Value).
Select(r => r.RowIndex.Value).ToList<uint>();
}
else
{
// Retrieve hidden columns.
var cols = ws.Descendants<Column>().
Where((c) => c.Hidden != null && c.Hidden.Value);
foreach (Column item in cols)
{
for (uint i = item.Min.Value; i <= item.Max.Value; i++)
{
itemList.Add(i);
}
}
}
}
}
return itemList;
}
Public Function GetHiddenRowsOrCols(
ByVal fileName As String, ByVal sheetName As String,
ByVal detectRows As Boolean) As List(Of UInteger)
' Given a workbook and a worksheet name, return either
' a list of hidden row numbers, or a list of hidden
' column numbers. If detectRows is True, return
' hidden rows. If detectRows is False, return hidden columns.
' Rows and columns are numbered starting with 1.
Dim itemList As New List(Of UInteger)
Using document As SpreadsheetDocument =
SpreadsheetDocument.Open(fileName, False)
Dim wbPart As WorkbookPart = document.WorkbookPart
Dim theSheet As Sheet = wbPart.Workbook.Descendants(Of Sheet)().
Where(Function(s) s.Name = sheetName).FirstOrDefault()
If theSheet Is Nothing Then
Throw New ArgumentException("sheetName")
Else
' The sheet does exist.
Dim wsPart As WorksheetPart =
CType(wbPart.GetPartById(theSheet.Id), WorksheetPart)
Dim ws As Worksheet = wsPart.Worksheet
If detectRows Then
' Retrieve hidden rows.
itemList = ws.Descendants(Of Row).
Where(Function(r) r.Hidden IsNot Nothing AndAlso
r.Hidden.Value).
Select(Function(r) r.RowIndex.Value).ToList()
Else
' Retrieve hidden columns.
Dim cols = ws.Descendants(Of Column).
Where(Function(c) c.Hidden IsNot Nothing AndAlso
c.Hidden.Value)
For Each item As Column In cols
For i As UInteger = item.Min.Value To item.Max.Value
itemList.Add(i)
Next
Next
End If
End If
End Using
Return itemList
End Function