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

このQ&Aのポイント
  • エクセルで単語のフラッシュカードを自動表示させる方法をまとめました。
  • For Next文を使用して単語と意味を交互に表示させる処理を実装しましたが、途中で止める方法がわかりません。
  • また、単語や意味のセルには異なる文字装飾がされているため、セルを移動して表示させる方法も探しています。
回答を見る
  • ベストアンサー

エクセル 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

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

  • ベストアンサー
  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.3

#2です。 コードの簡略化を図った際に次の行に移る箇所を間違っておりました。 Do~Loopの間は、下記の通り訂正願います。 また、参考URLを添付し忘れたので、添付いたします。 Do For i = 1 To 2 currentRange.Select Sleep 1000 currentRange.Offset(0, 1).Select Sleep 1000 DoEvents If stopFlag Then Sheets(2).Range("A1").Value = currentRange.Address Exit For End If Next i Set currentRange = currentRange.Offset(1, 0) Loop Until stopFlag

参考URL:
http://www.asahi-net.or.jp/~ef2o-inue/vba_o/sub05_090_050.html
issan55
質問者

お礼

mitarashi様 回答ありがとうございます。 currentRange.Addressをとりたいとは思っていたのですが、やり方がわかりませんでした。 2度ずつ繰り返すところまで再現していただき、ありがとうございます。 sleepやstopFlagなどもう少し勉強したいと思います。 無事に思い通りの作業ができました。

その他の回答 (4)

  • matsu_jun
  • ベストアンサー率55% (146/265)
回答No.5

ANo.4 の matsu_jun です。 下の方にある   If i i < 52 Then は、   If i < 52 Then の誤りでしたね。失礼いたしました。

  • matsu_jun
  • ベストアンサー率55% (146/265)
回答No.4

issan55さん、こんばんわ、ANo.1のmatsu_junです。 mitarashiさんの回答通り、 Sleepを組み込んだ上で、利用するのが一番良いようですね。 で、issan55さんの元のコードを極力変更しないよう、改造してみました。 '---------------------------ここから---------------------------- Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Sub セル移動()   Dim waitTime As Variant   Application.EnableCancelKey = xlErrorHandler   On Error GoTo ErrJob   'i = 0   Range("c2").Select   Sleep (1000)   Range("c3").Select   Sleep (1000)   For i = 1 To 50     ActiveCell.Select     Selection.Offset(0, 1).Select     Sleep (1000)     Selection.Offset(0, -1).Select     Sleep (1000)     Selection.Offset(0, 1).Select     Sleep (1000)     Selection.Offset(1, -1).Select     Sleep (1000)     i = i + 1   Next i ErrJob: If i i < 52 Then     If MsgBox("中断しますか?" & vbCrLf & "(OK:中断、キャンセル:再開)", vbOKCancel) = 2 Then Resume   End If   Range("c2").Select   Application.Goto reference:=ActiveCell, scroll:=True   Application.ScreenUpdating = True   Application.EnableCancelKey = xlInterrupt End Sub '---------------------------ここまで---------------------------- 作業中にEscキーを押すとダイアログが表示されます。 issan55 さんが、shuryo()でやりたかった処理は、通常に「セル移動」が終了した時と、中断ダイアログで終了させた時と、両方で実行されます。

issan55
質問者

お礼

matsu_junさん 再度のご回答ありがとうございます。 いろいろと勉強になります。 mitarashiさんのコードでうまく動きましたので、そちらを使わせていただきますが、 まだまだ素人ですので、コードをじっくり見させていただき、今後の参考にさせていただきます。 これからもよろしくお願いします。

  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.2

Application.Onkeyでうまくいかない理由は#1の方が解説して下さっているので、代替案です。 単語が一番左側のワークシートにあるとし、二番目のシートをセル位置の保存に使用しています。 ご質問には「ボタンで」といった記述もありますが、後学のためにEscキーのままで作成しております。 前回止まった位置を別シートに記録していますので、最初に戻すには別のプロシージャで消去する必要があります。 ご参考まで。 Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) Sub test() Dim currentRange As Range Dim i As Long Dim xlAPP As Application Dim stopFlag As Boolean On Error GoTo handleCancel Set xlAPP = Application xlAPP.EnableCancelKey = xlErrorHandler stopFlag = False If Sheets(2).Range("A1").Value = "" Then Set currentRange = Sheets(1).Range("C2") Else Set currentRange = Sheets(1).Range(Sheets(2).Range("A1").Value) End If Do For i = 1 To 2 currentRange.Select Sleep 1000 currentRange.Offset(0, 1).Select Sleep 1000 DoEvents If stopFlag Then Sheets(2).Range("A1").Value = currentRange.Address Exit For Else Set currentRange = currentRange.Offset(1, 0) End If Next i Loop While Not stopFlag xlAPP.EnableCancelKey = xlInterrupt Exit Sub handleCancel: If Err.Number = 18 Then stopFlag = True Resume Else MsgBox Err.Number & ":" & Err.Description Exit Sub End If End Sub

  • matsu_jun
  • ベストアンサー率55% (146/265)
