次の方法で共有


Open XML SDK 2.0 を使用して PowerPoint 2010 プレゼンテーションのスライドを並べ替える

Office Visual How To

概要: PowerPoint にドキュメントを読み込むことなく、Open XML SDK 2.0 for Microsoft Office の厳密に型指定されたクラスを使用して、Microsoft PowerPoint 2010 ドキュメントのスライドの順序を古い位置と新しい位置を指定することで変更します。

適用対象: Excel 2010 | Office 2007 | Office 2010 | Open XML | PowerPoint 2007 | PowerPoint 2010 | VBA | Word 2010

公開: 2010 年 10 月

提供元:  Ken Getz、MCW Technologies (英語)

概要

Open XML ファイル形式を使用すると、Microsoft PowerPoint 2010 または PowerPoint 2007 ドキュメントのスライドの順序を変更できますが、そのためには若干の作業が必要です。Open XML SDK 2.0 で追加される厳密に型指定されたクラスを使用すると、Open XML ファイル形式へのアクセスが簡単になります。この SDK を使用すると、スライドの順序を簡単に変更できます。この Visual How To に含まれるコード サンプルでは、SDK を使用してこの目的を実現する方法を示します。

コード化する

この Visual How To に付属するサンプルには、元の位置と新しい位置を指定して、PowerPoint 2010 または PowerPoint 2007 ドキュメント内のスライドの順序を変更するために必要なコードが含まれます。以下では、このコードについて詳細に説明します。

参照のセットアップ

Open XML SDK 2.0 のコードを使用するには、プロジェクトにいくつかの参照を追加する必要があります。サンプル プロジェクトには既にこれらの参照が含まれていますが、独自のコードでは次のアセンブリを明示的に参照する必要があります。

  • WindowsBase - 作成するプロジェクトの種類によっては、この参照がユーザーのために既に設定されている場合があります。

  • DocumentFormat.OpenXml - Open XML SDK 2.0 によってインストールされます。

また、次の using/Imports ステートメントをコード ファイルの先頭に追加する必要があります。

Imports DocumentFormat.OpenXml.Packaging
Imports DocumentFormat.OpenXml.Presentation
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Presentation;

プロシージャの確認

PPTReorderSlides プロシージャは 3 つのパラメーターを受け取ります。変更するプレゼンテーションの名前を示すパラメーター (string)、移動するスライドの元の位置、そして移動後のスライドの新しい位置です。サンプル プロシージャには、特定のケースを処理する方法を決定するためのヒューリスティックが含まれます。

  • 最後のスライドを元の位置または新しい位置として使用することを指定するには、対応するパラメーターに 0 未満の値を渡します (つまり、元の位置として値 -1 を渡すと、プロシージャはプレゼンテーションの最後のスライドを新しい位置に移動します)。

  • 元の位置がプレゼンテーションのスライドの数より大きい場合は、デックの最後のスライドが新しい位置に移動されます。

  • 新しい位置がプレゼンテーションのスライドの数より大きい場合は、選択されているスライドがプレゼンテーションの最後の位置に移動されます。

プロシージャは結果を示す値を返します。

  • 元の位置と新しい位置が同じ場合、プロシージャは何も行わず、-1 を返します。

  • スライドを移動した場合、プロシージャは指定されたスライドの新しい位置を返します。

プロシージャの宣言は次のようになります。

Public Function PPTReorderSlides(ByVal fileName As String, _
  ByVal originalPosition As Integer, 
  ByVal newPosition As Integer) As Integer
public static int PPTReorderSlides(
  string fileName, int originalPosition, int newPosition)

このプロシージャは、指定されたプレゼンテーションを変更し、1 つのスライドを originalPosition から newPosition に移動します。プロシージャを呼び出すには、コード例で示されているようにパラメーター値を渡します。サンプル コードを実行する前に、デモ用に少なくともいくつかのスライドを含む C:\temp\Sample.pptx という名前のドキュメントを用意しておく必要があります。次のコードでは、位置 0 のスライドを位置 3 に移動する方法を示します。

Console.WriteLine(
  PPTReorderSlides("C:\temp\sample.pptx", 0, 3).ToString())
Console.WriteLine(
  PPTReorderSlides("C:\temp\sample.pptx", 0, 3).ToString());

PPTReorderSlides 関数は、移動後のスライドの位置を返します。この値は、newPosition の値と、プレゼンテーションに含まれるスライドの数によっては、要求した新しい位置と異なる場合があります。スライドが移動されなかった場合は、関数は -1 を返します。

戻り値の設定

サンプル プロシージャでは、最初に戻り値を設定してから、新しい位置と元の位置が同じではないことを確認します。同じ場合、コードはすぐに返ります。

' Assume that no slide moves; return -1.
Dim returnValue As Integer = -1

