VBAで条件に応じて音を鳴らす方法

このQ&Aのポイント
  • VBAを使用して、セルの値に応じて音を鳴らす方法について解説します。
  • 特定のセルの値を参照して条件を満たすと音が鳴るが、別の式と参照している場合はどうすればいいかについても説明します。
  • また、IF関数を使用してセルの値が特定の条件を満たした場合に音を鳴らす方法についても解説します。
回答を見る
  • ベストアンサー

VBA Changeの記述方法

あるセルの計算結果次第で音を鳴らすという事をやりたいです。 Private Sub Worksheet_Change(ByVal Target As Range) If Target.Address(False, False) = "B1" Then If Range("B1") > Range("A1") Then Shell "C:\Program Files\Windows Media Player\wmplayer.exe C:\音楽ファイル.wav", 0 End If End If End Sub この内容で、B1とA1に直接、数値を入れて条件を満たすと音が鳴るのですが、B1とA1がそれぞれ別のセルの値を参照している式にすると音が鳴らないのですが、そのような場合はどうすればいいでしょうか。 現在、B1セルは=B10を参照して、A1は=A10を参照する式になっています。 また、あるセルに =IF(H34<G34,"",IF(H34=G34,"同","★")) という式を入れて、このセルが★になった場合に上記と同様に音を鳴らしたいのですが、その場合はどのような記述にすればよいのでしょうか。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

同じような処理を色んなところで書く場合には・・・。私なら、【標準モジュール】に次のような関数を用意します。 =Comparison(Range1, Range2, "未満,等しい,超える,空値") Comparison()は、Range1とRange2のどちらかが変更されると呼ばれます。そして、二つのセルの値を比較して呼応する値を戻します。同関数を用いれば =IF(H34<G34,"",IF(H34=G34,"同","★"))  ↓ =Comparison(H34, G34, "★,同,★", "同") と書く事ができます。音楽は戻り値が"同"の場合のみ鳴ります。 Option Explicit Public Function Comparison(ByVal R1 As Range, ByVal R2 As Range, ByVal returnText As String, ByVal isMusic As String) As String   Dim returnValue As String      'string1はstring2未満 -1   'string1とstring2は等しい 0   'string1はstring2を超える 1   'String1またはstring2はNull値 Null値   If Len(R1 & "") * Len(R2 & "") = 0 Then     returnValue = CutStr(returnText, ",", 4)   Else     Select Case StrComp(R1, R2, vbTextCompare)       Case -1         returnValue = CutStr(returnText, ",", 1)       Case 0         returnValue = CutStr(returnText, ",", 2)       Case 1         returnValue = CutStr(returnText, ",", 3)       Case Else         returnValue = ""     End Select   End If   If returnValue = isMusic Then     ' 音楽 End If   Comparison = returnValue End Function Public Function CutStr(ByVal Text As String, _             ByVal Separator As String, _             ByVal N As Integer) As String   Dim strDatas() As String      strDatas = Split("" & Separator & Text, Separator, , 0)   CutStr = strDatas(N * Abs(N <= UBound(strDatas))) End Function

don-naldo
質問者

補足

詳細なプログラムを記述していただきありがとうございました。 私には分からない事だらけですが =IF(H34<G34,"",IF(H34=G34,"同","★")) この関数がセルC1にあるとすると、教えていただいたプログラムのどこにそのセルC1を記述すればよいのでしょうか。 あと、R1とR2にはどこか該当するセルを指定する必要がありますか。 また、音楽を鳴らすための Shell "C:\Program Files\Windows Media Player\wmplayer.exe C:\音楽ファイル.wav", 0 という記述は If returnValue = isMusic Then この下に書けばいいのでしょうか。例えば、最初のご回答のように MsgBox "XXX" を出す場合の位置も If returnValue = isMusic Then の下あたりでしょうか。

その他の回答 (6)

回答No.7

【補足】Target.Address(False, False)に関して Excelを触るのは始めてですので私も知りませんでしたが、イミディエイトウインドウで確認した結果では、相対アドレスを戻すのか?それとも絶対アドレスを戻すのか?ということかと思いますよ。

don-naldo
質問者

補足

