マンガでよめる痔のこと・薬のこと

エクセルにて刻一刻変る外部データ(株価)を表示させています。それを自動で30分置きにデータ蓄積させる方法はありませんか?

現在は自分で作ったキーボードマクロで 時計を見ながらボタンを押し、データを取り込ん出る始末です。

その簡単マクロに「30分置きに実行させる」と云う記述を付け足す程度で自動実行させる事は可能でしょうか? 
当方キーボードマクロでの自動書き込みしか出来ない素人ですが、少々複雑な物であっても頑張ってみるつもりですので、どなたかご教授下さい。

このQ&Aに関連する最新のQ&A

A 回答 (8件)

えーー。

。実際に使うなら、zap35 さんのように、OnTime で実行したマクロ
の中で再度 OnTime を登録する方が良いと思います。

この方式だと、OnTime で登録されるのは常に一つだから管理し易いです。
これに未実行の予約を破棄できる仕組みを組み込めばベストだと思います。

今更こんな事言うのは、#6 の大げさなコードを見て、「また、やっちまった...」
と反省しているからです。が、#6 をアップしてしまった以上、それなりに
まとめておきました。こちらは、一括登録方式です。

コードのままだと、午前10時~午後6時まで30分間隔で Macro1 を実行します。
変更点は、

 ・ブッククローズをトラップした
 ・進捗状況をステータスバーに表示するようにした
 ・その他しょうもないこと

です。

このままコピペで使えると思いますが、試される場合は、MACRO1 はご自分の
用途に合わせて適切に修正して下さい。


Option Explicit

Dim mcolTask As Collection

Sub 実行予約()

  Dim i      As Date
  Dim strProcName As String
  Dim datBigin  As Date
  Dim datEnd   As Date
  Dim datInterval As Date
  Dim datTimeout As Date
  Dim blnJustTime As Boolean

  ' Setting-------------------------------------------------------

  datBigin = TimeValue("10:00:00")  ' 開始時刻
  datEnd = TimeValue("18:00:00")   ' 終了時刻
  datInterval = TimeValue("00:30:00") ' 実行間隔(少なくとも数秒以上で)
  datTimeout = TimeValue("00:02:00") ' 実行待機タイムアウト
  blnJustTime = True         ' datInterval で丸めるか
  strProcName = "MACRO1"       ' 実行するマクロ名

  '---------------------------------------------------------------

  ' 既に実行予約されているか確認
  If mcolTask Is Nothing Then

    ' 日付シリアル値を加算
    datBigin = datBigin + Date
    datEnd = datEnd + Date
    ' 終了時刻が開始時刻より小さければ日をまたぐので補正
    If datEnd < datBigin Then datEnd = datEnd + 1
    ' 現在時刻が既に終了時刻を過ぎている場合
    If datEnd < Now() Then
      MsgBox "終了時刻を過ぎているため予約できません。", vbCritical, "終了"
      Exit Sub
    End If
    ' 現在時刻が開始時刻を過ぎていれば補正
    If datBigin < Now() Then
      ' 開始時刻を datInterval で指定された値で丸めるか
      If blnJustTime Then
        datBigin = Application.Floor(Now() + datInterval, datInterval)
      Else
        datBigin = Now() + datInterval
      End If
    End If

    ' 初期化
    Set mcolTask = New Collection

    ' メイン部分
    For i = datBigin To datEnd Step datInterval
      ' 後から取り消せるようにコレクションに退避
      mcolTask.Add CStr(i) & "," & strProcName
      ' Application.Ontime で実行予約を行う
      Application.OnTime EarliestTime:=i, _
                Procedure:=strProcName, _
                LatestTime:=i + datTimeout, _
                Schedule:=True
    Next i
  Else
    MsgBox "既に実行中です", vbInformation
  End If

End Sub

