三流君 ken3のmemo置き場

三流プログラマーのメモ書きです。主にVBAやWindowsの話題が多いです

挨拶・自己紹介:
失敗続きのAB型の変わり者 :三流プログラマー Ken3です
フリーのエンジニア・個人事業主です・・と書くと聞こえはイイが(それとなくカッコよく聞こえるが)、 現在は小さな案件の受注請負 と 短期派遣 で 日々つつましく?ほそぼそと暮らしてます。

よく検索されるキーワード: [質問回答XXXXさんへ] [CreateObject] [VBA] [JRA競馬オッズ]

パワポ スライドショー 1ページ目に乱数セット 2ページ目で設定値を使いたい PowerPoint VBA OnSlideShowPageChange


下記の質問をコメント欄でいただきました。

PowerPointでゲームモドキを作っているものです。
>スライド1に能力設定(攻撃、防御)、ランダム関数を使った数値
>スライド2で戦闘を考えているのですが、スライド1の数値をスライド2に反映させる方法がわかりません。

サクっとカッコつけて素早く答えたかったけど、
いつものように、あのあの、手間取りました。 ぉぃぉぃ
youtu.be
https://youtu.be/jP0O2KlXeLE
目次
00:00 1.処理のタイミングをとりたい
00:32 1.2 標準モジュールにOnSlideShowPageChange
03:20 1.4 ん?一回目にコードが走らない?なんだこれ?
05:55 2.事前準備で名前を付ける
08:12 3.1 1ページ目でランダムの数値をセットする
11:37 3.2 スライド2ページ目に移動したら、1ページ目の値をセットする
15:39 4.スライドショー実行中、エラーを無視している?
17:27 5.おまけ 蛇足の繰り返し Split関数を使う

1.処理のタイミングをとりたい
単体テストで、処理のタイミング、
スライドが切り替わったタイミングを取りたかったので、
いつものように
VBA PowerPoint イベント処理 スライド開始SlideShowBegin と スライド終了SlideShowEnd を例題に

クラスモジュールのWithEventsを解説
https://www.youtube.com/watch?v=E837vhWZ09g
みたいに、
WithEventsを使って、
Public WithEvents App As Application
なんて、難しく、やろうと思っていたら、

なんと、最近は、

1.2 標準モジュールに OnSlideShowPageChange が書けるんですね

'ページが切り替わった時
Public Sub OnSlideShowPageChange(ByVal Wn As SlideShowWindow)
    MsgBox "ページ :" & ActivePresentation.SlideShowWindow.View.Slide.SlideIndex
End Sub

あれ、これが動くんだ・・・いいなぁ。って違うか。

google:VBA PowerPoint スライドショー ページ切替 イベントなどで検索すると見つかります。

1.3 ページ別の処理

Select case で 切り替えるとか?まぁ、コードが長くなるなら、サブ関数にした方がいいかな。

    'select Caseで分岐
    Select Case ActivePresentation.SlideShowWindow.View.Slide.SlideIndex
        Case 1:
                MsgBox "初回の処理"
        Case 2:
                MsgBox "2ページ の処理"
        Case 4:
                MsgBox "4ページ の処理 3ページはやらないの?"
    End Select

1.4 ん?一回目にコードが走らない?なんだこれ?
テストOKと安心して、再度テストすると、
あれ?コードが走らない・・なんでだ?
※なんか、抜けているみたいで、一度使わないスライドのコードを作ると、
 動くみたい?なんだろう?
ダミーで、開発からボタンを追加するといいみたい※おまじない?
標準モジュールに OnSlideShowPageChange って邪道なのかなぁ?う~ん・・・

2.事前準備で名前を付ける
気を取り直して、下準備の説明を開始します。

ホーム 配置 オブジェクト

パワポ テキストボックスに名前を付けます
https://youtu.be/ZLkCiXC0FzQ?t=63
↑参照。

ここでは、

相手
体力 [99](txt相手体力)
攻撃力 [99](txt相手攻撃力)
防御力 [99](txt相手防御力)

自分
体力 [99](txt自分体力)
攻撃力 [99](txt自分攻撃力)
防御力 [99](txt自分防御力)

と1ページ目のテキストボックスに名前をつけました。

単純に2ページ目にコピーしました。

3.実際に組み込んでみた

3.1 1ページ目でランダムの数値をセットする
スライドの一ページ目でランダムな数値を発生させて、
テキストボックスにセットします

google:VBA 乱数 サイコロ などで検索すると
Randomize
MyValue = Int((6 * Rnd) + 1) '
などが、みつかるので、あとは、好きな数値に変えてテストします。

PowerPoint テキストボックスに名前を付ける VBAから値をセットしたかったのでオブジェクトに名前

を手作業で付け セット処理を確認してみる
https://youtu.be/1nKrP4nhqHE?t=390
みたいに
ActivePresentation.Slides(2).Shapes("txtA").TextFrame.TextRange.Text = "AAAA"
ActivePresentation.Slides(2).Shapes("txtB").TextFrame.TextRange.Text = "222page2BBB"
.Slides(2)で二ページ目、.Shapes("txtB")で指定したほうが楽かな
これを変更して、
やるといいのかなぁ。