ご回答ありがとうございます。 イミディエイトウインドウというもので確認できるのですね。勉強になりました。 ありがとうございました。

回答No.6

  If returnValue = isMusic Then     Shell "C:\Program Files\・・・音楽ファイル.wav", 0   End If   NumComparison = returnValue End Function Comparison = returnValue   ↓ NumComparison = returnValue 回答自体では修正しているので単なる誤記と思われるでしょうが。念の為に!

回答No.5

C1のセルに =NumComparison(H34, G34, "★,同,★", "同") 音楽を鳴らすコードは   If returnValue = isMusic Then     Shell "C:\Program Files\・・・音楽ファイル.wav", 0   End If   Comparison = returnValue End Function でOKかと思います。 なお、 Public Function StrComparison(ByVal R1 As Range, _               ByVal R2 As Range, _               ByVal returnText As String,               Optional ByVal isMusic As String="") As String と、音楽を鳴らす指示を書かなくて済むように4番目の引数をオプションにしておくと汎用性が確保されるかとも思います。

回答No.4

【注意】の内容は、余りにも不親切だと思って・・・ 数字と文字列とを比較するそれぞれの関数は以下のようです。まあ、Excel用の関数なんて生まれて始めてのど素人のやっつけ仕事。十分にテストされてご利用、ご改変ください。 Public Function StrComparison(ByVal R1 As Range, ByVal R2 As Range, ByVal returnText As String, ByVal isMusic As String) As String   Dim returnValue As String     If Len(R1 & "") * Len(R2 & "") = 0 Then     returnValue = CutStr(returnText, ",", 4)   Else     Select Case StrComp(R1, R2, vbTextCompare)       Case -1         returnValue = CutStr(returnText, ",", 1)       Case 0         returnValue = CutStr(returnText, ",", 2)       Case 1         returnValue = CutStr(returnText, ",", 3)       Case Else         returnValue = ""     End Select   End If   If returnValue = isMusic Then     ' 音楽   End If   StrComparison = returnValue End Function Public Function NumComparison(ByVal R1 As Range, ByVal R2 As Range, ByVal returnText As String, ByVal isMusic As String) As String   Dim returnValue As String     If Len(R1 & "") * Len(R2 & "") = 0 Then     returnValue = CutStr(returnText, ",", 4)   Else     Select Case NumComp(R1, R2)       Case -1         returnValue = CutStr(returnText, ",", 1)       Case 0         returnValue = CutStr(returnText, ",", 2)       Case 1         returnValue = CutStr(returnText, ",", 3)       Case Else         returnValue = ""     End Select   End If   If returnValue = isMusic Then     ' 音楽   End If   NumComparison = returnValue End Function Public Function NumComp(ByVal V1 As Double, ByVal V2 As Double) As Integer   Dim R As Integer   If V1 < V2 Then     R = -1   ElseIf V1 = V2 Then     R = 0   ElseIf V1 > V2 Then     R = 1   End If   NumComp = R End Function Public Function CutStr(ByVal Text As String, _             ByVal Separator As String, _             ByVal N As Integer) As String   Dim strDatas() As String     strDatas = Split("" & Separator & Text, Separator, , 0)   CutStr = strDatas(N * Abs(N <= UBound(strDatas))) End Function

回答No.3

【注意】比較が数字の場合は128の長さで右詰めするなどの工夫が必要かもしれません。その工夫に腐心するようでしたら、数字比較関数、文字列比較関数の二つを用意されるのも手です。

don-naldo
質問者

補足

ありがとうございました。文字列比較関数で調べたらEXACT関数というのを見つけました。これを使って以下のような記述をしたらうまく出来ました。 Private Sub Worksheet_Change(ByVal Target As Range) If Target.Address(False, False) = "H9" Then If Range("Q9") = "True" Then Shell "C:\Program Files\Windows Media Player\wmplayer.exe C:\音楽ファイル.wav", 0 End If End If End Sub ただ、上記の記述もサイトなどで調べて見よう見まねでコピーしたものなので、以下の意味が理解できていません。 If Target.Address(False, False) = "H9" Then これは何を指定しているのでしょうか。Target.Addressで検索してもあまり理解できる説明が見つかりませんでした。 現在のExcelの記述はH9<G9より大きい場合にI9に★マークが表示されます。そして、Q9セルにEXACT関数を入れて、別のセルに予め入力してある★と比較するようにしています。G9は固定された数字であり、H9は変化する数字です。 If Target.Address(False, False) = "H9" Then この内容のH9を最初はQ9に変えたのですが、これだと★マークが表示されても音は鳴りませんでした。