' Moving to and from same position? Get out now.
If newPosition = originalPosition Then
  Return returnValue
End If
// Assume that no slide moves; return -1.
int returnValue = -1;

// Moving to and from same position? Get out now.
if (newPosition == originalPosition)
{
  return returnValue;
}

プレゼンテーションへのアクセス

次に、PresentationDocument.Open メソッドを使用してドキュメントを開き、読み取り/書き込みアクセス許可でドキュメントを開くように指定しています (最後の True パラメーター)。コードは、すぐにプレゼンテーションの作成者パーツの参照を取得し、参照が null の場合は例外をスローします (コードがプレゼンテーション パーツを見つけられない場合、プレゼンテーションには何らかの問題があります)。

Using doc As PresentationDocument = 
  PresentationDocument.Open(fileName, True)

  ' Get the presentation part of the document.
  Dim presentationPart As PresentationPart = doc.PresentationPart
  ' No presentation part? Something is wrong with the document.
  If presentationPart Is Nothing Then
    Throw New ArgumentException("fileName")
  End If
  ' Code removed here…
End Using
using (PresentationDocument doc = 
  PresentationDocument.Open(fileName, true))
{
  // Get the presentation part of the document.
  PresentationPart presentationPart = doc.PresentationPart;
  // No presentation part? Something is wrong with the document.
  if (presentationPart == null)
  {
    throw new ArgumentException("fileName");
  }
  // Code removed here…
}

位置の処理

スライドを現在の位置から新しい位置に移動するため、プロシージャは、2 つの数値パラメーターを確認し、場合によっては調整する必要があります。最初に、プレゼンテーションに含まれるスライドの数を取得し、値を変数に格納します。スライドの数が 0 の場合、処理を続ける理由はないので、プロシージャは返ります。スライドの数がわかると、プロシージャはそれから 1 を引いて最大位置を計算した後、CalcPositions プロシージャを呼び出し、必要に応じて元の位置と新しい位置を調節します。CalcPositions プロシージャは、負の値および使用可能なスライドの範囲外の位置を調べます。originalPosition および newPosition の値に対する参照および最大位置の値を基に、CalcPosition プロシージャは必要に応じて値を調節します。

Private Sub CalcPositions(
  ByRef originalPosition As Integer,
  ByRef newPosition As Integer, ByVal maxPosition As Integer)

  ' Adjust the original and new slide position, as necessary.

  If originalPosition < 0 Then
    ' Ask for the slide in the final position? Get that value now.
    originalPosition = maxPosition
  End If

  If newPosition < 0 Then
    ' Ask for the final position? Get that value now.
    newPosition = maxPosition
  End If

  If originalPosition > maxPosition Then
    originalPosition = maxPosition
  End If
  If newPosition > maxPosition Then
    newPosition = maxPosition
  End If
End Sub
private static void CalcPositions(
  ref int originalPosition, ref int newPosition, int maxPosition)
{
  // Adjust the original and new slide position, as necessary.
  if (originalPosition < 0)
  {
    // Ask for the slide in the final position? Get that value now.
    originalPosition = maxPosition;
  }

  if (newPosition < 0)
  {
    // Ask for the final position? Get that value now.
    newPosition = maxPosition;
  }

  if (originalPosition > maxPosition)
  {
    originalPosition = maxPosition;
  }
  if (newPosition > maxPosition)
  {
    newPosition = maxPosition;
  }
}

PPTReorderSlides プロシージャには、CalcPositions プロシージャをセットアップして呼び出す次のコードが含まれます。

' If you are here, you know that presentationPart exists.
Dim slideCount As Integer = presentationPart.SlideParts.Count()

' No slides? Just return -1 indicating that nothing happened.
If slideCount = 0 Then
  Return returnValue
End If

' There are slides. Calculate real positions.
Dim maxPosition As Integer = slideCount - 1

' Adjust the positions, if necessary.
CalcPositions(originalPosition, newPosition, maxPosition)
// If you are here, you know that presentationPart exists.
int slideCount = presentationPart.SlideParts.Count();

// No slides? Just return -1 indicating that nothing happened.
// Original and new positions the same? Nothing to do.
if (slideCount == 0)
{
  return returnValue;
}
// There are slides. Calculate real positions.
int maxPosition = slideCount - 1;
// Adjust the positions, if necessary.
CalcPositions(ref originalPosition, ref newPosition, maxPosition);

順序変更の実行

元の位置と新しい位置の調節が済むと、サンプル コードは実際に順序の変更を実行できます。当然のことながら、古い位置と新しい位置が同じ場合は、コードは何も行わずに単に返ります。

  If newPosition <> originalPosition Then
    ' Code removed here…
  End If