Sub 未実行予約強制解除()
 
  Dim i  As Long
  Dim vntS As Variant
 
  On Error Resume Next
  Application.StatusBar = "タスク破棄中... "
  For i = 1 To mcolTask.Count
    vntS = Split(mcolTask.Item(i), ",")
    Application.OnTime CDate(vntS(0)), CStr(vntS(1)), Schedule:=False
  Next i
  Application.StatusBar = ""
  Set mcolTask = Nothing

End Sub

' タスク管理用
Private Sub RemoveTask()
  
  On Error Resume Next
  mcolTask.Remove (1)
  Application.StatusBar = "待機中のタスク... " & mcolTask.Count
  DoEvents
  Beep
  If mcolTask.Count = 0 Then
    Application.StatusBar = ""
    Set mcolTask = Nothing
  End If

End Sub

Sub Auto_Close()

  Dim intRes As Integer
  If Not mcolTask Is Nothing Then
    intRes = MsgBox( _
        Prompt:="待機中のタスクが " & mcolTask.Count & " 件あります。" & vbLf _
           & "破棄して終了しますか?", _
        Buttons:=vbOKCancel + vbDefaultButton2 + vbExclamation, _
        Title:="問い合わせ")
    If intRes = vbOK Then
      Call 未実行予約強制解除
    Else
      ' ブッククローズをキャンセル
      Application.ExecuteExcel4Macro ("Halt(True)")
    End If
  End If

End Sub

' 呼び出すマクロ--> Application.Ontime のマクロ名と一致させて下さい
Sub MACRO1()

  Dim lngRow As Long
  With ThisWorkbook.Sheets("Sheet1")
    lngRow = .Range("V65536").End(xlUp).Offset(1).Row
    .Cells(lngRow, "V").Resize(1, 3).Value = .Range("Q12:S12").Value
    .Cells(lngRow, "Y").Value = Now()
  End With

  ' ご自分のマクロの最後に次の一行を追加しておいて下さい
  Call RemoveTask

End Sub
    • good
    • 3
この回答へのお礼

ありがとうございました。
頂いた記述を少々加工して月曜の値動きに使ってみましたら、ばっちり動いて非常に満足な結果です。
これとっても良さそうです。
本当にありがとうございました。

お礼日時:2006/06/19 09:24

あ、、、すみません。



Setting 欄、コメントと全然違いますね。
30秒間を10秒間隔でテストしたときのものです。
直すの忘れました。

適切に書き直して下さい。
    • good
    • 2

Application.OnTime は手軽な反面、結構扱いが難しいかもしれません。

実行
予約のキャンセルとか、2重予約のトラップとか。

その辺も含めてコーディングしてありますが、ザッと作ったので穴があるかも
しれません。

実行予約の Setting という場所を変更してみて下さい。

あとは、OnTime だと待機中は普通に Excel が使えてしまうので、不意にブック
が閉じられてしまうのをトラップする必要があるかもしれません。

ご参考までに。では。


Option Explicit

Dim mcolTask As Collection

Sub 実行予約()

  Dim i      As Date
  Dim strProcName As String
  Dim datBigin  As Date
  Dim datEnd   As Date
  Dim datInterval As Date

  ' Setting-------------------------------------------------------
  ' 開始時刻: 例えばマクロが実行された時刻
  datBigin = Now()
  ' 終了時刻: 例えば当日午後6時まで
  datEnd = Now() + TimeValue("00:00:30")
  ' 実行間隔: 例えば5秒間隔
  datInterval = TimeValue("00:00:10")
  ' 実行するマクロ名
  strProcName = "MACRO1"
  '---------------------------------------------------------------

  ' 既に実行予約されているか確認
  If mcolTask Is Nothing Then
    
    ' 初期化
    Set mcolTask = New Collection
    ' 開始時刻が現在時刻より早い場合は補正
    If datBigin < Now() Then datBigin = datBigin + datInterval
    
    ' 実行予約メイン部分
    For i = datBigin To datEnd Step datInterval
      ' 後から取り消せるように退避しておきます
      mcolTask.Add CStr(i) & "," & strProcName
      ' Application.Ontime で実行予約します
      Application.OnTime i, strProcName, Schedule:=True
    Next i
  
  Else
    MsgBox "既に実行予約されています", vbInformation
  End If