回答No.1

Excelは触ったこともない門外漢ですが・・・ Option Explicit Private Sub Worksheet_Change(ByVal Target As Range)   Static A1 As Long   Static B1 As Long   Dim newA1 As Long   Dim newB1 As Long      newA1 = Val(Range("A1") & "")   newB1 = Val(Range("B1") & "")   If newB1 <> B1 Then     If newB1 > newA1 Then       MsgBox "XXX"       A1 = newA1       B1 = newB1     End If   End If End Sub 門外漢ですのでVal()での型変換が必要かどうかは不明。ですが、要は、「B1の値が変更された場合には・・・」というIF文を書けばよいのではと推察します。

don-naldo
質問者

補足

ご回答ありがとうございます。 教えていただいた方法をやってみたら出来ました。ありがとうございました。記述の中身はVBA初心者の私にはまだ理解できておりませんが、とりあえずこれでやりたい事は実現できるので、中身は丁寧に学んでいきます。 あと、質問内容の後半部分にある以下の件はいかがでしょうか。 >> また、あるセルに =IF(H34<G34,"",IF(H34=G34,"同","★")) という式を入れて、このセルが★になった場合に上記と同様に音を鳴らしたいのですが、その場合はどのような記述にすればよいのでしょうか。 >>

関連するQ&A

  • エクセルVBAの記述法(Worksheet_Changeで)

    入力があればセルが黄色のなり、入力がなければ無色とするマクロです。 Private Sub Worksheet_Change(ByVal Target As Range) If Target.Value <> "" Then Target.Interior.ColorIndex = 6 Else Target.Interior.ColorIndex = xlNone End If End Sub このように書くと、通常は正しく動きますが、ドラッグした場合や、複数セルを一度にクリアした場合、エラーになってしまいます。 ただしく作動させるにはどう直せばいいのでしょうか?

  • 2つのVBAを組み合わせる方法

    お世話になります、2つのVBAを組み合わせる方法で迷っています。 1つ目が Private Sub Worksheet_Change(ByVal Target As Range) Dim i As Long, k As Long, myNum As Long If Intersect(Target, Range("C1,B9:B39")) Is Nothing Or Target.Count > 1 Then Exit Sub Application.EnableEvents = False With Target If .Column = 3 Then myNum = WorksheetFunction.Max(Range("B9:B39")) If IsDate(.Value) Then For i = 9 To 39 If Cells(i, "A").Value = "" Then Cells(i, "B").Value = "" Else Cells(i, "B") = myNum + i - 8 End If Next i End If Else i = .Row If .Value = "" Then Range(Cells(i + 1, "B"), Cells(39, "B")).ClearContents Else For k = i + 1 To 39 If Cells(k, "A").Value = "" Then Cells(k, "B").Value = "" Else Cells(k, "B") = Cells(k - 1, "B") + 1 End If Next k End If End If End With Application.EnableEvents = True End Sub です。 2つめが Private Sub Worksheet_Change(ByVal Target As Range)  Application.EnableEvents = True If Intersect(Target, Range("R8:R38")) Is Nothing Then Exit Sub Application.EnableEvents = False Range(Cells(Target.Row, 18), Cells(39, 18)).Value = Target.Value Application.EnableEvents = True End Sub です。2つのPrivate Sub Worksheet_Change(ByVal Target As Range)イベントのVBAですが、どのようにして組み合わせれば良いのでしょうか?

  • エクセルVBA記述方法についての質問です。

    初心者です。色々調べるとVBAを使わないと下記の処理はできないみたいで・・・ わかる方がいれば是非教えて頂きたいです。 今回、毎日入力している数値に対して作業日付(更新日時)を残したいのですが、 例えば、A列のセルに数値を入力すると、入力したセルの右側のセル(この場合B列)に 日付と時間が残るようにしたいです。 Private Sub Worksheet_Change(ByVal Target As Range) If Target = Range("a1") Then Target.Cells(1, 2).Value = Now() End If End Sub 自分でも色々調べてやってみましたが、上記の記述だと、A1に入力すればB1に作業日時が残ります。 やりたいことはこれに限りなく近いのですが、対象入力範囲をA列にしたいです。 A列のどのセルに数値を入力しても、入力したセルの右側(B列)に作業日時を残していきたいです。 どのように記述すれば良いのかわからないので是非アドバイスを下さい。 よろしくお願い致します。

  • VBAでコードの編集が上手くいきません

    先日、ご回答頂いたコードを元に自分でいじっているのですが上手く行きません 自分が変更したコード シート1→シート名:変更箇所 Private Sub worksheet_change(ByVal Target As Excel.Range) If Target.Address <> "$C$40" Then Exit Sub If Target = "" Then Worksheets("リスト").AutoFilterMode = False: Exit Sub Worksheets("リスト").Range("A:C").AutoFilter field:=1, Criteria1:=Target.Value If Target.Address <> "$C$42" Then Exit Sub If Target = "" Then Worksheets("リスト").AutoFilterMode = False: Exit Sub Worksheets("リスト").Range("A:C").AutoFilter field:=1, Criteria1:=Target.Value If Target.Address <> "$C$44" Then Exit Sub If Target = "" Then Worksheets("リスト").AutoFilterMode = False: Exit Sub Worksheets("リスト").Range("A:C").AutoFilter field:=1, Criteria1:=Target.Value End Sub シート2→シート名:リスト Private Sub worksheet_change(ByVal Target As Excel.Range) Dim i As Long, c As Long Dim h As Range, ha As Range Dim myDic As Object Set ha = Application.Intersect(Target, Range("A:C")) If ha Is Nothing Then Exit Sub Set ha = Application.Intersect(ha.EntireColumn, Range("1:1")) For Each h In ha Set myDic = CreateObject("Scripting.Dictionary") If h.Column = 1 Then c = 3 'A列→C列 If h.Column = 2 Then c = 4 'B列→D列 If h.Column = 3 Then c = 6 'C列→F列 On Error Resume Next For i = 2 To Cells.SpecialCells(xlCellTypeLastCell).Row If Cells(i, h.Column) <> "" Then myDic.Add Cells(i, h.Column).Value, Cells(i, h.Column).Value End If Next i With Worksheets("変更箇所").Cells(40, c).EntireColumn.Validation .Delete .Add Type:=xlValidateList, Formula1:=Join(myDic.keys, ",") End With Set myDic = Nothing Next End Sub シート1において$C$40または$C$42または$C$44のいずれかを変更した場合 最後に変更したセルに対し、シート2にオートフィルタ―がかかる様にしたいと思っています。 試しにシート1を以下のように編集したところ、思った動作を行ったのですが $C$40または$C$42または$C$44のいずれかのセルを空白にすると エラーがでてしまいます。 Private Sub worksheet_change(ByVal Target As Excel.Range) If Target = "" Then Worksheets("リスト").AutoFilterMode = False: Exit Sub Worksheets("リスト").Range("A:C").AutoFilter field:=1, Criteria1:=Target.Value If Target = "" Then Worksheets("リスト").AutoFilterMode = False: Exit Sub Worksheets("リスト").Range("A:C").AutoFilter field:=1, Criteria1:=Target.Value If Target = "" Then Worksheets("リスト").AutoFilterMode = False: Exit Sub Worksheets("リスト").Range("A:C").AutoFilter field:=1, Criteria1:=Target.Value End Sub Then Exit Subをどう編集すれば上手く動作するでしょうか?

  • VBA/Worksheet_Changeがうまくいかない

    エクセル2000です。 以下のワークシートチェンジイベントがうまくいきません。 Targetに値が入る場合は問題ないのですが、TargetをクリアしてもRange("F5").MergeAreaがクリアされません。 Targetをクリアした後、TargetをダブルクリックしてからEnterキーを押せばRange("F5").MergeAreaがクリアされるのですが、いちいちそうさせるわけにもいきません。 どうしたらよいのでしょうか? Private Sub Worksheet_Change(ByVal Target As Range) If Target.Address <> "$C$5" Then Exit Sub If Target.Value <> "" Then Range("F5").Value = Range("D42").Value Else Range("F5").MergeArea.ClearContents End If End Sub

  • excel 2007 VBA コードの記述

    Excel 2007 を使用しています。 TEST.xlsm というブック内に テスト01 というシートを作成し、そのタブを右クリックして コードの表示 を選択。 表示されたVBAコード入力シートに下記のコードを記述して使用してます。 Private Sub Worksheet_Change(ByVal Target As Range) 'この行から If Intersect(Target, Range("E3:E33,G3:G33,AH3:AH33,AJ3:AJ33,BK3:BK33,BM3:BM33")) Is Nothing Or Selection.Count <> 1 Then Exit Sub Application.EnableEvents = False If Target <> "" Then If IsNumeric(Target) Then Target = Target - 23 End If End If Application.EnableEvents = True End Sub 'この行まで この条件に新たに下記のコードを追加したいと思い ネット検索しながらあれこれ試行錯誤してますが まだまだVBA初心者のため上手く機能してくれません。 ※上のコードだけなら思った通りに機能します。 Private Sub Worksheet_Change(ByVal Target As Range) 'この行から If Intersect(Target, Range("Y3:Y33,BB3:BB33,CE3:CE33")) Is Nothing Or Selection.Count <> 1 Then Exit Sub Application.EnableEvents = False If Target <> "" Then If IsNumeric(Target) Then Target = Target - 30 End If End If Application.EnableEvents = True End Sub 'この行まで どなたかこれら二種のコードを一つにまとめた記述方法を 教えて頂けますでしょうか?

  • この場合エクセルVBAでどう書けばいいでしょうか?

    あるシートのH列で、H21からH46のあいだで"False"がある行を非表示にしたいのです。 下記の冗長なマクロでもそうなりますが、For Nextというのを使うともっと簡潔に記述できると思うのですが、初心者のためよくわかりません。ご教示ください。 また、下記の式はシートが保護されていると働きませんが、保護したシートでも動く方法があればそれもあわせて教えていただけると幸いです。 エクセルは95です。 Sub 空白行非表示() G% = Sheets("見積書").Range("H48").Value With Sheets("見積書") Rows("19:47").RowHeight = G% If Range("H21") = False Then Rows("21").EntireRow.Hidden = True End If If Range("H22") = False Then Rows("22").EntireRow.Hidden = True End If If Range("H23") = False Then Rows("23").EntireRow.Hidden = True End If If Range("H24") = False Then Rows("24").EntireRow.Hidden = True End If 途中、繰り返しのため省略 If Range("H42") = False Then Rows("42").EntireRow.Hidden = True End If If Range("H43") = False Then Rows("43").EntireRow.Hidden = True End If If Range("H44") = False Then Rows("44").EntireRow.Hidden = True End If If Range("H45") = False Then Rows("45").EntireRow.Hidden = True End If If Range("H46") = False Then Rows("46").EntireRow.Hidden = True End If End With End Sub

  • 連続データのVBAの質問

    お世話になります。 Private Sub Worksheet_Change(ByVal Target As Range) Dim i As Long, k As Long, myNum As Long If Range("C1") <= Date - Day(Date) Then Exit Sub If Not Intersect(Target, Range("C1,B9:B39")) Is Nothing And Target.Count = 1 Then Application.EnableEvents = False With Target If .Column = 3 Then myNum = WorksheetFunction.Max(Range("B9:B39")) If IsDate(.Value) Then For i = 9 To 39 If Cells(i, "A").Value = "" Then Cells(i, "B").Value = "" Else Cells(i, "B") = myNum + i - 8 End If Next i End If Else i = .Row If .Value = "" Then Range(Cells(i + 1, "B"), Cells(39, "B")).ClearContents Else For k = i + 1 To 39 If Cells(k, "A").Value = "" Then Cells(k, "B").Value = "" Else Cells(k, "B") = Cells(k - 1, "B") + 1 End If Next k End If End If End With Application.EnableEvents = True ElseIf Not Intersect(Target, Range("R8:R38")) Is Nothing Then Application.EnableEvents = False Range(Cells(Target.Row, 18), Cells(39, 18)).Value = Target.Value Application.EnableEvents = True End If End Sub これはセルC1に年月を表記させ、そのC1セルの年月を変更した場合B9~B39のセルが自動で連続データの数字を記入し、B9~B39のどこかのセルを空白にすると、そのセル以降も空白になります。 そこで質問ですが、例えばB14の数字を消すとB15~39まで空白のセルになります。そして、B20に1と入力するとB21~39に連続データの数字が自動記入されます。 そしてC1の年月を次の月に更新した際は、B39で示された数字以降の連続データをB9に表示させるには、どうすれば良いでしょうか?

  • VBA CHANGEイベントに複数イベントを

    いつもお世話になっています。 色々しらべて試してみたんですが、うまくいかないんで教えてください。 CHANGEイベントに複数のイベントを書き込みたいんですが。 今現在、問題なく動いている以下のイベントがあります。 (1) Private Sub Worksheet_Change(ByVal Target As Range) Dim rang3 As Range Dim rang4 As Range Dim ■■ As String Dim LastRow1 As Long LastRow1 = Worksheets("○○").Cells(Rows.Count, "b").End(xlUp).Row Set rang4 = Worksheets("○○").Range("b:I" & LastRow) Set rang3 = Range("h4") If Intersect(Target, rang3) Is Nothing Then Exit Sub On Error Resume Next ■■ = WorksheetFunction.VLookup(Target.Value, rang4, 2, 0) If Err.Number > 0 Then MsgBox Target.Value & "はありません。基本情報台帳に入力してください。" Range("h4").Select Else Application.EnableEvents = False Range("I4").Value = Application.WorksheetFunction.VLookup(Target, Worksheets("△△").Range("b:I"), 2, False) Range("j4").Value = Application.WorksheetFunction.VLookup(Target, Worksheets("△△").Range("b:I"), 3, False) Range("k4").Value = Application.WorksheetFunction.VLookup(Target, Worksheets("△△").Range("b:I"), 7, False) Range("l4").Value = Application.WorksheetFunction.VLookup(Target, Worksheets("△△").Range("b:I"), 8, False) Range("m4").Value = Application.WorksheetFunction.VLookup(Target, Worksheets("△△").Range("b:I"), 5, False) Application.EnableEvents = True Range("K4").Select End If End Sub このシートにもう一つ、イベントを入れたいのですが。 (2) If Target.Count > 1 Then Exit Sub If Intersect(Target, Range("E4")) Is Nothing Then Exit Sub Else If Range("e4").Value = "1" Then Target.Offset(0, 19).Value = "☆" End If どこに入れればいいのかわかりません。 (3) また、(2)のイベントの他に、 (1)のVLOOLUPが実行され、尚且つ(2)のイベントのE4が値が1だった場合、Y4にH4の値を入れたいのですが・・・。 (2)のみなら動くことは確認できましたが、(1)のexit sub の直前に入れたり、end ifの前に入れたりしましたが、片方は動くが、もうひとつが動かないです。 (3)については、まったくわかりません。 マクロについて、自分でネットで勉強した程度なので、基本がわかっていないからなのでしょうが・・・。 どなたか、教えてください。 お願いします。

  • EXCEL VBA 指定した数字ごとに表示

    ・1から3までの数字をいれた場合に、9:00から11:00と表示する場合として以下のソースを書きます。(以前にこちらで教えていただきました) ・a = array()の部分について、直接書くのではなく、セルを参照することはできますでしょうか? a = array("cell(1,1)", "cell(1,2)", "cell(1,3)")みたいなイメージです。 よろしくお願い致します。 option base 1 private sub Worksheet_Change(byval Target as excel.range)  dim h as range  dim a as variant  a = array("9:0", "10:0", "11:0") ’1から3  on error resume next  for each h in application.intersect(target, range("D:D"))   if cells(h.row, "F") <> "○" then   if 1=< h.value and h.value <= 3 then  ’1から3   if time >= timevalue(a(h.value)) then    cells(h.row, "F") = a(h.value)   end if   end if   end if  next end sub

専門家に質問してみよう