• ベストアンサー

EXCEL VBAでApplication.waitを使わずに一時停止させたい

マクロの実行中に、その処理を、条件分岐によってある一定時間だけ止めて、また再開させるようなプログラムを作りたいと考えています。 Application.Waitを使えば、可能というとこまではわかったのですが、それだとマクロ停止中にEXCEL上での一切の操作(たとえばスクロール)ができなくなるので、マクロだけ停止させておいて、他の操作はできるようなやり方はありませんでしょうか? ちなみに、当方の使用OSはXP、EXCELは2007です。VBAは、はじめて取り組む超初心者で、以下のコードもネットやこちらのサイトを探しまくって、ようやくここまでできました。 なお、本マクロで具体的にやりたいことは、楽天証券のRSSというアプリケーションから、EXCELの特定の列に、1行目から順番に、リアルタイムで株価が書き込まれていきます。その株価を監視して、ある一定以上になったら、音で知らせるということをやりたいのです。その際、株価が書き込まれていく間隔は、数秒~数分です。 長々と書きましたが、ご教授いただけると助かります。 <参考:現在のマクロ> Sub Test() Dim waitTime As Variant Dim 繰り返し As Long For 繰り返し = 1 To 10 If Cells(繰り返し, 1).Value >= 10000 Then Shell "mplay32.exe /play /close C:\WINDOWS\Media\notify.wav" ElseIf Cells(繰り返し, 1).Value = Empty Then waitTime = Now + TimeValue("0:00:05") Application.Wait waitTime End If Next 繰り返し End Sub

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

  • ベストアンサー
  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.3

こんばんは。 Microsoft のサポートには、そのものズバリの内容がありますが、少し古い内容です。実際、以下のプロパティで、楽天RSSの前バージョン(約2年前)では私は成功していますが、現行ツールでは知りません。RSSは、バージョンがあがりました。 http://support.microsoft.com/support/excel/content/onevent/onevent.asp?SD=gn&LN=ja&gssnb=1#ondata それから、外部ツールを使って、音を鳴らすのはあまり賛成しません。一応、書いておきますが、本来は、内部コマンドのBeep やパターンの色付けでよいと思います。 1番目の場合は、最初に、Auto_Open を実行してください。一旦、ファイルを閉じて、再び開いても自動的に設定されています。 なお、Microsoft サポートの注にも書かれていますが、DDEやOLEではない場合に、ハンドラーが取れないこともあります。その場合は、OnEntry や Change イベントを使用してください、と書かれています。つまり、1番のマクロは、データがインポートされたときにのみ、起動するマクロです。ともかく、最初のマクロだけでも試してみてください。まだ、そういう古い方式が可能なのか、こちらでも知りたいのです。 ----------------------------------------- '標準モジュール 'Option Explicit Private Declare 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 '一旦、閉じて開くか、最初に実行してください。 Sub Auto_Open()  '実際のシート名を入れてください。  Worksheets("Sheet1").OnData = "Test1" End Sub Sub Test1()   Dim i As Long   Dim rt As Long   Static j As Long   Const sSOUND As String = "C:\WINDOWS\Media\notify.wav"   i = Cells(Rows.Count, 1).End(xlUp).Row   If i <> j Then     If Cells(i, 1).End(xlUp).Value > 10000 Then       rt = mciSendString("Play " & sSOUND, "", 0, 0)       'Beep 'ビープ       'Cells(Rows.Count, 1).End(xlUp).Interior.ColorIndex = 34 '色づけ     End If   End If   j = i End Sub ------------------------------------- OnTime メソッドを使う場合は、LastTime を数秒の間の設定をしたほうがよいです。LastTime を入れないと、待機状態の後に、立て続けに、マクロの起動をしてしまい意味のないものになってしまいます。また、行数が単にインクリースしても、そこにデータがなければ、意味のないチェックになってしまいますから、必ず、実際に存在するデータに連動していなければなりません。また、データが増えなければ、チェックはしません。 以下の場合は、ワークシートの作業中とマクロのデータチェックがぶつかった場合は、作業のほうが必ず優先しますが、その待機状態は、数秒間しかありません。その時に無視したデータは、次のマクロで必ずフォローするように出来ています。なお、色づけとBeep という方式になっていますから、色づけが嫌いなら、コメントブロック(')を入れてください。 一列の最後尾に、文字「Q(大文字・小文字共通)」を入れれば、それで終了します。 ------------------------------------------ '標準モジュール 'Option Explicit Sub TimerMacro()   Dim i As Long '行   Dim n As Long   Dim myTime As Date Static j As Long   '----------------------------------   'チェックする値を以下に入れてください。   Const MYLIMIT As Long = 10000   '----------------------------------   i = Cells(Rows.Count, 1).End(xlUp).Row   '終了は、Q を入れる   If StrComp(Cells(i, 1).Value, "Q", 1) = 0 Then    MsgBox "終了しました。", 64    Exit Sub   End If   If i > j And j > 0 Then     For n = j To i       '上限を超える場合       If Cells(n, 1).Value > MYLIMIT Then         Cells(n, 1).Interior.ColorIndex = 34 '水色         Beep '音       End If     Next n   ElseIf j = 0 Then        If Cells(i, 1).Value > MYLIMIT Then         Cells(i, 1).Interior.ColorIndex = 34 '水色         Beep '音         End If   End If   j = i   myTime = Now + TimeSerial(0, 0, 5) '5秒   Application.OnTime myTime, "TimerMacro", myTime + TimeSerial(0, 0, 2) '待機2秒 End Sub ----------------------------------------

