サウンドを使いたいときがある
- VBAで何かしらの操作環境を提供しているとサウンド/効果音を使いたくなる時があります。例えば処理を待っている間や、ある操作を実施したという印象付けを目的とする効果音等です。
- しかし、Excel自身には音楽データを扱う機能が無いので、OSの機能...WindowsのAPI(Application Programming Interface)を使用します。言い換えると、今回のVBAはWindows上でのみ動作します。
API:mciSendString使用宣言
- 音楽データの処理にはAPIとしてmciSendStringを使用します。APIを使用する場合、VBA記述モジュール内で対象API使用を宣言します。宣言の書き方は下記になりますが、ExcelとCalcで異なります(*1)。まずはExcelでの記述です。
Option Explicit
Option Base 1
'======================================================================
'使用Windowsのbit数で有効ステートメント変わる
'API使用宣言: mciSendString (Excel)
#If Win64 Then
Private Declare PtrSafe Function mciSendString Lib "winmm.dll" Alias "mciSendStringA" _
(ByVal lpstrCommand As String, _
ByVal lpstrReturnString As String, _
ByVal uReturnLength As Long, _
ByVal hwndCallback As Long) _
As Long
#Else
Private Declare Function mciSendString Lib "winmm" Alias "mciSendStringA" _
(ByVal lpstrCommand As String, _
ByVal lpstrReturnString As String, _
ByVal uReturnLength As Long, _
ByVal hwndCallback As Long) _
As Long
#End If |
- 次はCalcでの記述です。使用Windowsのbit数に関わらず下記となります。
Option Explicit
Option Base 1
Option VBASupport 1
'======================================================================
'API使用宣言: mciSendString (Calc)
Private Declare Function mciSendString Lib "winmm" Alias "mciSendStringA" _
(ByVal lpstrCommand As String, _
ByVal lpstrReturnString As String, _
ByVal uReturnLength As Long, _
ByVal hwndCallback As Long) _
As Long |
- これでmciSendStringが使用可能になりました。それでは実際に音楽データを操作してみましょう。
音楽データの再生と停止
- 音楽データの操作は非常にシンプル(*2)です。下記のように使います。strSoundFileには、音楽データファイルのフルパス名が入っていると思って下さい。音楽ファイル名にplay等のコマンドを文字列で追加して第1引数に与えます。
'============================================================
'strSoundFileには、音楽データファイルのフルパス名が入ります
'============================================================
'再生
Call mciSendString("play " & strSoundFile, "", 0, 0)
'リピート再生
Call mciSendString("play " & strSoundFile & " repeat", "", 0, 0)
'停止
Call mciSendString("stop " & strSoundFile, "", 0, 0)
'一時停止
Call mciSendString("pause " & strSoundFile, "", 0, 0)
'一時停止解除
Call mciSendString("resume " & strSoundFile, "", 0, 0) |
- 再生できる音楽データはwavとmp3です。ファイルサイズからmp3を使う機会が多そうです。ちなみに第2,第3引数は戻り値を受け取る変数と、そのサイズを書きます。単に再生/停止といった操作だと使用しません。
ファイルパスに空白がある時: きちんとopenそしてclose
- しかしですね...、サウンドファイルの置かれた場所やファイル名に「空白」が含まれる場合、先に示した方法では操作ができません。対応方法ですが下記の「全て」が必要です。
- ファイルパス名をダブルクォーテーション(")で囲む
- 再生前にopenする
- 停止後はcloseする
- 例えばサウンドファイルのフルパスが下記のように「空白」を持つ場合です(2021 と 1120 の間)。
C:\sounds\dir2021 1120\bgm_sound.mp3
- この文字列をダブルクォーテーションで囲みます。そして、再生(play)前に必ずopenします。下記のコードを見るとopenしなくてもplayできそうに見えますが、やってみるとplayできません。わかりにくい...。
Dim strSoundFile As String
strSoundFile = "C:\sounds\dir2021 1120\bgm_sound.mp3"
'再生前にopenする。その際ダブルクォーテーションで囲む
'ダブルクォーテーションが4つなのは、エスケープの「"」と本物の「"」を文字列として「"」で囲んでいるから
Call mciSendString("open " & """" & strSoundFile & """", "", 0, 0)
'ファイルの置き場所表現にはaliasも使えるが、わかりやすさのために直書き
'open後再生(play)する
Call mciSendString("play " & """" & strSoundFile & """", "", 0, 0) |
- そして次は停止ですが、停止後に必ずcloseします。closeしないと再度open/playができません。これもわかりにくい...。
Dim strSoundFile As String
strSoundFile = "C:\sounds\dir2021 1120\bgm_sound.mp3"
'stopする。
Call mciSendString("stop " & """" & strSoundFile & """", "", 0, 0)
'stop後closeする
Call mciSendString("close " & """" & strSoundFile & """", "", 0, 0) |
ファイルパスに空白がある時: いつstop & close ... もう、いいかな
- サウンドを扱うAPIのmciSendStringですが非同期実行です。したがって短い曲を再生する場合でも、その曲の再生時間分を待ってからstop & closeする必要があります。
- サウンドの再生時間はstatusコマンドで取得できますが、その待ち時間の間ExcelをずっとWaitさせるわけにもいかず、Application.OnTimeを使ったりするわけですが、ここまで来ると労力と効果のバランスがかなり悪く(*3)なります。
- もうテンポラリ領域にサウンドファイルをコピーして、パス名の制約を取り払う方がシンプルだと思い始めています。Bookオープン時とファイル決定時にテンポラリファイル名決めつつコピーするのです。
- う〜ん。またテンポラリファイルを使うという結論になってしまいました。前回もそうだったので2回連続です。まだ私はVBA初心者なんだな...。まぁ、これからも頑張って覚えていきます。良い手が見つかったら追記しようと思います。
- あと、mciSendStringを使用したVBAサンプルはこちら(sample_2021_0110.zip)になります。
|