質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

1回答

8498閲覧

Powerpoint VBAで作ったカウントダウンタイマーに①一時停止ボタンをつけたい。②スライドごと複製しても使えるようにしたい。

SnowMonkey

総合スコア53

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

2クリップ

投稿2020/04/20 00:21

編集2020/04/21 14:18

前提

パワーポイントのスライド上にカウントダウンタイマーを表示したいときがあり、
ネットを参考に、作ってみました。

図形をクリックすることで分と秒を指定し、
大きい四角をクリックするとカウントダウンが始まるところまで
出来ました。

イメージ説明 図形の書式―オブジェクトの選択と表示で図形にTimerShape, ResetShape, MinutesShape, SecondsShapeと名前つけています。挿入―動作で図形をクリックするとマクロが動くよう関連付けています](6db2d64d0985d96d5ad9333f1eb87409.png)

実現したいこと

実現したいことが2つあります。

  1. カウントダウンの途中で止めることができるよう改造したいのですが、上手く行きません。
  2. カウントダウン用スライドを1ファイルの任意の場所に、複数おいても動くようにしたい。

発生している問題・エラーメッセージ

該当のソースコード

VBA

1Option Explicit 2Dim Minutes As Long 3Dim Seconds As Long 4'Dim tempStop As Boolean 5 6'-----------何分のカウントダウンか設定する-------------------------- 7 8Sub SetMinutes() 9 If Minutes < 59 Then 10 Minutes = Minutes + 1 11 Else 12 Minutes = 0 13 End If 14 15 ActivePresentation.Slides(1).Shapes("MinuteShape").TextFrame.TextRange.Text = Minutes & " min" 16 Debug.Print (Minutes & ":" & Seconds) 17End Sub 18 19'-----------何秒かのカウントダウンか設定する-------------------------- 20 21Sub SetSeconds() 22 23 If Seconds < 50 Then 24 Seconds = Seconds + 10 25 Else 26 Seconds = 0 27 End If 28 29ActivePresentation.Slides(1).Shapes("SecondsShape").TextFrame.TextRange.Text = Seconds & " s" 30 31Debug.Print (Minutes & ":" & Seconds) 32End Sub 33 34'-----------リセットする-------------------------- 35 36Sub Reset() 37Minutes = 0 38Seconds = 0 39 40 ActivePresentation.Slides(1).Shapes("MinuteShape").TextFrame.TextRange.Text = Minutes & " min" 41 ActivePresentation.Slides(1).Shapes("SecondsShape").TextFrame.TextRange.Text = Seconds & " s" 42Debug.Print (Minutes & ":" & Seconds) 43End Sub 44'-----------カウントダウン-------------------------- 45Sub CountDown() 46 47Dim EndTime As Date 48 49'tempStop = False 50 51Seconds = Minutes * 60 + Seconds 52EndTime = DateAdd("s", Seconds, Now()) 53 54 Do Until EndTime <= Now() 55 DoEvents 56 57 ActivePresentation.Slides(1).Shapes("TimerShape").TextFrame.TextRange.Text = Format((EndTime - Now()), "nn:ss") 58 59' If tempStop = True Then 60' Exit Sub 61' End If 62 63 Loop 64 65End Sub 66 67'Sub JudgeStop() 68' 69' tempStop = True 70' 71'End Sub 72

試したこと

1については、判定用の変数tempStopを用意し、それがtrueならループを抜けるように書いてみましたが、上手く行きません。

2については、現時点では、スライドの位置(スライド番号)は固定なのが問題だと考え、「ActivePresentation.Slides(1).」の部分を 「ActiveWindow.Selection.SlideRange.」に変更しました。しかし、そうすると、図形を押しても反応しなくなりました。

なにぶん初心者ですので、お手上げです。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

  1. カウントダウンの途中で止めることができるよう改造したいのですが、上手く行きません。

「途中で止める」という文言から、一時停止し、再スタートすると前回の続きから動作してほしい、という意図だと判断しました。

そのためには、ユーザーの設定したタイマーの時間を保存する変数以外に、途中で止めた場合の残り時間の変数も必要となります。

2.カウントダウン用スライドを1ファイルの任意の場所に、複数おいても動くようにしたい。

まず、クリックされた図形が存在するスライドを特定する方法ですが、大きく2種類の方法があります。

一つ目はウィンドウから辿る方法です。
PowerPointでは編集用のウィンドウ(DocumentWindow)とスライドショー表示のウィンドウ(SlideShowWindow)は別の物です。
「ActiveWindow.Selection.SlideRange.」はDocumentWindowのため、ActivePresentation.SlideShowWindow.View.SlideのようにSlideShowWindowから辿る必要があります。

二つ目は、図形に登録するマクロの引数を使用する方法です。
PowerPoint独自の仕様ですが、図形に登録するマクロに引数を設定すると、1個目の引数にクリックされた図形(PowerPoint.Shape)が渡されます。
確実にクリックされた図形を取得できるため、こちらの方がより確実な方法と思われます。