End Using
Return returnValue
  if (newPosition != originalPosition)
  {
    // Code removed here…
  }
}
return returnValue;

一方、新しい位置と元の位置が異なる場合は、プレゼンテーション コンテンツの参照を取得してから、プレゼンテーション内のスライド ID のリストを取得します。

Dim presentation As Presentation = presentationPart.Presentation
Dim slideIdList As SlideIdList = presentation.SlideIdList
Presentation presentation = presentationPart.Presentation;
SlideIdList slideIdList = presentation.SlideIdList;

次に、ソース スライドとターゲット スライドの両方に対する必要なスライド ID を取得します (現在、ターゲット スライドは新しい位置に表示されています)。

Dim sourceSlide As SlideId =
  CType(slideIdList.ChildElements(originalPosition), SlideId)
Dim targetSlide As SlideId =
  CType(slideIdList.ChildElements(newPosition), SlideId)
SlideId sourceSlide = 
  (SlideId)(slideIdList.ChildElements[originalPosition]);
SlideId targetSlide = 
  (SlideId)(slideIdList.ChildElements[newPosition]);

次の手順はではちょっとした技を使います。元の位置のスライドを新しい位置に移動する必要がありますが、スライドが XML ノード ツリーの一部である間はスライドを移動できません。そこで、移動する前に、XML ツリーからスライドを削除する必要があります。

sourceSlide.Remove()
sourceSlide.Remove();

スライドが自由に移動できるようになれば、元の位置のスライドを新しい位置に簡単に配置できます。新しい位置が元の位置より後の場合は、元の位置のスライドをターゲット スライドの後に挿入します。新しい位置が元の位置より前の場合は、元の位置のスライドをターゲット スライドの前に挿入します。どちらの場合も、コードは戻り値を設定してプレゼンテーションを保存します。

If newPosition > originalPosition Then
  slideIdList.InsertAfter(sourceSlide, targetSlide)
Else
  slideIdList.InsertBefore(sourceSlide, targetSlide)
End If

' Set the return value.
returnValue = newPosition

' Save the modified presentation.
presentation.Save()
if (newPosition > originalPosition)
{
  slideIdList.InsertAfter(sourceSlide, targetSlide);
}
else
{
  slideIdList.InsertBefore(sourceSlide, targetSlide);
}

// Set the return value.
returnValue = newPosition;

// Save the modified presentation.
presentation.Save();

サンプル プロシージャ

以下に、完全なサンプル プロシージャのコードを示します。

Public Function PPTReorderSlides(ByVal fileName As String, _
  ByVal originalPosition As Integer, 
  ByVal newPosition As Integer) As Integer

  ' Assume that no slide moves; return -1.
  Dim returnValue As Integer = -1

  ' Moving to and from same position? Get out now.
  If newPosition = originalPosition Then
    Return returnValue
  End If

  Using doc As PresentationDocument = 
    PresentationDocument.Open(fileName, True)
    ' Get the presentation part of the document.
    Dim presentationPart As PresentationPart = doc.PresentationPart
    ' No presentation part? Something is wrong with the document.
    If presentationPart Is Nothing Then
      Throw New ArgumentException("fileName")
    End If

    ' If you are here, you know that presentationPart exists.
    Dim slideCount As Integer = presentationPart.SlideParts.Count()
     ' No slides? Just return -1 indicating that nothing happened.
    If slideCount = 0 Then
      Return returnValue
    End If

    ' There are slides. Calculate real positions.
    Dim maxPosition As Integer = slideCount - 1

    ' Adjust the positions, if necessary.
    CalcPositions(originalPosition, newPosition, maxPosition)

    ' The two positions could have ended up being the same 
    ' thing. There is nothing to do, in that case. Otherwise,
    ' do the work.
    If newPosition <> originalPosition Then
      Dim presentation As Presentation = presentationPart.Presentation
      Dim slideIdList As SlideIdList = presentation.SlideIdList

      ' Get the slide ID of the source and target slides.
      Dim sourceSlide As SlideId =
        CType(slideIdList.ChildElements(originalPosition), SlideId)
      Dim targetSlide As SlideId =
        CType(slideIdList.ChildElements(newPosition), SlideId)

      ' Remove the source slide from its parent tree. You cannot
      ' move a slide while it is part of an XML node tree.
      sourceSlide.Remove()

      If newPosition > originalPosition Then
        slideIdList.InsertAfter(sourceSlide, targetSlide)
      Else
        slideIdList.InsertBefore(sourceSlide, targetSlide)
      End If

      ' Set the return value.
      returnValue = newPosition

      ' Save the modified presentation.
      presentation.Save()
    End If
  End Using
  Return returnValue
End Function