End Sub

Sub 未実行予約強制解除()
  
  Dim i  As Long
  Dim vntS As Variant
  
  On Error Resume Next
  For i = 1 To mcolTask.Count
    vntS = Split(mcolTask.Item(i), ",")
    Application.OnTime CDate(vntS(0)), CStr(vntS(1)), Schedule:=False
  Next i
  Set mcolTask = Nothing

End Sub

' タスク管理用
Private Sub RemoveTask()
  
  mcolTask.Remove (1)
  If mcolTask.Count = 0 Then
    Set mcolTask = Nothing
  End If

End Sub


' 呼び出すマクロ--> Application.Ontime のマクロ名と一致させて下さい
Sub MACRO1()

  'シート名は明示的に指定した方が良いですよ
  With ThisWorkbook.Sheets("Sheet1")
    .Activate
    .Range("Q12:S12").Copy
    .Range("V65536").End(xlUp).Offset(1).Select
    Selection.PasteSpecial Paste:=xlPasteValues
  End With
  
  ' ご自分のマクロの最後に次の一行を追加しておいて下さい
  Call RemoveTask

End Sub
    • good
    • 1
この回答へのお礼

ありがとうございます。
これはそのまま貼り付けて使えるものなのでしょうか? これが理解できたら本当に面白そうです。

自宅に戻って試してみます
ありがとうございました。

お礼日時:2006/06/16 17:39

#04です。

#04ではループしちゃいますね。再掲します。Bookを開いた時から一定間隔でマクロを実行します。

Sub Auto_Open()
TargetTime = Now + TimeValue("00:10:00") '現在時刻より10分後
WaitTime = TimeValue("00:02:00") 'TargetTimeに他処理実行中の時のWaitTime
Application.OnTime TimeValue(TargetTime), "Macro1", TimeValue(WaitTime)
End Sub

Sub Macro1()
Range("Q12:S12").Select
Selection.Copy
Range("V65536").End(xlUp).Offset(1).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False

TargetTime = Now + TimeValue("00:10:00")   WaitTime = TimeValue("00:02:00")    Application.OnTime TimeValue(TargetTime), "Macro1", TimeValue(WaitTime)
End Sub

ただし質問者さまのマクロは別のシートを開いているときなどにエラーになる可能性があります。
Worksheets("シート名").Range("Q12:S12").Copy
のようにワークシートを明示した方がよいです

この回答への補足

ありがとうございます。
早速試してみます。
後ほど結果をご報告いたします。

補足日時:2006/06/16 14:08
    • good
    • 1
この回答へのお礼

ばっちり上手く行きそうです。
現在仕事中なので終わってからみっちりと検証しようと思いますが、今の所想像通りの動きをしています。
本当にありがとうございました。

お礼日時:2006/06/16 14:37

指定時刻に指定するマクロを実行させる命令はあります。

詳しくは下記URLを参照して下さい。(著作権があるので引用はしません)

質問者さまが作成したマクロを Macro1 として
Auto_Open()
 DO
   指定時刻 = 現在時刻 + n分
   指定時刻に Macro1を実行
 LOOP
End sub

とすれば良いと思います

参考URL:http://www.asahi-net.or.jp/~ZN3Y-NGI/YNxv214.html
    • good
    • 1

Application.OnTime じゃダメ?



OnTime メソッド
指定された時刻 (特定の日時、または特定の期間の経過後) にプロシージャを実行します。

この回答への補足

早速ありがとうございます。

ON TIME メソッドと云う言葉は 他の質問者様への回答で目にした事はありますが、それが私のパターンで有効なのか、又どのように活用していいのかもまったく分かりません。 
しかし「特定の期間の経過後にプロシージャを実行する」と云うのは凄く良さそうに思えます。
ON TIME メソッド のやり方はどのようにするのでしょうか? 現在のマクロの書き込み  

  Range("Q12:S12").Select
