スプレッドシート ドキュメントのセルからテキストを削除する
適用対象: Excel 2010 | Office 2010 | PowerPoint 2010 | Word 2010
この記事の内容
SpreadsheetDocument オブジェクトを取得する
SpreadsheetML ドキュメントの基本構造
サンプル コードの動作のしくみ
サンプル コード
このトピックでは、Open XML SDK 2.0 for Microsoft Office のクラスを使用して、プログラムによってスプレッドシート ドキュメントのセルからテキストを削除する方法を説明します。
このトピックのコードをコンパイルするには、次のアセンブリ ディレクティブが必要です。
using System.Collections.Generic;
using System.Linq;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
Imports System.Collections.Generic
Imports System.Linq
Imports DocumentFormat.OpenXml.Packaging
Imports DocumentFormat.OpenXml.Spreadsheet
SpreadsheetDocument オブジェクトを取得する
Open XML SDK では、SpreadsheetDocument クラスが Excel ドキュメント パッケージを表します。Excel ドキュメントを開いて操作するには、ドキュメントから SpreadsheetDocument クラスのインスタンスを作成します。ドキュメントからインスタンスを作成した後、ワークシートが入っているメインのブック パーツにアクセスできます。パッケージ内では、SpreadsheetML マークアップを使用してドキュメントのテキストを XML で表現します。
ドキュメントからクラス インスタンスを作成するには、Open() のいずれかのメソッドを呼び出します。メソッドにはいくつかの種類があり、それぞれシグネチャが異なります。このトピックのサンプル コードでは、2 つのパラメーターを必要とするシグネチャを持つ Open(String, Boolean) メソッドを使用します。最初のパラメーターには、開くドキュメントを表す完全なパスの文字列を指定します。2 番目のパラメーターは true または false で、開いたファイルを編集するかどうかを指定します。このパラメーターを false に指定した場合は、ドキュメントに対する変更が保存されません。
Open メソッドを呼び出す using ステートメントのコード例を次に示します。
// Open the document for editing.
using (SpreadsheetDocument document = SpreadsheetDocument.Open(docName, true))
{
// Other code goes here.
}
' Open the document for editing.
Using document As SpreadsheetDocument = SpreadsheetDocument.Open(docName, True)
' Other code goes here.
End Using
using ステートメントは、典型的な .Open, .Save, .Close シーケンスの代わりに使える推奨手段です。これを使用すると、対応する右かっこに達したとき、Dispose メソッド (Open XML SDK でリソースのクリーンアップに使われる内部メソッド) が自動的に呼び出されます。using ステートメントに続くブロックが、using ステートメントで作成または指定したオブジェクト (このケースでは document) のスコープとして設定されます。
SpreadsheetML ドキュメントの基本構造
SpreadsheetML ドキュメントの基本構造は、Sheets 要素と Sheet 要素で構成されます。これらの要素は、ブック内のワークシートを参照します。ワークシートごとに個別の XML ファイルが作成されます。たとえば、MySheet1 と MySheet2 という名前の 2 つのワークシートがある Workbook の SpreadsheetML は Workbook.xml ファイル内にあり、次のコード例のように記述されます。
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<workbook xmlns=https://schemas.openxmlformats.org/spreadsheetml/2006/main xmlns:r="https://schemas.openxmlformats.org/officeDocument/2006/relationships">
<sheets>
<sheet name="MySheet1" sheetId="1" r:id="rId1" />
<sheet name="MySheet2" sheetId="2" r:id="rId2" />
</sheets>
</workbook>
ワークシート XML ファイルは、1 つまたは複数のブロック レベルの要素 (SheetData など ) を持ちます。sheetData は、セルのテーブルを表し、1 つまたは複数の Row 要素を持ちます。row は、1 つまたは複数の Cell 要素を持ちます。各セルは、そのセルの値を表す CellValue 要素を持ちます。たとえば、あるブックの最初のワークシート (セル A1 の値が 100 で、それ以外の値はないものとする) の SpreadsheetML は、ファイル Sheet1.xml 内に置かれ、次のコード例のように記述されます。
<?xml version="1.0" encoding="UTF-8" ?>
<worksheet xmlns="https://schemas.openxmlformats.org/spreadsheetml/2006/main">
<sheetData>
<row r="1">
<c r="A1">
<v>100</v>
</c>
</row>
</sheetData>
</worksheet>
Open XML SDK 2.0 を使用すると、SpreadsheetML 要素に対応する厳密に型指定されたクラスを使用したドキュメント構造とコンテンツを作成できます。これらのクラスは DocumentFormat.OpenXML.Spreadsheet 名前空間にあります。次の表は、workbook、sheets、sheet、worksheet、sheetData の各要素に対応するクラスのクラス名の一覧です。
SpreadsheetML の要素 |
Open XML SDK 2.0 のクラス |
説明 |
---|---|---|
workbook |
DocumentFormat.OpenXML.Spreadsheet.Workbook |
メイン ドキュメント パーツのルート要素。 |
sheets |
DocumentFormat.OpenXML.Spreadsheet.Sheets |
ISO/IEC 29500 (英語) の仕様で規定されている、シート、ファイル バージョン、その他のブロック レベル構造のコンテナー。 |
sheet |
DocumentFormat.OpenXml.Spreadsheet.Sheet |
シート定義ファイルを指し示すシート。 |
worksheet |
DocumentFormat.OpenXML.Spreadsheet. Worksheet |
シート データが含まれているシート定義ファイル。 |
sheetData |
DocumentFormat.OpenXML.Spreadsheet.SheetData |
セル テーブル。行ごとにグループ化されています。 |
row |
DocumentFormat.OpenXml.Spreadsheet.Row |
セルの表内の行。 |
c |
DocumentFormat.OpenXml.Spreadsheet.Cell |
行内のセル。 |
v |
DocumentFormat.OpenXml.Spreadsheet.CellValue |
セルの値。 |
サンプル コードの動作のしくみ
次のコード例では、SpreadsheetDocument ドキュメント パッケージのセルからテキストを削除します。次に、スプレッドシート ドキュメント内の他のセルが、行から削除したテキストを参照しているかどうか確認し、参照していない場合は、Remove メソッドを使用して SharedStringTablePart オブジェクトからテキストを削除します。その後、RemoveSharedStringItem メソッドを呼び出して SharedStringTablePart オブジェクトをクリーンアップします。
// Given a document, a worksheet name, a column name, and a one-based row index,
// deletes the text from the cell at the specified column and row on the specified worksheet.
public static void DeleteTextFromCell(string docName, string sheetName, string colName, uint rowIndex)
{
// Open the document for editing.
using (SpreadsheetDocument document = SpreadsheetDocument.Open(docName, true))
{
IEnumerable<Sheet> sheets = document.WorkbookPart.Workbook.GetFirstChild<Sheets>().Elements<Sheet>().Where(s => s.Name == sheetName);
if (sheets.Count() == 0)
{
// The specified worksheet does not exist.
return;
}
string relationshipId = sheets.First().Id.Value;
WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(relationshipId);
// Get the cell at the specified column and row.
Cell cell = GetSpreadsheetCell(worksheetPart.Worksheet, colName, rowIndex);
if (cell == null)
{
// The specified cell does not exist.
return;
}
cell.Remove();
worksheetPart.Worksheet.Save();
}
}
' Given a document, a worksheet name, a column name, and a one-based row index,
' deletes the text from the cell at the specified column and row on the specified worksheet.
Public Shared Sub DeleteTextFromCell(ByVal docName As String, ByVal sheetName As String, ByVal colName As String, ByVal rowIndex As UInteger)
' Open the document for editing.
Using document As SpreadsheetDocument = SpreadsheetDocument.Open(docName, True)
Dim sheets As IEnumerable(Of Sheet) = document.WorkbookPart.Workbook.GetFirstChild(Of Sheets)().Elements(Of Sheet)().Where(Function(s) s.Name = sheetName)
If sheets.Count() = 0 Then
' The specified worksheet does not exist.
Return
End If
Dim relationshipId As String = sheets.First().Id.Value
Dim worksheetPart As WorksheetPart = CType(document.WorkbookPart.GetPartById(relationshipId), WorksheetPart)
' Get the cell at the specified column and row.
Dim cell As Cell = GetSpreadsheetCell(worksheetPart.Worksheet, colName, rowIndex)
If cell Is Nothing Then
' The specified cell does not exist.
Return
End If
cell.Remove()
worksheetPart.Worksheet.Save()
End Using
End Sub
次のコード例では、列名と行インデックスで指定したセルが存在するかどうかを確認します。存在する場合は、そのセルを返します。それ以外の場合は null を返します。
// Given a worksheet, a column name, and a row index, gets the cell at the specified column and row.
private static Cell GetSpreadsheetCell(Worksheet worksheet, string columnName, uint rowIndex)
{
IEnumerable<Row> rows = worksheet.GetFirstChild<SheetData>().Elements<Row>().Where(r => r.RowIndex == rowIndex);
if (rows.Count() == 0)
{
// A cell does not exist at the specified row.
return null;
}
IEnumerable<Cell> cells = rows.First().Elements<Cell>().Where(c => string.Compare(c.CellReference.Value, columnName + rowIndex, true) == 0);
if (cells.Count() == 0)
{
// A cell does not exist at the specified column, in the specified row.
return null;
}
return cells.First();
}
' Given a worksheet, a column name, and a row index, gets the cell at the specified column and row.
Private Shared Function GetSpreadsheetCell(ByVal worksheet As Worksheet, ByVal columnName As String, ByVal rowIndex As UInteger) As Cell
Dim rows As IEnumerable(Of Row) = worksheet.GetFirstChild(Of SheetData)().Elements(Of Row)().Where(Function(r) r.RowIndex = rowIndex)
If rows.Count() = 0 Then
' A cell does not exist at the specified row.
Return Nothing
End If
Dim cells As IEnumerable(Of Cell) = rows.First().Elements(Of Cell)().Where(Function(c) String.Compare(c.CellReference.Value, columnName & rowIndex, True) = 0)
If cells.Count() = 0 Then
' A cell does not exist at the specified column, in the specified row.
Return Nothing
End If
Return cells.First()
End Function
次のコード例では、スプレッドシート ドキュメント内の他のセルが、shareStringId パラメーターで指定されたテキストを参照しているかどうかを確認します。テキストを参照していない場合は、そのテキストを SharedStringTablePart オブジェクトから削除します。そのためには、削除するテキストの ID を表すパラメーターと、SpreadsheetDocument ドキュメント パッケージを表すパラメーターを渡します。その後、各 Worksheet オブジェクトを反復処理し、各 Cell オブジェクトの内容を共有文字列 ID と比較します。スプレッドシート ドキュメント内の他のセルがまだ SharedStringItem オブジェクトを参照している場合は、SharedStringTablePart オブジェクトからアイテムを削除しません。スプレッドシート ドキュメント内の他のセルがもう SharedStringItem オブジェクトを参照していない場合は、そのアイテムを SharedStringTablePart オブジェクトから削除します。その後、各 Worksheet オブジェクトおよび Cell オブジェクトを反復処理し、共有文字列の参照を更新します。最後に、ワークシートと SharedStringTable オブジェクトを保存します。
// Given a shared string ID and a SpreadsheetDocument, verifies that other cells in the document no longer
// reference the specified SharedStringItem and removes the item.
private static void RemoveSharedStringItem(int shareStringId, SpreadsheetDocument document)
{
bool remove = true;
foreach (var part in document.WorkbookPart.GetPartsOfType<WorksheetPart>())
{
Worksheet worksheet = part.Worksheet;
foreach (var cell in worksheet.GetFirstChild<SheetData>().Descendants<Cell>())
{
// Verify if other cells in the document reference the item.
if (cell.DataType != null &&
cell.DataType.Value == CellValues.SharedString &&
cell.CellValue.Text == shareStringId.ToString())
{
// Other cells in the document still reference the item. Do not remove the item.
remove = false;
break;
}
}
if (!remove)
{
break;
}
}
// Other cells in the document do not reference the item. Remove the item.
if (remove)
{
SharedStringTablePart shareStringTablePart = document.WorkbookPart.SharedStringTablePart;
if (shareStringTablePart == null)
{
return;
}
SharedStringItem item = shareStringTablePart.SharedStringTable.Elements<SharedStringItem>().ElementAt(shareStringId);
if (item != null)
{
item.Remove();
// Refresh all the shared string references.
foreach (var part in document.WorkbookPart.GetPartsOfType<WorksheetPart>())
{
Worksheet worksheet = part.Worksheet;
foreach (var cell in worksheet.GetFirstChild<SheetData>().Descendants<Cell>())
{
if (cell.DataType != null &&
cell.DataType.Value == CellValues.SharedString)
{
int itemIndex = int.Parse(cell.CellValue.Text);
if (itemIndex > shareStringId)
{
cell.CellValue.Text = (itemIndex - 1).ToString();
}
}
}
worksheet.Save();
}
document.WorkbookPart.SharedStringTablePart.SharedStringTable.Save();
}
}
}
' Given a shared string ID and a SpreadsheetDocument, verifies that other cells in the document no longer
' reference the specified SharedStringItem and removes the item.
Private Shared Sub RemoveSharedStringItem(ByVal shareStringId As Integer, ByVal document As SpreadsheetDocument)
Dim remove As Boolean = True
For Each part In document.WorkbookPart.GetPartsOfType(Of WorksheetPart)()
Dim worksheet As Worksheet = part.Worksheet
For Each cell In worksheet.GetFirstChild(Of SheetData)().Descendants(Of Cell)()
' Verify if other cells in the document reference the item.
If cell.DataType IsNot Nothing AndAlso cell.DataType.Value = CellValues.SharedString AndAlso cell.CellValue.Text = shareStringId.ToString() Then
' Other cells in the document still reference the item. Do not remove the item.
remove = False
Exit For
End If
Next cell
If Not remove Then
Exit For
End If
Next part
' Other cells in the document do not reference the item. Remove the item.
If remove Then
Dim shareStringTablePart As SharedStringTablePart = document.WorkbookPart.SharedStringTablePart
If shareStringTablePart Is Nothing Then
Return
End If
Dim item As SharedStringItem = shareStringTablePart.SharedStringTable.Elements(Of SharedStringItem)().ElementAt(shareStringId)
If item IsNot Nothing Then
item.Remove()
' Refresh all the shared string references.
For Each part In document.WorkbookPart.GetPartsOfType(Of WorksheetPart)()
Dim worksheet As Worksheet = part.Worksheet
For Each cell In worksheet.GetFirstChild(Of SheetData)().Descendants(Of Cell)()
If cell.DataType IsNot Nothing AndAlso cell.DataType.Value = CellValues.SharedString Then
Dim itemIndex As Integer = Integer.Parse(cell.CellValue.Text)
If itemIndex > shareStringId Then
cell.CellValue.Text = (itemIndex - 1).ToString()
End If
End If
Next cell
worksheet.Save()
Next part
document.WorkbookPart.SharedStringTablePart.SharedStringTable.Save()
End If
End If
End Sub
サンプル コード
次のコード サンプルでは、スプレッドシート ドキュメントの特定のセルからテキストを削除します。次の例で示すように、"Sheet3.xlsx" ファイルから DeleteTextFromCell メソッドを呼び出すことで、プログラムを実行できます。このとき、行 2、列 B、およびワークシートの名前を指定します。
string docName = @"C:\Users\Public\Documents\Sheet3.xlsx";
string sheetName = "Jane";
string colName = "B";
uint rowIndex = 2;
DeleteTextFromCell( docName, sheetName, colName, rowIndex);
Dim docName As String = "C:\Users\Public\Documents\Sheet3.xlsx"
Dim sheetName As String = "Jane"
Dim colName As String = "B"
Dim rowIndex As UInteger = 2
DeleteTextFromCell(docName, sheetName, colName, rowIndex)
以下は、C# および Visual Basic の完全なコード サンプルです。
// Given a document, a worksheet name, a column name, and a one-based row index,
// deletes the text from the cell at the specified column and row on the specified worksheet.
public static void DeleteTextFromCell(string docName, string sheetName, string colName, uint rowIndex)
{
// Open the document for editing.
using (SpreadsheetDocument document = SpreadsheetDocument.Open(docName, true))
{
IEnumerable<Sheet> sheets = document.WorkbookPart.Workbook.GetFirstChild<Sheets>().Elements<Sheet>().Where(s => s.Name == sheetName);
if (sheets.Count() == 0)
{
// The specified worksheet does not exist.
return;
}
string relationshipId = sheets.First().Id.Value;
WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(relationshipId);
// Get the cell at the specified column and row.
Cell cell = GetSpreadsheetCell(worksheetPart.Worksheet, colName, rowIndex);
if (cell == null)
{
// The specified cell does not exist.
return;
}
cell.Remove();
worksheetPart.Worksheet.Save();
}
}
// Given a worksheet, a column name, and a row index, gets the cell at the specified column and row.
private static Cell GetSpreadsheetCell(Worksheet worksheet, string columnName, uint rowIndex)
{
IEnumerable<Row> rows = worksheet.GetFirstChild<SheetData>().Elements<Row>().Where(r => r.RowIndex == rowIndex);
if (rows.Count() == 0)
{
// A cell does not exist at the specified row.
return null;
}
IEnumerable<Cell> cells = rows.First().Elements<Cell>().Where(c => string.Compare(c.CellReference.Value, columnName + rowIndex, true) == 0);
if (cells.Count() == 0)
{
// A cell does not exist at the specified column, in the specified row.
return null;
}
return cells.First();
}
// Given a shared string ID and a SpreadsheetDocument, verifies that other cells in the document no longer
// reference the specified SharedStringItem and removes the item.
private static void RemoveSharedStringItem(int shareStringId, SpreadsheetDocument document)
{
bool remove = true;
foreach (var part in document.WorkbookPart.GetPartsOfType<WorksheetPart>())
{
Worksheet worksheet = part.Worksheet;
foreach (var cell in worksheet.GetFirstChild<SheetData>().Descendants<Cell>())
{
// Verify if other cells in the document reference the item.
if (cell.DataType != null &&
cell.DataType.Value == CellValues.SharedString &&
cell.CellValue.Text == shareStringId.ToString())
{
// Other cells in the document still reference the item. Do not remove the item.
remove = false;
break;
}
}
if (!remove)
{
break;
}
}
// Other cells in the document do not reference the item. Remove the item.
if (remove)
{
SharedStringTablePart shareStringTablePart = document.WorkbookPart.SharedStringTablePart;
if (shareStringTablePart == null)
{
return;
}
SharedStringItem item = shareStringTablePart.SharedStringTable.Elements<SharedStringItem>().ElementAt(shareStringId);
if (item != null)
{
item.Remove();
// Refresh all the shared string references.
foreach (var part in document.WorkbookPart.GetPartsOfType<WorksheetPart>())
{
Worksheet worksheet = part.Worksheet;
foreach (var cell in worksheet.GetFirstChild<SheetData>().Descendants<Cell>())
{
if (cell.DataType != null &&
cell.DataType.Value == CellValues.SharedString)
{
int itemIndex = int.Parse(cell.CellValue.Text);
if (itemIndex > shareStringId)
{
cell.CellValue.Text = (itemIndex - 1).ToString();
}
}
}
worksheet.Save();
}
document.WorkbookPart.SharedStringTablePart.SharedStringTable.Save();
}
}
}
' Given a document, a worksheet name, a column name, and a one-based row index,
' deletes the text from the cell at the specified column and row on the specified sheet.
Public Sub DeleteTextFromCell(ByVal docName As String, ByVal sheetName As String, ByVal colName As String, ByVal rowIndex As UInteger)
' Open the document for editing.
Dim document As SpreadsheetDocument = SpreadsheetDocument.Open(docName, True)
Using (document)
Dim sheets As IEnumerable(Of Sheet) = document.WorkbookPart.Workbook.GetFirstChild(Of Sheets)().Elements(Of Sheet)().Where(Function(s) s.Name = sheetName.ToString())
If (sheets.Count = 0) Then
' The specified worksheet does not exist.
Return
End If
Dim relationshipId As String = sheets.First.Id.Value
Dim worksheetPart As WorksheetPart = CType(document.WorkbookPart.GetPartById(relationshipId), WorksheetPart)
' Get the cell at the specified column and row.
Dim cell As Cell = GetSpreadsheetCell(worksheetPart.Worksheet, colName, rowIndex)
If (cell Is Nothing) Then
' The specified cell does not exist.
Return
End If
cell.Remove()
worksheetPart.Worksheet.Save()
End Using
End Sub
' Given a worksheet, a column name, and a row index, gets the cell at the specified column and row.
Private Function GetSpreadsheetCell(ByVal worksheet As Worksheet, ByVal columnName As String, ByVal rowIndex As UInteger) As Cell
Dim rows As IEnumerable(Of Row) = worksheet.GetFirstChild(Of SheetData)().Elements(Of Row)().Where(Function(r) r.RowIndex = rowIndex.ToString())
If (rows.Count = 0) Then
' A cell does not exist at the specified row.
Return Nothing
End If
Dim cells As IEnumerable(Of Cell) = rows.First().Elements(Of Cell)().Where(Function(c) String.Compare(c.CellReference.Value, columnName + rowIndex.ToString(), True) = 0)
If (cells.Count = 0) Then
' A cell does not exist at the specified column, in the specified row.
Return Nothing
End If
Return cells.First
End Function
' Given a shared string ID and a SpreadsheetDocument, verifies that other cells in the document no longer
' reference the specified SharedStringItem and removes the item.
Private Sub RemoveSharedStringItem(ByVal shareStringId As Integer, ByVal document As SpreadsheetDocument)
Dim remove As Boolean = True
For Each part In document.WorkbookPart.GetPartsOfType(Of WorksheetPart)()
Dim worksheet As Worksheet = part.Worksheet
For Each cell In worksheet.GetFirstChild(Of SheetData)().Descendants(Of Cell)()
' Verify if other cells in the document reference the item.
If cell.DataType IsNot Nothing AndAlso cell.DataType.Value = CellValues.SharedString AndAlso cell.CellValue.Text = shareStringId.ToString() Then
' Other cells in the document still reference the item. Do not remove the item.
remove = False
Exit For
End If
Next
If Not remove Then
Exit For
End If
Next
' Other cells in the document do not reference the item. Remove the item.
If remove Then
Dim shareStringTablePart As SharedStringTablePart = document.WorkbookPart.SharedStringTablePart
If shareStringTablePart Is Nothing Then
Exit Sub
End If
Dim item As SharedStringItem = shareStringTablePart.SharedStringTable.Elements(Of SharedStringItem)().ElementAt(shareStringId)
If item IsNot Nothing Then
item.Remove()
' Refresh all the shared string references.
For Each part In document.WorkbookPart.GetPartsOfType(Of WorksheetPart)()
Dim worksheet As Worksheet = part.Worksheet
For Each cell In worksheet.GetFirstChild(Of SheetData)().Descendants(Of Cell)()
If cell.DataType IsNot Nothing AndAlso cell.DataType.Value = CellValues.SharedString Then
Dim itemIndex As Integer = Integer.Parse(cell.CellValue.Text)
If itemIndex > shareStringId Then
cell.CellValue.Text = (itemIndex - 1).ToString()
End If
End If
Next
worksheet.Save()
Next
document.WorkbookPart.SharedStringTablePart.SharedStringTable.Save()
End If
End If
End Sub