それ以外にも、タイマーの設定は、全体で共通でよいのか、スライド毎に個別にしたいのかでコードが変わってきます。


参考として、マクロの引数から図形を取得し、タイマーの設定を全体で共通とする場合の例です。

変数を管理するのが面倒だったため、MinutesSecondstimerTime_の変数にまとめています。

また「途中で止めた場合の残り時間の変数」としてremainingTime_を用意しています。

vba

1Option Explicit 2 3'ユーザーが設定したタイマーの時間 4Private timerTime_ As Date 5 6'途中で止めたときの残り時間 7Private remainingTime_ As Date 8 9'一時停止用のフラグ 10Private isRunning_ As Boolean 11 12 13'共通処理 14 15'inTimeにinSecond秒足した時間を返す。ただし、1時間を超える分は切り捨てる。 16Private Function AddSecondsAndLimit1Hour(inTime As Date, inSecond As Long) As Date 17 Dim newTime As Date 18 newTime = DateAdd("s", inSecond, inTime) 19 20 'Hourを0にすることで、最大でも1時間より小さくなるようにする。 21 Let AddSecondsAndLimit1Hour = TimeSerial(0, Minute(newTime), Second(newTime)) 22End Function 23 24'タイマー部分の図形の表示を更新する 25Private Sub UpdateTimerShape(inSld As PowerPoint.Slide, inTime As Date) 26 With inSld.Shapes 27 .Item("TimerShape").TextFrame.TextRange.Text = Format(inTime, "nn:ss") 28 End With 29End Sub 30 31'時間設定部分の図形を更新する 32Private Sub UpdateSettingShapes(inSld As PowerPoint.Slide, inTime As Date) 33 With inSld.Shapes 34 .Item("MinuteShape").TextFrame.TextRange.Text = Minute(inTime) & " min" 35 .Item("SecondsShape").TextFrame.TextRange.Text = Second(inTime) & " s" 36 End With 37 UpdateTimerShape inSld, inTime 38 39 '時間設定を変えるということは、一時停止の情報をリセットしてもいいという判断 40 remainingTime_ = CDate(Empty) 41End Sub 42 43 44'-----------何分のカウントダウンか設定する-------------------------- 45 46Sub SetMinutes(inMinuteShape As PowerPoint.Shape) 47 '60秒(=1分)足して、図形の表示を更新する。 48 timerTime_ = AddSecondsAndLimit1Hour(timerTime_, 60) 49 UpdateSettingShapes inMinuteShape.Parent, timerTime_ 50 51 Debug.Print Format(timerTime_, "nn:ss") 52End Sub 53 54'-----------何秒かのカウントダウンか設定する-------------------------- 55 56Sub SetSeconds(inSecondsShape As PowerPoint.Shape) 57 '10秒足して、図形の表示を更新する。 58 timerTime_ = AddSecondsAndLimit1Hour(timerTime_, 10) 59 UpdateSettingShapes inSecondsShape.Parent, timerTime_ 60 61 Debug.Print Format(timerTime_, "nn:ss") 62End Sub 63 64'-----------リセットする-------------------------- 65 66Sub Reset(inResetShape As PowerPoint.Shape) 67 timerTime_ = CDate(Empty) 68 UpdateSettingShapes inResetShape.Parent, timerTime_ 69 70 Debug.Print Format(timerTime_, "nn:ss") 71End Sub 72 73'-----------カウントダウン-------------------------- 74Sub CountDown(inCountDownShape As PowerPoint.Shape) 75 If isRunning_ Then 76 '個人的にスタートと一時停止はトグル式の方が好みだったのでその対応。 77 '実行中に押した場合は停止させる。 78 isRunning_ = False 79 Exit Sub 80 End If 81 82 isRunning_ = True 83 84 Dim EndTime As Date 85 '残り時間が0で無ければその続きから再開。 86 If remainingTime_ = CDate(Empty) Then 87 EndTime = Now + timerTime_ 88 Else 89 EndTime = Now + remainingTime_ 90 End If 91 92 93 Dim sld As PowerPoint.Slide 94 Set sld = inCountDownShape.Parent 95 96 Do Until EndTime <= Now 97 DoEvents 98 remainingTime_ = EndTime - Now 99 UpdateTimerShape sld, remainingTime_ 100 101 If isRunning_ = False Then 102 Exit Sub 103 End If 104 Loop 105 106 '終了処理 107 remainingTime_ = CDate(Empty) 108 isRunning_ = False 109 MsgBox "End" 110End Sub 111 112Sub JudgeStop() 113 isRunning_ = False 114End Sub

投稿2020/04/20 14:54

imihito

総合スコア2166

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

SnowMonkey

2020/04/21 07:52

ありがとうございました。私が実現したかったことが完全に実現できています。とてもうれしいです。 こうすればトグル式に切り替えができるんだとか、shape.Parentでスライドを取得(?指定?)するんだとか、解読しながら勉強させていただいています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問