Private Sub CalcPositions(
  ByRef originalPosition As Integer,
  ByRef newPosition As Integer, ByVal maxPosition As Integer)

  ' Adjust the original and new slide position, as necessary.

  If originalPosition < 0 Then
    ' Ask for the slide in the final position? Get that value now.
    originalPosition = maxPosition
  End If

  If newPosition < 0 Then
    ' Ask for the final position? Get that value now.
    newPosition = maxPosition
  End If

  If originalPosition > maxPosition Then
    originalPosition = maxPosition
  End If
  If newPosition > maxPosition Then
    newPosition = maxPosition
  End If
End Sub
public static int PPTReorderSlides(string fileName, int originalPosition, int newPosition)
{
  // Assume that no slide moves; return -1.
  int returnValue = -1;

  // Moving to and from same position? Get out now.
  if (newPosition == originalPosition)
  {
    return returnValue;
  }

  using (PresentationDocument doc = 
    PresentationDocument.Open(fileName, true))
  {
    // Get the presentation part of the document.
    PresentationPart presentationPart = doc.PresentationPart;
    // No presentation part? Something is wrong with the document.
    if (presentationPart == null)
    {
      throw new ArgumentException("fileName");
    }

    // If you are here, you know that presentationPart exists.
    int slideCount = presentationPart.SlideParts.Count();

    // No slides? Just return -1 indicating that nothing happened.
    if (slideCount == 0)
    {
      return returnValue;
    }

    // There are slides. Calculate real positions.
    int maxPosition = slideCount - 1;

    // Adjust the positions, if necessary.
    CalcPositions(ref originalPosition, ref newPosition, maxPosition);

    // The two positions could have ended up being the same 
    // thing. There is nothing to do, in that case. Otherwise,
    // do the work.
    if (newPosition != originalPosition)
    {
      Presentation presentation = presentationPart.Presentation;
      SlideIdList slideIdList = presentation.SlideIdList;

      // Get the slide ID of the source and target slides.
      SlideId sourceSlide = 
        (SlideId)(slideIdList.ChildElements[originalPosition]);
      SlideId targetSlide = 
        (SlideId)(slideIdList.ChildElements[newPosition]);

      // Remove the source slide from its parent tree. You cannot
      // move a slide while it is part of an XML node tree.
      sourceSlide.Remove();

      if (newPosition > originalPosition)
      {
        slideIdList.InsertAfter(sourceSlide, targetSlide);
      }
      else
      {
        slideIdList.InsertBefore(sourceSlide, targetSlide);
      }

      // Set the return value.
      returnValue = newPosition;

      // Save the modified presentation.
      presentation.Save();
    }
  }
  return returnValue;
}

private static void CalcPositions(
  ref int originalPosition, ref int newPosition, int maxPosition)
{
  // Adjust the original and new slide position, as necessary.
  if (originalPosition < 0)
  {
    // Ask for the slide in the final position? Get that value now.
    originalPosition = maxPosition;
  }

  if (newPosition < 0)
  {
    // Ask for the final position? Get that value now.
    newPosition = maxPosition;
  }

  if (originalPosition > maxPosition)
  {
    originalPosition = maxPosition;
  }
  if (newPosition > maxPosition)
  {
    newPosition = maxPosition;
  }
}
手順

この Visual How To に含まれるサンプルでは、PowerPoint プレゼンテーションのスライドの順序を変更するコードが示されています。サンプルを使用するには、「関連情報」のリンクから入手できる Open XML SDK 2.0 をインストールする必要があります。また、このサンプルでは、Open XML SDK 2.0 に対するコード例のセットの一部として含まれるコードの変更バージョンを使用します。「関連情報」セクションにはコード例全体のリンクも含まれますが、例をダウンロードしてインストールしなくてもサンプルを使用できます。

サンプルでは、プレゼンテーションの構造を変更するときに使用できる Open XML SDK 2.0 で提供されているプロパティとメソッドのうちの一部のみが紹介されています。詳細については、Open XML SDK 2.0 生産性ツールに付属するドキュメントを参照してください (アプリケーション ウィンドウの左下隅の [Open XML SDK Documentation] タブをクリックし、目的のクラスを検索します)。現在ドキュメントにコード例は含まれませんが、ここで示したサンプルとドキュメントを使用すれば、サンプル アプリケーションを問題なく変更できるはずです。

ビデオ

ビデオを見る

ビデオを見る (英語) | 所要時間: 00:09:07

クリックしてコードを取得

コードを取得する (英語)

関連情報

著者について
Ken Getz 氏は、MCW Technologies のシニア コンサルタント。『ASP.NET Developers Jumpstart』(Addison-Wesley 刊、2002 年)、『 Access Developer's Handbook』(Sybex 刊、2001 年)、および『VBA Developer's Handbook, 2nd Edition』(Sybex 刊、2001 年) の共著者でもあります。