スライドをプレゼンテーション内の新しい位置に移動する
このトピックでは、Open XML SDK for Office のクラスを使用して、プログラムを使用してプレゼンテーション内の新しい位置にスライドを移動する方法について説明します。
Presentation オブジェクトの取得
Open XML SDK では、 PresentationDocument クラスはプレゼンテーション ドキュメント パッケージを表します。 プレゼンテーション ドキュメントを操作するには、まず PresentationDocument
クラスのインスタンスを作成してから、そのインスタンスを操作します。 ドキュメントからクラス インスタンスを作成するには、ファイル パスを使用する Open メソッドを呼び出し、2 番目のパラメーターとしてブール値を使用してドキュメントを編集可能にするかどうかを指定します。 プレゼンテーション内のスライド数をカウントするためには、不用意な書き込みを避けるためにファイルを読み取り専用のアクセス権で開くのが最善です。 これを行うには、次のusing
ステートメントに示すように、Boolean パラメーターにfalse
値を指定します。 このコードでは、 presentationFile
パラメーターは、ドキュメントを開くファイルのパスを表す文字列です。
{
// Open the presentation as read-only.
using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, false))
v3.0.0 以降では、using ステートメントに依存することを優先して、Close() メソッドが削除されました。
これにより、閉じかっこに達したときに、 Dispose() メソッドが自動的に呼び出されます。
using
ステートメントに続くブロックは、using
ステートメントで作成または名前付けされたオブジェクトのスコープを確立します(この場合はpresentationDocument
。
プレゼンテーション ドキュメントの基本構造
PresentationML
ドキュメントの基本的なドキュメント構造は、多数のパーツで構成され、その中にはプレゼンテーション定義を含むメインパーツがあります。
ISO/IEC 29500 仕様の次のテキストでは、PresentationML
パッケージの全体的な形式について説明します。
PresentationML
パッケージのメイン部分は、プレゼンテーション ルート要素で始まります。 この要素にはプレゼンテーションが含まれており、プレゼンテーションは スライド リスト、スライド マスター リスト、ノート マスター リスト、配布資料マスター リストを参照します。 スライド リストはプレゼンテーション内のすべてのスライドを参照します。スライド マスター リストはプレゼンテーションで使用されるスライド マスター全体を参照します。ノート マスターにはノート ページの書式設定に関する情報が含まれます。配布資料マスターは配布資料がどのように表示されるかを示します。配布資料とは、聴衆に提供できるように一連のスライドを印刷したものです。
テキストやグラフィックのように、各スライドにはコメントとノートを含めることができ、レイアウトを指定したり、1 つ以上のカスタム プレゼンテーションに組み込んだりできます。 コメントは、プレゼンテーション スライド デッキをメンテナンスする人向けの注釈です。 ノートは、プレゼンテーションの発表者または参加者向けのリマインダーやメモです。
PresentationML
ドキュメントには、アニメーション、オーディオ、ビデオ、スライド間の切り替えなどのその他の機能があります。
PresentationML
ドキュメントは、1 つのパーツに 1 つの大きな本文として格納されません。 その代わりに、特定のグループの機能を実現する要素が別個のパーツに格納されます。 たとえば、ドキュメント内のすべての作成者は 1 つの作成者パーツに格納され、各スライドには独自のパーツがあります。ISO/IEC 29500: 2016
次の XML コードの例は、267 と 256 という ID で示される 2 つのスライドを含むプレゼンテーションを表します。
<p:presentation xmlns:p="…" … >
<p:sldMasterIdLst>
<p:sldMasterId
xmlns:rel="https://…/relationships" rel:id="rId1"/>
</p:sldMasterIdLst>
<p:notesMasterIdLst>
<p:notesMasterId
xmlns:rel="https://…/relationships" rel:id="rId4"/>
</p:notesMasterIdLst>
<p:handoutMasterIdLst>
<p:handoutMasterId
xmlns:rel="https://…/relationships" rel:id="rId5"/>
</p:handoutMasterIdLst>
<p:sldIdLst>
<p:sldId id="267"
xmlns:rel="https://…/relationships" rel:id="rId2"/>
<p:sldId id="256"
xmlns:rel="https://…/relationships" rel:id="rId3"/>
</p:sldIdLst>
<p:sldSz cx="9144000" cy="6858000"/>
<p:notesSz cx="6858000" cy="9144000"/>
</p:presentation>
Open XML SDK を使用すると、PresentationML 要素に対応する厳密に型指定されたクラスを使用して、ドキュメント構造とコンテンツを作成できます。 これらのクラスは、 名前空間にあります。 次の表に、 sld
、 sldLayout
、 sldMaster
、および notesMaster
の各要素に対応するクラスのクラス名を示します。
PresentationML 要素 | Open XML SDK クラス | 説明 |
---|---|---|
<sld/> |
Slide | プレゼンテーション スライド。 SlidePart のルート要素 |
<sldLayout/> |
SlideLayout | スライド レイアウト。 SlideLayoutPart のルート要素 |
<sldMaster/> |
SlideMaster | スライド マスター。 SlideMasterPart のルート要素 |
<notesMaster/> |
NotesMaster | ノート マスター (または handoutMaster)。 NotesMasterPart のルート要素 |
サンプル コードの動作のしくみ
プレゼンテーション ファイル内の特定のスライドを新しい位置に移動するためには、最初にプレゼンテーション内のスライド数を知る必要があります。 そのため、このトピックのコードは、2 つの部分に分かれています。 スライドの数をカウントする部分と、スライドを新しい位置に移動する部分です。
スライドの数をカウントする
スライドの数をカウントするためのサンプル コードは、メソッド CountSlides
の 2 つのオーバーロードで構成されます。 最初のオーバーロードは string
パラメーターを使用し、2 番目のオーバーロードでは PresentationDocument
パラメーターを使用します。 最初の CountSlides
メソッドでは、サンプル コードによって、 using
ステートメントでプレゼンテーション ドキュメントが開きます。 次に、 PresentationDocument
オブジェクトを 2 番目の CountSlides
メソッドに渡します。これは、プレゼンテーション内のスライドの数を表す整数を返します。
// Pass the presentation to the next CountSlides method
// and return the slide count.
return CountSlides(presentationDocument);
2 番目のCountSlides
メソッドでは、渡されたPresentationDocument
オブジェクトがnull
されていないことを確認し、PresentationDocument
オブジェクトからPresentationPart
オブジェクトを取得します。
SlideParts
を使用すると、コードはslideCount
を取得して返します。
int slidesCount = 0;
// Get the presentation part of document.
PresentationPart? presentationPart = presentationDocument.PresentationPart;
// Get the slide count from the SlideParts.
if (presentationPart is not null)
{
slidesCount = presentationPart.SlideParts.Count();
}
// Return the slide count to the previous method.
return slidesCount;
スライドを別の位置に移動する
次のusing
ステートメントに示すように、スライドを新しい位置に移動するには、Boolean パラメーターにtrue
値を指定して、読み取り/書き込みアクセス用のファイルを開く必要があります。 スライドを移動するためのコードは、 MoveSlide
メソッドの 2 つのオーバーロードで構成されます。 最初にオーバーロードされた MoveSlide
メソッドは、プレゼンテーション ファイル名とパスを表す文字列と、スライドの現在のインデックス位置を表す 2 つの整数、およびスライドを移動するインデックス位置の 3 つのパラメーターを受け取ります。 プレゼンテーション ファイルを開き、 PresentationDocument
オブジェクトを取得し、そのオブジェクトと 2 つの整数 ( from
と to
) を、実際の移動を実行する 2 つ目のオーバーロードされた MoveSlide
メソッドに渡します。
// Move a slide to a different position in the slide order in the presentation.
public static void MoveSlide(string presentationFile, int from, int to)
{
using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, true))
{
MoveSlide(presentationDocument, from, to);
}
}
2 つ目のオーバーロードされた MoveSlide
メソッドでは、 CountSlides
メソッドが呼び出され、プレゼンテーション内のスライドの数が取得されます。 次に、0 から始まるインデックス ( from
と to
) が範囲内にあり、互いに異なるかどうかを確認します。
// Move a slide to a different position in the slide order in the presentation.
static void MoveSlide(PresentationDocument presentationDocument, int from, int to)
{
if (presentationDocument is null)
{
throw new ArgumentNullException("presentationDocument");
}
// Call the CountSlides method to get the number of slides in the presentation.
int slidesCount = CountSlides(presentationDocument);
// Verify that both from and to positions are within range and different from one another.
if (from < 0 || from >= slidesCount)
{
throw new ArgumentOutOfRangeException("from");
}
if (to < 0 || from >= slidesCount || to == from)
{
throw new ArgumentOutOfRangeException("to");
}
PresentationPart
オブジェクトが宣言され、渡されたPresentationDocument
オブジェクトのプレゼンテーション部分と等しく設定されます。
PresentationPart
オブジェクトは、Presentation
オブジェクトを作成し、Presentation
オブジェクトからプレゼンテーション内のスライドの一覧を表すSlideIdList
オブジェクトを作成するために使用されます。 ソース スライド (移動するスライド) のスライド ID が取得され、ターゲット スライド (ソース スライドはスライド順でこのスライドの後ろに移動されます) の位置が特定されます。
// Get the presentation part from the presentation document.
PresentationPart? presentationPart = presentationDocument.PresentationPart;
// The slide count is not zero, so the presentation must contain slides.
Presentation? presentation = presentationPart?.Presentation;
if (presentation is null)
{
throw new ArgumentNullException(nameof(presentation));
}
SlideIdList? slideIdList = presentation.SlideIdList;
if (slideIdList is null)
{
throw new ArgumentNullException(nameof(slideIdList));
}
// Get the slide ID of the source slide.
SlideId? sourceSlide = slideIdList.ChildElements[from] as SlideId;
if (sourceSlide is null)
{
throw new ArgumentNullException(nameof(sourceSlide));
}
SlideId? targetSlide = null;
// Identify the position of the target slide after which to move the source slide.
if (to == 0)
{
targetSlide = null;
}
else if (from < to)
{
targetSlide = slideIdList.ChildElements[to] as SlideId;
}
else
{
targetSlide = slideIdList.ChildElements[to - 1] as SlideId;
}
SlideID
オブジェクトの Remove
メソッドを使用してソース スライドを現在の位置から削除し、SlideIdList
オブジェクトの InsertAfter
メソッドを使用して、ターゲット スライドの後のインデックス位置にソース スライドを挿入します。 最後に、変更されたプレゼンテーションが保存されます。
// Remove the source slide from its current position.
sourceSlide.Remove();
// Insert the source slide at its new position after the target slide.
slideIdList.InsertAfter(sourceSlide, targetSlide);
サンプル コード
C# と Visual Basic の両方の同じプレゼンテーション ファイル内のスライドを 1 つの位置から別の位置に移動するために使用できる完全なサンプル コードを次に示します。
// Counting the slides in the presentation.
public static int CountSlides(string presentationFile)
{
// Open the presentation as read-only.
using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, false))
{
// Pass the presentation to the next CountSlides method
// and return the slide count.
return CountSlides(presentationDocument);
}
}
// Count the slides in the presentation.
static int CountSlides(PresentationDocument presentationDocument)
{
int slidesCount = 0;
// Get the presentation part of document.
PresentationPart? presentationPart = presentationDocument.PresentationPart;
// Get the slide count from the SlideParts.
if (presentationPart is not null)
{
slidesCount = presentationPart.SlideParts.Count();
}
// Return the slide count to the previous method.
return slidesCount;
}
// Move a slide to a different position in the slide order in the presentation.
public static void MoveSlide(string presentationFile, int from, int to)
{
using (PresentationDocument presentationDocument = PresentationDocument.Open(presentationFile, true))
{
MoveSlide(presentationDocument, from, to);
}
}
// Move a slide to a different position in the slide order in the presentation.
static void MoveSlide(PresentationDocument presentationDocument, int from, int to)
{
if (presentationDocument is null)
{
throw new ArgumentNullException("presentationDocument");
}
// Call the CountSlides method to get the number of slides in the presentation.
int slidesCount = CountSlides(presentationDocument);
// Verify that both from and to positions are within range and different from one another.
if (from < 0 || from >= slidesCount)
{
throw new ArgumentOutOfRangeException("from");
}
if (to < 0 || from >= slidesCount || to == from)
{
throw new ArgumentOutOfRangeException("to");
}
// Get the presentation part from the presentation document.
PresentationPart? presentationPart = presentationDocument.PresentationPart;
// The slide count is not zero, so the presentation must contain slides.
Presentation? presentation = presentationPart?.Presentation;
if (presentation is null)
{
throw new ArgumentNullException(nameof(presentation));
}
SlideIdList? slideIdList = presentation.SlideIdList;
if (slideIdList is null)
{
throw new ArgumentNullException(nameof(slideIdList));
}
// Get the slide ID of the source slide.
SlideId? sourceSlide = slideIdList.ChildElements[from] as SlideId;
if (sourceSlide is null)
{
throw new ArgumentNullException(nameof(sourceSlide));
}
SlideId? targetSlide = null;
// Identify the position of the target slide after which to move the source slide.
if (to == 0)
{
targetSlide = null;
}
else if (from < to)
{
targetSlide = slideIdList.ChildElements[to] as SlideId;
}
else
{
targetSlide = slideIdList.ChildElements[to - 1] as SlideId;
}
// Remove the source slide from its current position.
sourceSlide.Remove();
// Insert the source slide at its new position after the target slide.
slideIdList.InsertAfter(sourceSlide, targetSlide);
}