system225
質問者

お礼

Wendy02様 ご丁寧なアドバイス、ありがとうございます。 Wendy02様も以前同様なことを、楽天RSSでなされていたのですね。 さて、頂いたアドバイスをもとに、RSSにはつながずテスト環境で試そうと試みたのですが、この場合はDDEではないため、OnEntryやChangeイベントを使用とのことで、恥ずかしながら、まだそこまでの知識が不足しており、上手くテストできておりません。 幸い週末ですので、VBAの学習しつつ、頂きましたサンプルマクロをテストさせて頂きます。うまく進めば、楽天RSSが使用できる月曜以降に本番環境でテストしてみますので、またその結果をご報告させていただきたいと存じます。 取り急ぎお礼まで。 ありがとうございました。

その他の回答 (2)

  • fujillin
  • ベストアンサー率61% (1594/2576)
回答No.2

ユーザに一旦制御を返すということのようなので、マクロを一度中断させる(終了させる)ようなコードにしておく必要があります。一定時間経過後に(続きを)実行させれば可能です。 ごく簡単な、サンプルを・・ 5秒おきにA1セルの値を1増加します。(中断するには、A1セルに文字を入れてエラーを起こさせるか、Ctr+Breakなど) マクロを一度抜け出しますので、実際の計算では(もっと複雑でしょうから)、その間にセルの内容が変わったり(ユーザが変える)することも考慮して、また、独立で実行可能なマクロを作成する必要がありますので、ご注意ください。 Sub sample() Cells(1, 1) = Cells(1, 1) + 1 Application.OnTime Now + TimeValue("00:00:05"), "ThisWorkbook.sample" End Sub

system225
質問者

お礼

fujillin様、 早速のアドバイスありがとうございます。 このやり方ですと、私の場合は条件式以下に、 Application.OnTime~ 以下を挿入するということだと理解いたしました(違ってますでしょうか?)。 早速試してみます。 誠にありがとうございました。

  • cj_mover
  • ベストアンサー率76% (292/381)
回答No.1

こんにちは 他にもありますが、比較的簡単な方法のサンプルです。 お使いのアプリケーションとの兼ね合いでお望み通り機能するか、 私にはわかりませんので、試しに、ということで。 Sub TEST() Dim tm As Single tm = Timer() + 5 Do DoEvents Loop While Timer() < tm MsgBox "5秒経過" End Sub

system225
質問者

お礼

cj_mover様、 早速のアドバイスありがとうございました。 助かりました。 ただ、このマクロを組み込んで実行したところ、メッセージボックスで毎回ボタンを押さないと、マクロはずっと止まったままになるのですね。 不在(監視していない)の時は、自動的にメッセージボックスが閉じて、マクロが再開されるような方法を、ネットで調べてみます。 今回はありがとうございました。

関連するQ&A

  • vba 初心者

    Dim a As Integer Dim inbox As String Dim Localpath As Variant Dim c As Range, myFadd As String Dim flag As Variant Dim MyShell As Object Dim Mysh As String Dim newHour As Variant Dim newMinute As Variant Dim newSecond As Variant Dim waitTime As Variant Localpath = ThisWorkbook.Path a = 1 inbox = InputBox("番号") Do If inbox = Empty Then Exit Sub End If If inbox = Cells(a, 1) Then MsgBox ("あります") Exit Do Else a = a + 1 ElseIf Cells(a, 1) <> inbox Then MsgBox ("ない") End If Loop Set MyShell = CreateObject("WScript.Shell") MyShell.Run ("AcroRd32.exe /n") MyShell.Run ("AcroRd32.exe /p") & Localpath & "\" & Myfile & ".pdf" newHour = Hour(Now()) newMinute = Minute(Now()) newSecond = Second(Now()) + 10 waitTime = TimeSerial(newHour, newMinute, newSecond) Application.Wait waitTime Application.SendKeys "{Enter}", True '次の使用例は、10 秒を過ぎるとメッセージを表示します。 If Application.Wait(Now + TimeValue("0:00:10")) Then MsgBox "時間が過ぎました。" End If End Sub ExcelからPDFファイルを検索して印刷したいのですが、 見よう見まねで作ってみたもののエラーが出てしまってよく分かりません。 指摘できるところご指導よろしくお願いします。

  • Excel VBAについて

    早速ですがExcelVBAについて質問です。 年齢がN列にあるとき、M列に年代を入れたいと思います。(例:19才なら10代、30才なら30代) 以下のように作成しましたが、すべてに20と入ったり正常に動作しないときがあります。 Excelは2003で作成していますが、いずれ2007でも使いたいです。 もっと正確に実行できるコードを教えてください。 ワークシート関数での解決は望んでいません。データ数も多く他の作業もマクロで処理するのでマクロを希望しています。よろしくお願いします。 -------------------------- Sub ByAge() Range("N1").Value = "年代別" Dim i As Long, N As Integer For i = 2 To Cells(Rows.Count, 1).End(xlUp).Row If Cells(i, 13).Value >= 60 And Cells(i, 13).Value < 70 Then Cells(i, 14).Value = 60 ElseIf Cells(i, 13).Value >= 50 And Cells(i, 13).Value < 60 Then Cells(i, 14).Value = 50 ElseIf Cells(i, 13).Value >= 50 And Cells(i, 13).Value < 60 Then Cells(i, 14).Value = 40 ElseIf Cells(i, 13).Value >= 30 And Cells(i, 13).Value < 40 Then Cells(i, 14).Value = 30 ElseIf Cells(i, 13).Value >= 20 And Cells(i, 13).Value < 30 Then Cells(i, 14).Value = 20 End If Next i MsgBox "完了!" End Sub --------------------------

  • vba初心者

    いつもお世話様です。 A列にあらかじめデータを入れといてinboxでデータを検索してもしあったらPDFファイルを開いて印刷でもしデータがなかったらinboxに戻るかたちにしたいんですけど、do...loopの使い方が分からないのと、デバックがでてしまってどう直せばいいかわかりません。サンプルコードがあれば助かります。よろしくお願いします。 Dim a As Integer Dim inbox As String Dim Localpath As Variant Dim c As Range, myFadd As String Dim flag As Variant Dim MyShell As Object Dim Mysh As String Dim newHour As Variant Dim newMinute As Variant Dim newSecond As Variant Dim waitTime As Variant Localpath = ThisWorkbook.Path a = 1 inbox = InputBox("番号") Do If inbox = Empty Then Exit Sub End If If inbox = Cells(a, 1) Then MsgBox ("あります") Exit Do Else a = a + 1 ←ここでデバックがでてしまいます。 ElseIf Cells(a, 1) <> inbox Then MsgBox ("ない") End If Loop Set MyShell = CreateObject("WScript.Shell") MyShell.Run ("AcroRd32.exe /n") MyShell.Run ("AcroRd32.exe /p") & Localpath & "\" & Myfile & ".pdf" newHour = Hour(Now()) newMinute = Minute(Now()) newSecond = Second(Now()) + 10 waitTime = TimeSerial(newHour, newMinute, newSecond) Application.Wait waitTime Application.SendKeys "{Enter}", True '次の使用例は、10 秒を過ぎるとメッセージを表示します。 If Application.Wait(Now + TimeValue("0:00:10")) Then MsgBox "時間が過ぎました。" End If End Sub

  • エクセルVBAのApplication.Wait Now()について

    皆様こんにちは 温度計を導入しまして、リアルタイムに温度を取り込むアドインがついていました。いまsheet1のA1からG1まで次々値が変化するセルがあります。 そこで10秒おきにA1からG1までの値だけを2列下にコピーするコードを実行してみたのですが・・・ '----------------------------- Sub 一定秒おきに実行() Dim i As Integer Static k For i = 1 To 5 If k = "" Then k = 2 Application.Wait Now() + TimeValue("00:00:01") DoEvents 下に数値のみを貼り付ける Next End Sub '--------------------------------------- Sub 下に数値のみを貼り付ける() Range("A1:G1").Select Selection.Copy Range("A3:G3").Select Selection.PasteSpecial Paste:=xlPasteValues End Sub '-------------------------------------- その結果 Sub 下に数値のみを貼り付ける()をVBエディタの標準ツールバーの実行をクリックするたびにリアルタイムに値がコピーされるのですが、Sub 一定秒おきに実行()を実行すると、画面が5回ちらつくのでコピーはされてるみたいですがマウスポインタが砂時計になって、その間アドインからの数値の更新も止まってしまいます。 Application.Wait だけにマクロが停止していると思いますが、これには大変困ってしまっています。 マクロをとめないで一定時間置きに "Sub 下に数値のみを貼り付ける()"を実行する方法はないでしょうか。 よろしくお願いします。

  • EXCEL VBA

    EXCEL VBAで空白行が現れたら「小計」の文字を入力したいと思い以下のように記述しましたが、うまくいきません。どこがおかしいのか教えてください。 宜しくお願いします。 Sub write小計() Dim i As Integer Dim rowcnt As Integer rowcnt = Cells(1, 1).CurrentRegion.Rows.Count Range("B1").Select For i = 1 To rowcnt If Cells(i, 2).Value = "" Then Value = "小 計" ActiveCell.Offset(1).Select Next i End Sub

  • Excel VBA ・・・教えてください

    何度も質問させて頂いてます。すみません、 下記のプログラムはこの場で教えて頂いたプログラムで、 実行すると●の後を▲や■が追いかける動きをします。 下記のプログラムをある程度使用して 1~20の数字が順々で追いかけっこする プログラムを作成するにはどのようにすればいいのでしょうか… できればプログラムは長めにならず 20の数字から簡単に増やすことのできるような そんなプログラムが作成したいです… どなたかアドバイスお持ちの方 教えて下さいお願いします... Dim time1 As Integer, time As Integer Dim X As Integer, Y As Integer Dim X1 As Integer, Y1 As Integer Dim X2 As Integer, Y2 As Integer Dim maru As String, yoko As String, tate As String Dim sankaku As String, shikaku As String Sub 描画() Cells(Y2, X2).Value = shikaku Cells(Y1, X1).Value = sankaku Cells(Y, X).Value = maru End Sub Sub 削除() Cells(Y2, X2).Value = "" End Sub Sub 待機() For time1 = 0 To 1000 For time2 = 0 To 1000 Next Next End Sub Sub 座標移動() X2 = X1 Y2 = Y1 X1 = X Y1 = Y If yoko = "右" Then X = X + 1 Else X = X - 1 End If If X = 30 Then yoko = "左" ElseIf X = 1 Then yoko = "右" End If If tate = "上" Then Y = Y + 1 Else Y = Y - 1 End If If Y = 20 Then tate = "下" ElseIf Y = 1 Then tate = "上" End If End Sub Sub main() maru = "●" sankaku = "▲" shikaku = "■" X = 1 Y = 1 X1 = 1 Y1 = 1 X2 = 1 Y2 = 1 yoko = "右" tate = "上" Do 描画 待機 削除 待機 座標移動 Loop End Sub

  • EXCEL VBAについて

    EXCEL VBAについて教えてください やりたいことは以下の通りです。 ・全シートJ列1~100行目を検索しアルファベットが含まれるセルが存在すれば 上のセルをコピーする ここまで作ったのですが上手くいきません Sub VBAsample() Dim GYO As Long For GYO = 1 To 100 If Find([a-z], LookAt:=xlPart) Then Cells(GYO, 10).Value = Cells(GYO - 1, 10).Value End If Next GYO End Sub 添削をお願いします

  • エクセル VBA 自動処理の途中終了について

    エクセルで単語のフラッシュカードを自動表示させたいと考えています。 エクセルの1セルの大きさを縦最大、横120位に広げ、C列に単語、D列に意味を縦に並べ、 C2 1秒後 D2 1秒後 C2 1秒後 D2 1秒後  C3 1秒後 D4 のように単語と意味を交互に2度ずつ表示させます。 For Next を使い表示はできるようになりましたが、途中で止めたいときに、escを押すと For Nextの処理を最後まで一気に行ってから止まってしまいます。 C5を表示していたら、その場所でPause をし、スタートボタンで再度継続して表示したいと思います。また、単語や意味のセルにはそれぞれ別の文字装飾をしてあるので、(赤や青、大きさなど) セルを移動して表示したいと考えています。 実は他のサイトでも質問しましたが、思ったような回答を得られませんでした。よろしくお願いします。 Sub セル移動() Dim waitTime As Variant i = 0 Range("c2").Select waitTime = Now + TimeValue("0:00:01") Application.Wait waitTime Range("c3").Select waitTime = Now + TimeValue("0:00:01") Application.Wait waitTime For i = 1 To 50 ActiveCell.Select Selection.Offset(0, 1).Select waitTime = Now + TimeValue("0:00:01") Application.Wait waitTime Selection.Offset(0, -1).Select waitTime = Now + TimeValue("0:00:01") Application.Wait waitTime Selection.Offset(0, 1).Select waitTime = Now + TimeValue("0:00:01") Application.Wait waitTime Selection.Offset(1, -1).Select waitTime = Now + TimeValue("0:00:01") Application.Wait waitTime Application.OnKey ("{esc}"), "shuryo" i = i + 1 Next i End Sub Sub shuryo() Application.ScreenUpdating = False Range("c2").Select Application.GoTo reference:=ActiveCell, scroll:=True Application.ScreenUpdating = True Exit Sub End Sub

  • 【VBA】sleepかwaitをどこに書き込めば

    ExcelでWebスクレイピングを行うための、VBAのソースをご教示頂きました。 過去の質問|https://okwave.jp/qa/q9420082.html このソースは完璧に動くのですが、googleに負荷を掛けてしまい、100件ほど抽出するとエラーが出て使えなくなってしまいます。 そこでsleepやwaitを使って、間隔を空けて実行させたいと考えています。 以下のどの部分に追加すれば良いのか、教えてください! お願い致します。 ――――――――――――――――――― ' Option Explicit ' Sub Macro1() '   Dim SheetW As Worksheet   Dim SheetO As Worksheet   Dim Start As Integer   Dim URL As String   Dim NowCell As String   Dim RowI As Integer   Dim RowO As Integer   Dim RowEnd As Integer   Dim Col As Integer   Dim ColEnd As Integer '   Set SheetO = ActiveSheet   [A10:C10] = Array("番号", "URL", "説明")   [A11:C1048576].Clear   Set SheetW = Sheets.Add   SheetW.Name = "Webクエリ"   RowO = 11   ColEnd = [A5].End(xlToRight).Column '   For Start = SheetO.[B2] To SheetO.[C2] Step SheetO.[D2] DoEvents     URL = SheetO.[B1] & SheetO.[C1] & SheetO.[D1] & Start     With ActiveSheet.QueryTables.Add( _       Connection:="URL;" & URL, _       Destination:=[A1])       .Name = "Google検索結果"       .WebSelectionType = xlEntirePage       .WebFormatting = xlWebFormattingAll       .BackgroundQuery = False       .Refresh     End With '     With SheetO     RowI = [A:A].Find(.[B3]).Row + 1     RowEnd = Cells(Rows.Count, "A").End(xlUp).Row     While Not Cells(RowI, "A") Like .[B4] And _        RowI < RowEnd       NowCell = Cells(RowI, 1) '       For Col = 2 To ColEnd '         If NowCell Like .Cells(5, Col) Then           Exit For         End If       Next Col '       If Cells(RowI, 1).Hyperlinks.Count > 0 And Col > ColEnd Then         .Cells(RowO, "A") = RowO - 10         .Cells(RowO, "C") = NowCell         NowCell = Cells(RowI, "A").Hyperlinks(1).Address '        SheetO.Cells(RowO, "B") = NowCell         .Hyperlinks.Add Anchor:=.Cells(RowO, "B"), _           Address:=NowCell, _           TextToDisplay:=NowCell         RowO = RowO + 1       End If       RowI = RowI + 1     Wend     End With   Next Start ' "Webクエリ"シート削除   Application.DisplayAlerts = False   SheetW.Delete   Application.DisplayAlerts = True End Sub

  • EXCEL VBA 

    Excel VBAで アンケート集計をしたいと思い、プログラムを作ったのですが、J列までは入力がうまくいくのですが、K列にデータを入れて次の行にデータを入れると もともと存在していたKれつのデータが消えてしまします。 どう修正すれば ちゃんとデータが残ってくれるのでしょうか?  誰か教えてください Option Explicit Private Sub UserForm_Initialize() Dim チェックボックス As Control With cboBlood .AddItem "A型" .AddItem "B型" .AddItem "O型" .AddItem "AB型" End With cboBlood.ListIndex = -1 txtNo.Value = WorksheetFunction.Max( _ [Database].Resize(, 1)) + 1 txtNo.Enabled = False txtName.Text = "" optMale.Value = True txtAge.Value = 0 For Each チェックボックス In fraOS.Controls チェックボックス.Value = False Next txtName.SetFocus End Sub Private Sub cmdEntry_Click() Dim 行 As Long Dim 確認 As Integer 確認 = MsgBox("データを登録します。" _ & "よろしいですか?", vbYesNo) If 確認 <> vbYes Then Exit Sub 行 = [Database].Rows.Count + 1 [Database].Cells(行 - 1, 1).EntireRow.Insert [Database].Offset(行 - 1).Resize(1).Copy _ [Database].Cells(行 - 1, 1) [Database].Offset(行 - 1).Resize(1).ClearContents [Database].Cells(行, 1) = txtNo.Value [Database].Cells(行, 2) = txtName.Text If optMale.Value = True Then [Database].Cells(行, 3) = "男性" Else [Database].Cells(行, 3) = "女性" End If [Database].Cells(行, 4) = cboBlood.Text [Database].Cells(行, 5) = txtAge.Value If chkWin.Value = True Then _ [Database].Cells(行, 6) = "○" If chkMac.Value = True Then _ [Database].Cells(行, 7) = "○" If chkLinux.Value = True Then _ [Database].Cells(行, 8) = "○" If chkOther.Value = True Then _ [Database].Cells(行, 9) = "○" If chkOther.Value = True Then _ [Database].Cells(行, 10) = "○" Unload frmNew End Sub Private Sub cmdCancel_Click() Unload frmNew End Sub

専門家に質問してみよう