PowerPoint (全般)

PowerPoint 全般に関する話題を扱うフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(Windows 7全般 : PowerPoint 2010)
指定したテキストのあるスライド番号を取得したい
投稿日時: 17/09/06 22:01:31
投稿者: iori_y

いつもお世話になっております。
パワポのVBは初めて組みます。
 
スライドにページ番号を振りたいのですが、
[ページ番号/総ページ数]
ではなく、
[ページ番号/任意のページ数]
としたいのです。
 
例えば10枚のスライドを作りますが、そのうちの6枚がプレゼン画面で使用(印刷して配布)し、
残りの4枚は参考資料という構成になっています。
[総ページ数]はマスタに直接入力のため、
ページ数が増えた時にまた修正しないといけないというのが手間や間違いの原因となることがあり、
しばしばほかの部署の資料が間違っていることがあります。
 
そのため、
  ・[ページ数/任意のページ数]という表示にしたい
  ・[任意のページ数]は自動で修正してほしい
ということをしたいが出来るか?という相談が来ました。
 
ネットにある数少ないマクロの説明では、やはり[総ページ数]なので
希望している自動化はムリなのかな。。。と思いつつ、こちらに相談に着ました。
 
今日一日考えてみたコードは以下のとおりです。
 
資料作成のルール:報告画面の最後は「END」だけを表示させる
 

Option Explicit
'参考1
''【パワポでテキストボックス内のテキストを取得するマクロ備忘録】
''http://d.hatena.ne.jp/dzd12061/20111123/1322058057

'参考2
''【TextRange.Find メソッド (PowerPoint)】(JP)
''https://msdn.microsoft.com/ja-jp/library/office/ff744247.aspx

'参考3
''パワーポイントの総スライド数を思い通りに表示する様々な方法
''http://thepopp.com/how-to-insert-total-number-of-slides/#VBA

'参考4
'Microsoft PowerPoint の VBA でスライドの総数をカウントして表示する
'https://www.nakagawamasayuki.jp/2016/10/08/8/

Const DEFAULT_DIVIDER As String = "/"

Sub SlideNo_insert()

Dim pSlide As Slide
Dim pShape As Shape
Dim txtRng As textRange
Dim foundText As textRange
Dim FoundSlide As Slide
Dim LstSlide As Long
Dim i As Long

    '全てのスライドをチェックする
    For Each pSlide In ActivePresentation.Slides

    'すべてのシェイプ(図形)をチェックする
        For Each pShape In pSlide.Shapes

            If pShape.HasTextFrame Then
                Set txtRng = pShape.TextFrame.textRange
                Set foundText = txtRng.Find(FindWhat:="End")
            Do While Not (foundText Is Nothing)
                With foundText
                    LstSlide = foundText.InsertSlideNumber
                    Set foundText = txtRng.Find(FindWhat:="End", After:=.Start + .Length - 1)
                End With
            Loop
            End If
         Next
            pSlide.DisplayMasterShapes = True
        
        'スライドマスタ上にあるフッター右下の名前は、基本は「スライド番号プレースホルダー*」となっている
        '名前を左から12文字抜き出して、「Slide Number」なら、ページ番号を振っていく
        For Each pShape In pSlide.Shapes
            If Left(pShape.Name, 12) = "Slide Number" Then
                pShape.TextFrame.textRange.Text = pSlide.SlideNumber & DEFAULT_DIVIDER & LstSlide
            End If
        Next
    Next
MsgBox LstSlide
End Sub

 
「END」と書かれたテキストボックスは見つけてくれましたが、
そのテキストボックスのあるスライド番号の取得が出来ません。
上記コードを実行すると、スライド番号を取得しているように見えますが、
InsertSlideNumber」を使用しているので、「END」にページ番号が挿入され、
表示が「END4」となってしまいます(当たり前ですが。。。)
 
また、ページ番号の割り振りが[1/0][2/0][3/0][4/4][5/4]・・・となってしまい、
希望する[1/4][2/4][3/4][4/4]となりません。
(参考資料のページはページ番号がなくても構わないとのことでした)
 
 
なんとかスライド番号を取得する方法がないでしょうか?

回答
投稿日時: 17/09/07 12:06:04
投稿者: sk

引用:
例えば10枚のスライドを作りますが、
そのうちの6枚がプレゼン画面で使用(印刷して配布)し、
残りの4枚は参考資料という構成になっています。

・1 〜 6 枚目のスライドがプレゼン画面用、
 7 〜 10 枚目のスライドが参考資料用である。
 
・1 〜 4 枚目のスライドが参考資料用、
 5 〜 10 枚目のスライドがプレゼン画面用である。
 
どちらの意味でおっしゃっているのでしょうか。

回答
投稿日時: 17/09/07 14:07:32
投稿者: んなっと

よく読んでいませんが、こんな感じでしょうか。
 
Sub SlidesCount_Add()
  Dim Sld As Slide
  Dim Shp As Shape
  Dim cntSld As Long
  For Each Sld In ActivePresentation.Slides
    For Each Shp In Sld.Shapes
      If Shp.HasTextFrame Then
        With Shp.TextFrame
          If .HasText Then
            If .TextRange.Text = "End" Then
              cntSld = Sld.SlideIndex
              GoTo tugi
            End If
          End If
        End With
      End If
    Next
  Next
tugi:
  If cntSld > 0 Then
    For Each Sld In ActivePresentation.Slides
      For Each Shp In Sld.Shapes
        SlideNum Shp, cntSld
      Next
    Next
    For Each Shp In ActivePresentation.Slides(cntSld).CustomLayout.Shapes
      SlideNum Shp, cntSld
    Next
  End If