Selection.Copy
Range("V65536").End(xlUp).Offset(1).Select
Selection.PasteSpecial Paste:=xlPasteValues,   Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False

こんな感じですが、これに on time メソッドをどう加えたら宜しいのでしょうか?

補足日時:2006/06/16 12:45
    • good
    • 0

現在の状態では、



その外部のデータを取り込む方法は、
エクセルを開くと、「自動的に、外部のデータを取り込む」ようになってるのでしょうか?
    • good
    • 0

たぶんエクセルVBAにはタイマーコントロールが無かったと思います。


がんばれば作れそうな気もしますが・・
下記のフリーソフトを使うほうが早いです。

参考URL:http://www.vector.co.jp/soft/win95/prog/se286953 …
    • good
    • 0
この回答へのお礼

ありがとうございました。
僕の質問の件は#4 #5サンの回答で解決いたしました。 しかし フリーソフトを使ってどんどん進化させそうなきもいたします。 ありがとうございました。

お礼日時:2006/06/16 14:36

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QエクセルVBAにおけるON TIMEメソッドの解除方法について

こんにちは。現在エクセルでフォームを使用したVBAマクロを作成中です。
内容はフォーム内のテキストボックスに制限時間を設けて文字入力を行ってもらうものです。

Sub テスト()

do until
 ・
 ・
call timeup
loop

End Sub

Sub timeup()
dim timekp as integer
'テストの開始時間をキープ

'Application.OnTime timekp + TimeValue("1:00:00"),"endform"
'1時間経過後終了を促すフォームを表示する

End Sub

Sub endform()

load userform1
userform1.show
'エクセル終了のコマンドボタンがついているフォームを表示する

End Sub

マクロは大まかに記述しましたが以上のようにすると、一度はマクロの作成が成功したように終了するのですが、ブックを開けたままでいると1時間後に自動的にuserform1が表示されてしまいます。また、ブックを閉じていても自動的にオープンし、(マクロを有効にする)をONにするとデバック状態となります。
変数のtimekpを初期化する事で凌げると思ったのですが、うまくいきません。
以前マクロのヘルプを操作している時にON TIMEメソッドを解除する方法が掲載されていたように思うのですが、探し方がマズイのか見つけられませんでした。
マクロの記述方法がマズイのでしょうか?ON TIMEメソッドを解除しない限り、いつまでもこのメソッドは効力を発揮するのでしょうか?
また、ON TIMEメソッドを解除できるメソッドや良い解決方法がありましたら入門書等を片手にマクロを作成している素人にご教授の程お願い致します。

こんにちは。現在エクセルでフォームを使用したVBAマクロを作成中です。
内容はフォーム内のテキストボックスに制限時間を設けて文字入力を行ってもらうものです。

Sub テスト()

do until
 ・
 ・
call timeup
loop

End Sub

Sub timeup()
dim timekp as integer
'テストの開始時間をキープ

'Application.OnTime timekp + TimeValue("1:00:00"),"endform"
'1時間経過後終了を促すフォームを表示する

End Sub

Sub endform()

load userform1
userform1.show
'エクセル終了のコマ...続きを読む

Aベストアンサー

>ON TIMEメソッドを解除
OnTimeのヘルプはごらんになられましたか?
expression.OnTime(EarliestTime, Procedure, LatestTime, Schedule)

Schedule にfalseを設定することで、直前の実行指定を解除することができます。
具体的には
Application.OnTime timekp + TimeValue("1:00:00"),"endform",,false
とでもすればいいです。

Qエクセルのマクロを一定時間ごとに実行

エクセルのマクロを例えば08:30に実行したら、それから15:00まで、3分毎に実行したいのですが、このようなことは可能でしょうか?
教えてください。

Aベストアンサー

他サイトで紹介されていた現在時刻
をリアルタイムで取得するマクロです。
スタートで開始し、ストップで終了します。
この記述の時間を変更すれば間隔を調整で
きます。