'1ページ目、初期処理。ランダムな数値をセットする
Sub page1処理()
    
    Dim 乱数 As Integer
    Randomize  '乱数初期化の同じない
    
    With ActivePresentation.Slides(1)
    
        '相手のステをセットする
        '体力のセット 体力は 20 + 1から12 とする
        乱数 = Int((12 * Rnd) + 1)  '1から12の値
        .Shapes("txt相手体力").TextFrame.TextRange.Text = 20 + 乱数
        
        '攻撃力 は 10 + 1から79 とする
        乱数 = Int((79 * Rnd) + 1)  '1から79の値
        .Shapes("txt相手攻撃力").TextFrame.TextRange.Text = 10 + 乱数
    
        '防御力 は 100-攻撃力 とする
        .Shapes("txt相手防御力").TextFrame.TextRange.Text _
            = 100 - Int(.Shapes("txt相手攻撃力").TextFrame.TextRange.Text)
    
    
        '自分のステをセットする
        '体力のセット 体力は 20 + 1から12 とする
        乱数 = Int((12 * Rnd) + 1)  '1から12の値
        .Shapes("txt自分体力").TextFrame.TextRange.Text = 20 + 乱数
        
        '攻撃力 は 10 + 1から79 とする
        乱数 = Int((79 * Rnd) + 1)  '1から79の値
        .Shapes("txt自分攻撃力").TextFrame.TextRange.Text = 10 + 乱数
    
        '防御力 は 100-攻撃力 とする
        .Shapes("txt自分防御力").TextFrame.TextRange.Text _
            = 100 - Int(.Shapes("txt自分攻撃力").TextFrame.TextRange.Text)
    
    End With

End Sub

3.2 スライド2ページ目に移動したら、1ページ目の値をセットする

単純に代入でいいのかな・・・

下記、腐ったコピペコード・・・

'2ページ目  1ページ目のステをコピーする とりあえずここまで。
Sub page2処理()

    Dim objSL As Slide
    Set objSL = ActivePresentation.Slides(1)  'スライド1ページ目を変数へ
'MsgBox "2ページ目"
    With ActivePresentation.Slides(2)  '2ページ目のスライド
        '縦に並べたら、怒られるなコレ・・・
        .Shapes("txt相手体力").TextFrame.TextRange.Text _
            = objSL.Shapes("txt相手体力").TextFrame.TextRange.Text
        
        .Shapes("txt相手攻撃力").TextFrame.TextRange.Text _
            = objSL.Shapes("txt相手攻撃力").TextFrame.TextRange.Text
        
        .Shapes("txt相手防御力").TextFrame.TextRange.Text _
            = objSL.Shapes("txt相手防御力").TextFrame.TextRange.Text
        
        '自分のステ
        .Shapes("txt自分体力").TextFrame.TextRange.Text _
            = objSL.Shapes("txt自分体力").TextFrame.TextRange.Text
        
        .Shapes("txt自分攻撃力").TextFrame.TextRange.Text _
            = objSL.Shapes("txt自分攻撃力").TextFrame.TextRange.Text
        
        .Shapes("txt自分防御力").TextFrame.TextRange.Text _
            = objSL.Shapes("txt自分防御力").TextFrame.TextRange.Text
    
    End With

End Sub

3.2.1 ミスの起きやすいコピペのコードを修正する

正確にコピペすればいいんだけど※良くないです
自分とか相手とか、置き換えでミスしたり・・・
あと、コードが読みにくかったり※逆にコピペコードは簡単で読みやすい的な・・・だめだこりゃ・・

配列に項目名をセットして、ループで回してみます。

手前みそ動画だと
Array関数で配列の初期化 その後 Split関数で区切り 配列作成、作成された配列の個数をUBoundで調

べ判断【VBA
https://www.youtube.com/watch?v=OVbqLRFv5Vo
ここら辺りかなぁ

'2ページ目  1ページ目のステをコピーする とりあえずここまで。
Sub page2処理()  'セットする項目名をループで回してみます

    Dim objSLp1 As Slide
    Set objSLp1 = ActivePresentation.Slides(1)  'スライド1ページ目を変数へ
    
    Dim objSLp2 As Slide
    Set objSLp2 = ActivePresentation.Slides(2)  'スライド2ページ目を変数へ
    
    Dim str項目名()
    str項目名 = Array("txt相手体力", "txt相手攻撃力", "txt相手防御力", _
                        "txt自分体力", "txt自分攻撃力", "txt自分防御力")
    
    Dim n As Integer
    For n = 0 To UBound(str項目名)   'UBound使用インデックス最大値までループ
        'ページ1str項目名(n)をページ2にセットする
        objSLp2.Shapes(str項目名(n)).TextFrame.TextRange.Text _
            = objSLp1.Shapes(str項目名(n)).TextFrame.TextRange.Text
    Next n

End Sub