回答No.1

issan55 さん、こんばんわ まずはプログラム中の、OnKeyコマンドについて解説していきましょう。 Application.OnKey ("{esc}"), "shuryo" という命令を実行したことで、一度Excelを終了し、再起動するまでは、Escキーを押した時に、shuryo という処理を実行することになります。(別のシートや別のブックを選択していてもです。) これは上記の通り、一度Excelを再立ち上げするか、別のマクロで Application.OnKey ("{esc}") という命令を実行するまでは戻りません。 この命令そのものは、プログラム(この場合は「セル移動」)の実行を、Escキーを利用して中断するという機能はありません。 あくまで他のプログラムが実行されていない時にEscキーを押せば、「shuryo」プログラムが実行されるよう定義したに過ぎません。 さて、Escキーは、基本的には現在の処理を中断するキーとして割り当てられているので、Application.Wait の処理実行中に Esc キーを押したら、以降Wait命令をキャンセルし、さらにマクロの実行中であれば、マクロの実行をキャンセル(確認メッセージは出ますが)します。 Escキーを押した時のこの動作は別の命令でキャンセルしない限り、有効であり続けます。 さて、そうすると、issan55さんは、Escキーに複数の機能を割りつけたことになります。 このことをより明確にするため、以下の実験を行なってみてください。 1) 最低一度「セル移動」を実行したあと新規ブックを開き、そこでEscキーを押してみてください。開いているブックの開いているシートのC2セルにカーソルが合うはずです。 2) 「セル移動」中の   For i = 1 To 50  の50を10000に変更して実行してみてください。  最初にEscを押したときは、セル移動のスピードが上がります。(Application.Waitがキャンセルされたため)  そのまますぐににEscを押してみてください。そのときは、開発画面に切り替わり、「コードの実行が中断されました」というダイアログが表示されるはずです。(「終了(E)」ボタンをクリックすれば終了します)  その後、再度Escを押すと、"shuryo"が実行され、C2セルが選択された状態に戻ります。 ソースを拝見させていただきますと、issan55様はまだVBAを利用し始めてからあまり経験が無いように見受けられますが、よくここまでのコードをお書きになったものと感心いたします。 ただし残念ながら、それなりに改造を施さないと、issan55様が期待するとおりの動作をさせるのは難しいと思います。 私としても、ちょっとすぐに思いつく方法だと、いずれにしても何らかの不都合(時間がバラつくなど)が出てきてしまいます。 また、現状の情報だけでは最適な方法を特定もできません。  ・Sub セル移動 プロシージャは何をきっかけに実行されているか?(画面上にボタンを置いたりしているのか?マクロメニューから実行しているのか?フォームを設計しているのか?)  ・Excelのバージョン  ・OSのバージョン  ・Escキー以外にキーを利用しても良いか? など とりあえず、「EnableCancelKey」もしくは「DoEvents」あたりを調査して、issan55さんも、もう少し頑張ってみてください。

issan55
質問者

お礼

matsu_junさん 丁寧な解説ありがとうございます。本やネットの解説をみながら何とか動くようになると、 今度は途中で止めたくなったりと、やりたいことが次々と浮かんできてしまいます。 まだまだ素人ですが、実験は(1)、(2)どちらも試してみるとその通りになりました。 また、質問のときの自分の環境や状況説明についても、これからの参考にさせていただきます。 ほんとうにありがとうございました。