Private flgStop As Boolean

Sub スタート()
flgStop = False
現在時刻
End Sub

Sub 現在時刻()
If flgStop Then End
Application.OnTime Now() + TimeValue("00:00:01"), "現在時刻"
Range("A1").Value = Format(Now, "hh:mm:ss")
End Sub

Sub ストップ()
flgStop = True
End Sub

Qエクセル時間毎ごとにマクロを実行するやり方。

 初めまして、よろしくお願いします。より正確な指定時間毎にマクロを実行させるやり方を考えています。
 1分毎ごとにマクロを実行する

nextTime = Now() + TimeValue("00:01:00")
Application.OnTime nextTime, "時間毎ごとに実行"

というやり方は解るのですが、

Application.OnTime TimeValue("09:00:00"), "時間毎ごとに実行"

 この指定時間("09:00:00")に実行するマクロを利用し
("09:01:00")、("09:02:00")、("09:03:00")、("09:04:00")、("09:05:00"),・・・・・の時間、秒が00になると("hh:ss:00")マクロを実行されるやり方は有るのでしょうか。
 もし有るのでしたら、よろしくお願いします。

Aベストアンサー

例えばこんな感じでしょうか。

Dim SetTime As Date

Private Sub Test()
Range("A1").Value = Time
SetTime = TimeSerial(Hour(Time), Minute(Time) + 1, 0)
Application.OnTime SetTime, "Test"
End Sub

Sub TimerSet()
SetTime = TimeValue("09:00:00")
Application.OnTime SetTime, "Test"
End Sub

Sub TimerCancel()
Application.OnTime SetTime, "Test", , False
End Sub

QVBAを時間指定で自動実行

就業時間内(9時~6時)でエクセルVBAを指定時間に自動実行させたいです。
エクセルはパソコン起動した朝に、開いておきます。(バックグラウンド)
指定時間になったらVBAを自動実行させたいのです。
指定時間は例えば、
10時11分
10時16分
10時21分 などです。最初の時間から5分間隔で実行。
こういう事はできるのでしょうか?VBAでできるのか?
それ以外の方法があるのか?よくわかりません。
詳しく教えてください。

Aベストアンサー

たとえば、こんなことか。
下記は、1度testを実行すると、15秒たつとtest1を実行し、以後10秒ごとにtest2を実行するというもの。
test1もtest2も単にmsgboxを表示するだけ。

Dim gotime1, gotime2
Sub test()

gotime1 = Time + TimeValue("00:00:15")
gotime2 = gotime1
Application.OnTime gotime1, "test1"
gotime2 = gotime2 + TimeValue("00:00:10")

While gotime2 < gotime1 + TimeValue("00:01:00")
Application.OnTime gotime2, "test2"
gotime2 = gotime2 + TimeValue("00:00:10")
Debug.Print gotime1, gotime2
Wend
MsgBox "start " & Time
End Sub

Sub test1()
MsgBox "test1 " & Time
End Sub

Sub test2()
If Time >= gotime1 + TimeValue("00:01:00") Then
MsgBox "end " & Time
Else
MsgBox "test2 " & Time
End If
End Sub

たとえば、こんなことか。
下記は、1度testを実行すると、15秒たつとtest1を実行し、以後10秒ごとにtest2を実行するというもの。
test1もtest2も単にmsgboxを表示するだけ。

Dim gotime1, gotime2
Sub test()

gotime1 = Time + TimeValue("00:00:15")
gotime2 = gotime1
Application.OnTime gotime1, "test1"
gotime2 = gotime2 + TimeValue("00:00:10")