4.スライドショー実行中、エラーを無視している?
勘違いかもしれないが、
MS,パワポ様の親切な仕様かもしれないのですが、
もしかして、
スライドショー実行中、エラーを無視している?

そんな気がした。※エラーを作り、テストしてみる

5.おまけ 蛇足の繰り返し Split関数を使う

Split関数を使って無駄に変更してみた。
どっちがいいのかなぁ・・・う~ん。。。。

Option Explicit

'ページが切り替わった時
Public Sub OnSlideShowPageChange(ByVal Wn As SlideShowWindow)
    
    'select Caseで分岐
    Select Case ActivePresentation.SlideShowWindow.View.Slide.SlideIndex
        Case 1: Call page1処理
        Case 2: Call page2処理
    End Select
'Debug.Print ActivePresentation.SlideShowWindow.View.Slide.SlideIndex
End Sub

'1ページ目、初期処理。ランダムな数値をセットする
Sub page1処理()
    
    Dim 乱数 As Integer
    Randomize  '乱数初期化の同じない
    
    With ActivePresentation.Slides(1)
    
        '相手のステをセットする
        '体力のセット 体力は 20 + 1から12 とする
        乱数 = Int((12 * Rnd) + 1)  '1から12の値
        .Shapes("txt相手体力").TextFrame.TextRange.Text = 20 + 乱数
        
        '攻撃力 は 10 + 1から79 とする
        乱数 = Int((79 * Rnd) + 1)  '1から79の値
        .Shapes("txt相手攻撃力").TextFrame.TextRange.Text = 10 + 乱数
    
        '防御力 は 100-攻撃力 とする
        .Shapes("txt相手防御力").TextFrame.TextRange.Text _
            = 100 - Int(.Shapes("txt相手攻撃力").TextFrame.TextRange.Text)
    
    
        '自分のステをセットする
        '体力のセット 体力は 20 + 1から12 とする
        乱数 = Int((12 * Rnd) + 1)  '1から12の値
        .Shapes("txt自分体力").TextFrame.TextRange.Text = 20 + 乱数
        
        '攻撃力 は 10 + 1から79 とする
        乱数 = Int((79 * Rnd) + 1)  '1から79の値
        .Shapes("txt自分攻撃力").TextFrame.TextRange.Text = 10 + 乱数
    
        '防御力 は 100-攻撃力 とする
        .Shapes("txt自分防御力").TextFrame.TextRange.Text _
            = 100 - Int(.Shapes("txt自分攻撃力").TextFrame.TextRange.Text)
    
    End With

End Sub

'2ページ目  1ページ目のステをコピーする とりあえずここまで。
Sub page2処理()  'セットする項目名をループで回してみます

    Dim objSLp1 As Slide
    Set objSLp1 = ActivePresentation.Slides(1)  'スライド1ページ目を変数へ
    
    Dim objSLp2 As Slide
    Set objSLp2 = ActivePresentation.Slides(2)  'スライド2ページ目を変数へ
    
    Dim str項目名 As Variant
    str項目名 = Split("体力,攻撃力,防御力", ",")
    
    Dim n As Integer
    For n = 0 To UBound(str項目名)   'UBound使用インデックス最大値までループ
        'ページ1str項目名(n)をページ2にセットする
        objSLp2.Shapes("txt相手" & str項目名(n)).TextFrame.TextRange.Text _
            = objSLp1.Shapes("txt相手" & str項目名(n)).TextFrame.TextRange.Text
        
        objSLp2.Shapes("txt自分" & str項目名(n)).TextFrame.TextRange.Text _
            = objSLp1.Shapes("txt自分" & str項目名(n)).TextFrame.TextRange.Text
    
    Next n

End Sub


Sub test()

    Dim MyValue As Long
    Randomize
    MyValue = Int((6 * Rnd) + 1) '
    MsgBox "サイコロ1-6: " & MyValue

End Sub

以上、長かったけど、一つでも処理の参考となればうれしいです。



ken3memo.hatenablog.com
ken3memo.hatenablog.com

Ken3 ホームページ 目次

分類:HPを大きく分けると4つの柱(分類)です。

  1. [VBA・マクロ プログラミング]の解説
    当店の人気はVBA系のCreateObject("XXXXXX.application")で他のアプリケーションを操作するサンプルが人気です
  2. [プログラマーの愚痴]では、あまり見せたくない三流プログラマーの内面かな。
    三流君を踏み台にする
  3. [古いクラシック ASP(Active Server Pages)]の解説。
  4. [元コンビニ店長時代の話]が弟に巻き込まれ、失敗した脱サラ、畑違い?の仕事で失敗。
主に上記4つの分類でHP作成やメルマガの発行を行ってます。
※更新頻度が落ちていて情報の鮮度が悪いです。



本当に三流なんです(笑):たまにスゴイですねなんて言われることもありますが、
真実は→ [三流君の真実は...] ←を初めに見てくださるとわかると思います。
(からくりは、成功例↑しか載せてなくて ヒドイ失敗例はお蔵入り迷宮入りが多かったりします)