End Sub
Sub SlideNum(Shp As Shape, cntSld As Long)
  Dim numStr As Long
  If Shp.Type = msoPlaceholder Then
    If Shp.PlaceholderFormat.Type = ppPlaceholderSlideNumber Then
      With Shp.TextFrame.TextRange
        numStr = InStr(1, .Text, "/")
        If numStr > 0 Then
          .Characters(numStr, .Characters.Count) = "/" & cntSld
        Else
          .InsertAfter "/" & cntSld
        End If
      End With
    End If
  End If
End Sub

投稿日時: 17/09/11 19:30:56
投稿者: iori_y

skさん、んなっとさん
 
すみません、折角お返事を頂いたのにちょっと放置した形になってしまいました。
 
希望の形ですが、

スライド番号           内容                希望1              希望2 
[    1      ]          title                                   1/6 

[    2      ]                              1/5                2/6 

[    3      ]                              2/5                3/6 

[    4      ]                              3/5                4/6 

[    5      ]                              4/5                5/6 

[    6      ]           end                 5/5                6/6  

[    7      ]                               *                  *  

[    8      ]                               *                  *  

[    9      ]                               *                  * 

[    10     ]                               *                  * 

という形にしたいと思っています。
 
んなっとさんから頂いたコードは、全く反応がありませんでした。
推測で申し訳ないのですが、
            If .TextRange.Text = "End" Then 
               cntSld = Sld.SlideIndex 

デバッグしてもcntSldに値が入らなかったので、ここが問題かなと思いました。
 
で、参考にさせていただいて本日また色々やってみました。
Option Explicit

Sub SlidesCount_Add()
   Dim Sld As Slide
   Dim Shp As Shape
   Dim cntSld As Long
   Dim txtRng As TextRange
   Dim foundtext As TextRange

   For Each Sld In ActivePresentation.Slides
     For Each Shp In Sld.Shapes
      
       If Shp.HasTextFrame Then
                Set txtRng = Shp.TextFrame.TextRange
                Set foundtext = txtRng.Find(FindWhat:="End")
            Do While Not (foundtext Is Nothing)
                With foundtext
                    cntSld = Sld.SlideIndex
’                    Debug.Print cntSld
                     GoTo tugi
                    Set foundtext = txtRng.Find(FindWhat:="End", After:=.Start + .Length - 1)
                End With
            Loop
       End If
     Next
   Next
tugi:
  If cntSld > 0 Then
     For Each Sld In ActivePresentation.Slides
       For Each Shp In Sld.Shapes
         SlideNum Shp, cntSld
       Next
     Next
     For Each Shp In ActivePresentation.Slides(cntSld).CustomLayout.Shapes
       SlideNum Shp, cntSld
     Next
   End If
End Sub

Function SlideNum(Shp As Shape, cntSld As Long) 'Subで頂きましたが、これで良いですよね?
   Dim numStr As Long
   
   If Shp.Type = msoPlaceholder Then
     If Shp.PlaceholderFormat.Type = ppPlaceholderSlideNumber Then
       With Shp.TextFrame.TextRange
         numStr = InStr(1, .Text, "/")
         If numStr > 0 Then
           .Characters(numStr, .Characters.Count) = "/" & cntSld
         Else
           .InsertAfter "/" & cntSld
         End If
       End With
     End If
   End If
End Function

 
としたところ、希望2の形で表示がされました!
(End以降は [7/6][8/6]・・・ですが)
 
多分今後言われることとしては、
 1)”END”じゃない場合も想定して欲しい
 2)参考資料のページ数は何とかならないか
だと思います。
 
1に関してはユーザーフォームを表示させて選択(もしくはテキスト入力)してもらって、
それを変数にすればいけるのかな?と思っていますが、
2に関しては変数を追加して、
For〜Nextで1枚目からcntSldまでとすれば出来るのかな?とやってみましたが、
[1/][2/]・・・[6/6][7/6]・・・となってしまいました。
(すみません、この時のコードを持って帰ってくるのを忘れました)
 
プレースホルダーに総ページ数を入れていくので、
For〜Nextではうまくいかないと言う理解でいいのでしょうか。。。?
そうすると、なんで6ページ目から入るんだろうという疑問があります。
(私が一番最初に作ったマクロはマスタを操作する感じだったのでムリなのかなと思っていました)
 
 
パワポマクロは難しいです。[/quote]

回答
投稿日時: 17/09/11 19:56:38
投稿者: んなっと

引用:
資料作成のルール:報告画面の最後は「END」だけを表示させる

とあったので、報告画面最後のスライドに
 
End
 
の「3文字だけ」しか入力していないテキストボックスなどが存在するという前提で考えました。
違うのですか?
 
仮に
 
-End----
 
などのようにEnd以外の文字も存在する場合は、
 
            If .TextRange.Text = "End" Then
                ↓
            If .TextRange.Text Like "*End*" Then
 
となるだけです。
コードを貼り付けるよりも、仕様の説明を正確にすることを優先してください。

投稿日時: 17/09/11 20:24:03
投稿者: iori_y

すみません。
ENDの3文字だけです。
 
ですが、部署によってははENDではなく Thank you for listening と表示する部署や
ご静聴ありがとうございました と表示する部署もあります。
(日本語/英語の両方でパワポ資料作成をする時もあります)
 
ENDで統一すればそれでいいのかもしれませんが、
今のままを使いたいと言われると、そういう対処法しかないかなと思った次第です。

回答
投稿日時: 17/09/11 21:03:51
投稿者: んなっと

最初の質問はもう解決したようなので、閉じましょう。
ここから先はできるはずです。

投稿日時: 17/09/13 21:24:43
投稿者: iori_y

ありがとうございました。