While gotime2 < gotime1 + TimeValue("00:01:00")
Application.OnTime gotime2, "test2"
gotime2 = gotime2 + TimeValue("00:...続きを読む

QEXCEL VBA で現在開いているブックのファイル名を取得する方法

EXCEL2003 VBAで業務を簡素化するために、現在開いているブックのファイル名を取得する方法が分かりません。
作業手順をマクロを使って処理していますが、オリジナルのワークブックをファイル名を変えて保存し、以後、このワークブックを読み込んで使用しています。
このときのVBAは、オリジナルのファイル名を使っているため、ファイル名を変更するとエラーになり、以後の業務に使用できません。
常にファイル名を取得出来るVBAをどなたか、教えて下さい。

Aベストアンサー

>現在開いているブックのファイル名
 ちょっと曖昧な表現かなぁという気もいたしますが、VBAが書いてあるブックのブック名は
ThisWorkbook.Name
で、現在 "アクティブにして" 操作対象になっているブックの名前は
ActiveWorkbook.Name
ですね。

 しかし、
>VBAは、オリジナルのファイル名を使っているため、ファイル名を変更するとエラーになり
というような文脈からすると、
ThisWorkbook.Name
の方ですかね。

Q【Excel VBA】マクロでExcel自体を終了させたい

環境:WindowsXP、Excel2003

マクロでエクセルを終了(ブックを閉じて、アプリケーション自体も終了)させたいのですが、以下のコードではアプリケーションが閉じてくれません。

ThisWorkbook.Close
ExcObj.Quit
Application.Quit

どこか悪いところはありますでしょうか?

よろしくお願いします。

Aベストアンサー

普通に考えれば質問者のコードで上手くいきそうですが
hana-hana3さんの回答にもあるようにThisWorkBook.Closeでコード終了となりますので
Application.QuitをThisWorkBook.Closeの前にもってこないといけません。
Application.Quitはそれがあるプロシージャのコードが全て終わるまで
その実行を保留するちょと特別動作をします。

'-------------------------------------
 Application.Quit
 ThisWorkbook.Close
'-------------------------------------
 
 

QSub ***( ) と Private Sub ***( ) の違い

初歩的な質問で申し訳ありませんが・・・

自分でコードを書いていても、イベントが発生したりした時の処理で、コードのウィンドウで上のドロップダウンリストで選択できる時の処理などは自動的に[Private Sub Command1_Click( )]などと出てくるのでそのまま使っています。自分で別途プロシージャーを作成する時は[Sub ****( )]としています。
ですがその違いを理解しないまま、自分で作成する時は[Private Sub]ではなくて[Sub]を使っています。

Sub ***( ) と Private Sub ***( ) の違いは何なんでしょうか?
どなたか説明頂けませんか?
よろしくお願いします。

Aベストアンサー

「Sub」の部分にカーソルを置いて[F1]を押せばヘルプが起動します。
「指定項目」のところに「Public」と「Private」の説明がありますよ。
省略して「Sub hogehoge()」とした場合は「Public」とみなされます。

Publicは「すべてのモジュールから呼び出せるプロシージャ」ということになります。
Privateとすると「同じモジュールの中からしか呼び出せないプロシージャ」となります。

もしExcelをお持ちでしたらExcelのVBEで標準モジュールを追加し、「Sub Test1()」と「Private Sub Test2()」を作成してみてください。
そしてExcelの[ツール]-[マクロ]-[マクロ(Alt+F8)]でマクロ実行のダイアログを表示させてみるとわかります。
ここには実行できるプロシージャの一覧が表示されますが、Test1は表示されているけれどTest2は表示されません。
Test1はPublicで、Test2はPrivateだからです。

QDoEvents関数って何?

こんにちは。

VBAやプログラミングに詳しい皆様に
教えていただきたい質問があります。

cells(1,1)からcells(5000,1)までの値を消去するときに
処理の進行状況を表示するためにuserform上にプログレスバーを表示したいと思います。

そこで下記のようなコードを入力しました。

userform1.show
for i =1 to 5000
cells(i,1)=""
userform1.progressbar1.value=i/5000*100
next i
unload userform1

しかしこれだとuserformの背景が真っ白になってしまい
ラベルの文字も消えてしまいます。
そこで「EXCEL VBA パーフェクトマスター」という本を見たら

for i =1 to 5000
cells(i,1)=""
userform1.progressbar1.value=i/5000*100
DoEvents
next i
unload userform1
と入力すれば解決することがわかりました。

しかし「DoEvents」についてあまり詳しく書いていなかったのでDoEvents関数をヘルプで見ると、
「発生したイベントがオペレーティング システムによって処理されるように、プログラムで占有していた制御をオペレーティング システムに渡すフロー制御関数です。」

と書いてあるのですが正直、書いてあることがよくわかりません。

どなたかDoEvents関数について、
もう少しわかりやすく教えていただけませんか。
それから、最初に書いたコードで実行すると
ユーザーフォームの背景が真っ白になってしまう原因も
教えていただけませんか?

よろしくお願いいたします。

こんにちは。

VBAやプログラミングに詳しい皆様に
教えていただきたい質問があります。

cells(1,1)からcells(5000,1)までの値を消去するときに
処理の進行状況を表示するためにuserform上にプログレスバーを表示したいと思います。

そこで下記のようなコードを入力しました。

userform1.show
for i =1 to 5000
cells(i,1)=""
userform1.progressbar1.value=i/5000*100
next i
unload userform1

しかしこれだとuserformの背景が真っ白になってしまい
ラベルの文字も消えてしまいます。
そ...続きを読む

Aベストアンサー

簡単に言うと、
OS に制御を渡すってことです。(ヘルプそのまんま)
時間が掛かるループ処理などの場合、ループが終わるまで制御は独占されてしまいます。
ですのでループ中は OS や Excel そのものにも再描画をさせる暇さえ与えません。
途中に DoEvents を入れると制御が OS に渡るので、OS は溜まっていた処理をそこで行うことができます。
結果、フォームの再描画などが行われることになります。

注意点ですが、
Private Sub CommandButton1_Click()
  Dim i As Long

  For i = 1 To 50000
    DoEvents
    Cells(i,1) = ""
  Next i
End Sub

Private Sub CommandButton2_Click()
  MsgBox "hoge"
End Sub

っていうフォームのコードがあった場合、
DoEvents を入れることによって、ループ中にユーザーがCommandButton2 を押すことによって CommandButton2 のクリック イベントも動いちゃいます。
CommandButton1 のクリック イベントではループの前に
CommandButton1.Enabled = False
CommandButton2.Enabled = False
を書いてフォーム上の CommandButton を無効にしておき、ループが終わったら
CommandButton1.Enabled = True
CommandButton2.Enabled = True
と書いて CommandButton を有効に戻してください。

これを工夫すれば、CommandButton2 で CommandButton1 のループを途中キャンセルする処理もすることができます。

Private Canceled As Boolean

Private Sub CommandButton1_Click()

  CommandButton2.Enabled = False

  Dim i As Long
  For i = 1 To 50000
    DoEvents

    If Canceled = True Then
      MsgBox "キャンセルしました"
      Exit Sub
    End If

    Cells(i, 1).Value = ""
  Next i
End Sub

Private CommandButton2_Click()
  Canceled = True
End Sub



コードの行頭にあるスペースは見易さのために全角スペースで作成していますので、これをこのままコピペするとエラーになるかもしれません。
コピペするなら行頭の全角スペースを半角スペースに直してください。

簡単に言うと、
OS に制御を渡すってことです。(ヘルプそのまんま)
時間が掛かるループ処理などの場合、ループが終わるまで制御は独占されてしまいます。
ですのでループ中は OS や Excel そのものにも再描画をさせる暇さえ与えません。
途中に DoEvents を入れると制御が OS に渡るので、OS は溜まっていた処理をそこで行うことができます。
結果、フォームの再描画などが行われることになります。

注意点ですが、
Private Sub CommandButton1_Click()
  Dim i As Long

  For i = 1 To 50000
...続きを読む

QEXCELマクロで上書きメッセージ無しで保存する方法

EXCELマクロで上書きメッセージ無しで保存する方法をお願いします
ActiveWorkbook.SaveAs "C:\Documents andSettings\Nakatani\MyDocuments\Book1.xls"
の様にするとすでにファイルがある場合上書きメッセージが出ます
メッセージを出さずに上書きするプログラミングを教えて下さい
宜しくお願いします

Aベストアンサー

Application.DisplayAlerts = False
ActiveWorkbook.SaveAs "C:\Documents andSettings\Nakatani\MyDocuments\Book1.xls"
Application.DisplayAlerts = True

QExcelマクロにて、タイマーで自動更新は出来るのでしょうか?

Excelマクロにて、タイマーで自動更新は出来るのでしょうか?

Excelマクロの初心者です。

最近関数にて、時間の計算を行うbookを作成しましたが、
下記の様に手動で現時刻欄を更新している状態です。
(これは1カ所ですが、実際には複数箇所を行いたいです。)


Sub 残り時間を更新()
'
Range("C21").Select '現時刻欄を選択
ActiveCell.FormulaR1C1 = "=NOW()" '使用開始時刻欄に現時刻を再設定
Application.CutCopyMode = False

End Sub


これを別のマクロにくっつけて、例えば10分おき位に自動で
更新が出来る様な事は出来ますでしょうか?

理想は、セルに自動更新時間が任意に設定でき、その数字の基で
タイマーが時間が決まり、実行ボタンでタイマー開始、停止ボタン
で実行キャンセルといった、VB上では出来そうな事をExcel上
でも可能でしょうか?

良きアドバイスをいただきたいと思います。
よろしくお願いいたします。

Aベストアンサー

#1のimogasiさんのご指摘の「初心者が行う域を超えている」というのは、私も同感です。Excelでも作れますが、APIタイマーは、やむにやまれず、どこかで発表したことがあります。

GetTickCount, SetTimer 等を使いますから、調べてくださってもよいです。ただ、正直なところ、実験的というか、かなり微妙というか、安定性が今ひとつのような気がしますね。今でも、お仕事で使う方にとっては中途半端なものを作って申し訳ないと思っています。

イベントの一種ですから、稼働中でも、Excelやマクロは動きます。ファイルを閉じなければよいです。

しかし、以下のように、UserForm で、OnTime と組み合わせたほうがよいと思います。時間表示も可能です。理由は詳しくは知らないのですが、UserForm の中は、独立して動くことが多いです。ただし、UserFormを立ち上げていると邪魔ですから、GetWindowLong, SetWindowLong, で、隠す方法があります。

これに、OnTime を別に設定させればよいです。
>実行ボタンでタイマー開始、停止ボタンで実行キャンセル
これは、ヘルプを参照してください。安定して使用できます。

分からなければ、しばらくの間でしたら、その辺りの返事を含めて書きます。

ただし、UserForm 起動はフラグを立てて、起動しているのを忘れて、ファイルを閉じないような安全装置は付けてください。ハングする可能性があります。

'//UserForm プロパティは、ShowModal False
'//Labelをひとつ用意してください。
Private Sub UserForm_Activate()
Dim currentTime As String
 While UserForms.Count > 0
  currentTime = Format$(Time(), "h:nn:ss")
 If currentTime <> Label1.Caption Then
  Label1.Caption = currentTime
 End If
  DoEvents
 Wend
End Sub

Private Sub TimerRefresh()
 If UserForms.Count = 0 Then Exit Sub
 UserForm1.TimerRefresh
End Sub

#1のimogasiさんのご指摘の「初心者が行う域を超えている」というのは、私も同感です。Excelでも作れますが、APIタイマーは、やむにやまれず、どこかで発表したことがあります。

GetTickCount, SetTimer 等を使いますから、調べてくださってもよいです。ただ、正直なところ、実験的というか、かなり微妙というか、安定性が今ひとつのような気がしますね。今でも、お仕事で使う方にとっては中途半端なものを作って申し訳ないと思っています。

イベントの一種ですから、稼働中でも、Excelやマクロは動きます。ファ...続きを読む


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング