下記の質問をコメント欄でいただきました。
>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