関連するQ&A

  • セルの現在時刻表示の更新間隔をセルから入力したい

    セルの現在時刻表示の更新間隔をセルから入力したい マクロは以下を使用してますが更新間隔変更のtimevalue(c3)とするとエラー13が出ます。 どなたかお教え下さい。 ******************************************** Sub Auto_Open() Dim TargetTime, WaitTime TargetTime = Now + TimeValue("00:00:01") WaitTime = TimeValue("00:00:10") Application.OnTime TargetTime, "Macro1", WaitTime End Sub Sub Macro1() Dim TargetTime, WaitTime Calculate TargetTime = Now + TimeValue("00:00:01") 'ココをセルにするとエラー13がでる WaitTime = TimeValue("00:00:10") Application.OnTime TargetTime, "Macro1", WaitTime End Sub Sub auto_close() Dim i As Integer, TargetTime On Error Resume Next For i = 1 To 10 TargetTime = Now + TimeValue("00:00:" & Application.Text(i, "00")) Application.OnTime TargetTime, "Macro1", , False Next i End Sub **********************************************

  • Excellでカウントダウン

    Excel2003でカウントダウン機能をつくろうとしていますのですが、 わからない部分があるので、どなたか教えてください! 作成したいカウントダウンは、 「現在の時間から目標の時間までのカウントダウン」です。 条件としては、 ●表示を「残り何ヶ月何日何時間何分何秒」と表示し、 ●0ヶ月や0日や0時間、0秒となる場合はそれは表示しないようにすることです。(つまり、「残り0ヶ月0日0時間3分24秒」ではなくて、「残り3分24秒」という表示にする) ●カウントダウンをリアルタイムで更新すること。 の3つです。 今できていることは、A1セルに、現在時刻を表示しています。 A1には「=TEXT(NOW(),"YY年MM月DD日 H時MM分SS秒")」と入力し、 マクロとして以下のものを組んでいます。 ******************************************** Sub Auto_Open() Dim TargetTime, WaitTime TargetTime = Now + TimeValue("00:00:01") WaitTime = TimeValue("00:00:10") Application.OnTime TargetTime, "Macro1", WaitTime End Sub Sub Macro1() Dim TargetTime, WaitTime Calculate TargetTime = Now + TimeValue("00:00:01") WaitTime = TimeValue("00:00:10") Application.OnTime TargetTime, "Macro1", WaitTime End Sub Sub auto_close() Dim i As Integer, TargetTime On Error Resume Next For i = 1 To 10 TargetTime = Now + TimeValue("00:00:" & Application.Text(i, "00")) Application.OnTime TargetTime, "Macro1", , False Next i End Sub ********************************************** B1にA1のようにリアルタイムで秒単位で更新されるカウントダウンを表示させるにはどうすればよいでしょうか。 例えば2009年の2月1日0時0分0秒までのカウントダウンでお願いします。 どなたかお願いいたします。

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

    エクセルです。12個のセルの文字列をオートシェープの吹き出しに順に表示させるマクロをつくりました。 Sub tenki2() Dim i As Integer Dim a As String For i = 1 To 12 a = Cells(i, 2).Value ActiveSheet.Shapes("AutoShape 4").Select Selection.Characters.Text = a Application.Wait Now + TimeValue("00:00:05") Next i End Sub これで思った通り表示されるのですが、できればオートシェープをセレクトしないようにしたいのです。 (シートを保護するため) それで ActiveSheet.Shapes("AutoShape 4").Select Selection.Characters.Text = a のところを ActiveSheet.Shapes("AutoShape 4").Characters.Text = a と変えたのですが、「オブジェクトはこのプロパティまたはメソッドをサポートしていません」という実行時エラーがでてしまいました。書き方のどこがまずかったのでしょうか?ご教示いただければ幸いです。

  • VBA 時間設定

    以前こちらでVBAでの時間設定を行いたいと思っています。 下記が現在使用しているものですが、 newHour、newMinute、newSecond 共にシートのセルに 数字を入力したものを読み込んで時間の設定をしたいと思っています。 セルA1:newHour セルB1:newMinute セルC1:newSecond に数字を入れて、時間を変更したりしたいと思っています。 よろしくお願いします。 Sub wait() newHour = Hour(Now()) newMinute = Minute(Now()) + 4 newSecond = Second(Now()) + 50 waitTime = TimeSerial(newHour, newMinute, newSecond) Application.wait waitTime 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 下に数値のみを貼り付ける()"を実行する方法はないでしょうか。 よろしくお願いします。

  • エクセルVBAで、とびとびのセルの順次選択方法?!

    仮にA1:B10という範囲内で、空白のセルだけを一つずつ順番に選択しようと思い、以下のコードを書いてみました。 実行してみると、範囲内がすべて空白の場合にはA1→B1→A2→B2→・・・と、選択してくれます。 しかし、空白と空白以外のセルが混在していると、最初の空白セルから下に、範囲内の空白セル数分だけ、空白であると否とを問わず選択してしまいます。 ( ̄□ ̄;)!! myRngには空白セルだけを指定され、myRng.Cells.Countでもちゃんと空白セル数がカウントされます。 でも、myRng.Cells(i).Select では正しく選択されないのはなぜでしょうか? Cells(i)を使用せず、ループを For Each c In myRng c.Select Application.Wait Now + TimeValue("0:00:01") Next c で回せば選択できるのに・・・・・。 Sub test01() Dim x As Long, i As Long, myRng As Range With ActiveSheet Set myRng = .Range("A1:B10").SpecialCells(xlCellTypeBlanks) x = myRng.Cells.Count For i = 1 To x myRng.Cells(i).Select Application.Wait Now + TimeValue("0:00:01") Next i End With Set myRng = Nothing End Sub ご教示くださいませ。 (o。_。)oペコッ.

  • エクセルVBA 10分後にエクセル自動終了&カウン

    どなたかご教授お願い致します。 ・エクセルの当該ブックを、起動10分後に自動終了(保存しない)させる ・開いている間は、10分のカウントダウンを「分:秒」でA1セルに表示する 以上を実行したいのですが、VBAは全く素人ですので、うまくいきません。 見よう見まねで、以下のようなことをしましたが、結局ダメでした。 何卒、よろしくお願い致します。 ThisWorkbook Workbook Open Private Sub Workbook_Open() test01 Application.OnTime Now + TimeValue("00:10:00"), "終了" End Sub 標準モジュール Module1 Sub 終了() ThisWorkbook.Close Savechanges:=False Application.Quit End Sub Sub test01() With Sheets("バックアップ").Range("A1") .Value = Time .NumberFormatLocal = "mm:ss" End With Application.OnTime Now + TimeValue("0:00:01"), "test01" End Sub

  • ExcelのVBAで、順次動作の実現

    Excelのシートに、トグルボタンを3つ配置します。 ToggleButton1~3 そして、次のマクロを実行すると、2秒ごとに順番にトグルボタンが押されるのかと思いきや、6秒後に一斉にトグルボタンがへっこみます。 どうにか?2秒ごとに順番にトグルボタンが押されるように出来ないでしょうか? Sub test() Dim MyWait As String MyWait = 2 ToggleButton1.Value = True Application.ScreenUpdating = True DoEvents 'この間にもマクロを入れたい(0.1秒以内に処理できるものです) Application.Wait (Now + TimeValue("0:00:" & MyWait)) ToggleButton2.Value = True DoEvents Application.Wait (Now + TimeValue("0:00:" & MyWait)) ToggleButton3.Value = True Application.ScreenUpdating = True DoEvents End Sub

  • On Timeメソッド?で更新されません。

    On Timeメソッド?で更新されません。 現在Web上にあった例を参考に 下記の様にホワイトボード解析シートのA1セルに 20秒ごとに現在時刻を表示させています。 これを応用して、違うシートに 17:00に天気というマクロを実行するよう 作成したのですが上手くいきませんでした。 Sub Auto_Open()とSub auto_close()のtargetTimeを targetTime = TimeValue("17:00") Macro7を天気 としたのですが、なぜ更新されなかったか分かる方がいらっしゃいましたら ご教授下さい。 Sub Auto_Open() Dim TargetTime, WaitTime TargetTime = Now + TimeValue("00:00:01") WaitTime = TimeValue("00:00:10") Application.OnTime TargetTime, "Macro7", WaitTime End Sub Sub Macro7() On Error Resume Next Worksheets("ホワイトボード解析").Range("A1").Calculate Application.OnTime Now + TimeValue("00:00:20"), "Macro7", TimeValue("00:00:10") '↑TimeValueの最初の方をへんこうする事で時間が変わる End Sub Sub auto_close() Dim i As Integer, TargetTime On Error Resume Next For i = 1 To 10 TargetTime = Now + TimeValue("00:00:" & Application.Text(i, "00")) Application.OnTime TargetTime, "Macro7", , False Next i End Sub

  • エクセルシートの順繰り表示マクロについて

    エクセルにて随時更新されるデータを全画面表示し、3枚のシートを5秒置きに順繰り表示させるようマクロを組みました。始めは順調なのですが、数時間たつとフリーズしてしまいます。そもそもエンドレスのマクロプログラム実行に無理があるのでしょうか。 または下記のプログラムに問題があるのでしょうか。ご教授お願いします。 Sub Macro1() Sheets("Sheet2").Select Application.OnTime Now + TimeValue("00:00:05"), "Macro2" End Sub Sub Macro2() Sheets("Sheet3").Select Application.OnTime Now + TimeValue("00:00:05"), "Macro3" End Sub Sub Macro3() Sheets("Sheet1").Select Application.OnTime Now + TimeValue("00:00:05"), "Macro1" End Sub

専門家に質問してみよう