プロが教えるわが家の防犯対策術!

Excel VBA で処理中断(DoEvents)ができなくて困っています。

まず、CommandButton1ボタンでSampleをコールし、Sample処理の中でループを廻し、途中でCommand1ボタンをクリックして、処理中断(DoEventsによって)をいれたいと思っています。

しかし、Command1ボタンをクリックしても処理中断がきかないのです。
グローバル変数fStopにはCommand1ボタンをクリックしたときにTrueが入っていることは、MsgBoxで確認していますが、Sample処理の方に値がつたわっていないようで、ループが最後まで止まりません。
コードが悪いのでしょうか、それとも、DoEventsの使い方が悪いのでしょうか。
もし、DoEventsが使えないのであれば、代替手段はありますでしょうか。
(長時間の印刷中の処理中断に応用したいと思っています)

環境はExcel 2002 SP3 , VB 6.0 , Windows XPです。
なお、DoEventsのコードは以下のURLを参考にして作成しました。
http://officetanaka.net/excel/vba/function/DoEve …

コードは以下のとおりです。
'*********
Dim fStop As Boolean 'グローバル変数を宣言
'*********
Sub Sample()
Dim i As Long
fStop = False
For i = 1 To 1000000
DoEvents
If fStop = True Then
MsgBox "処理が中断されました"
Exit For
End If
Next i
End Sub
'********
Private Sub CommandButton1_Click()
Call Sample
End Sub
'********
Private Sub Command1_Click()
fStop = True
MsgBox "fStop=" & fStop
End Sub

A 回答 (2件)

当方xl2000ですが、提示されたコードで問題なく動作いたしました。


動作が分かり易いようにラベルを一個追加しています。
Dim fStop As Boolean

Sub Sample()
Dim i As Long
fStop = False
For i = 1 To 1000000
DoEvents
Me.Label1.Caption = i
If fStop = True Then
MsgBox "処理が中断されました"
Exit For
End If
Next i
End Sub

Private Sub CommandButton1_Click()
Call Sample
End Sub

Private Sub CommandButton2_Click()
fStop = True
MsgBox "fStop=" & fStop
End Sub

Private Sub UserForm_Initialize()
Me.Label1.Caption = 1
End Sub

'○標準モジュール
'Sub test()
' UserForm1.Show 'vbModeless
'End Sub
    • good
    • 0
この回答へのお礼

みなさまご回答ありがとうございます。

結果、Trueは以下のように2箇所を書き換えることでTrueが伝わるようになりました。

`**********
Dim fStop As Boolean 'グローバル変数を宣言
`**********
Sub Sample()
Dim i As Long
fStop = False
For i = 1 To 1000000
DoEvents
If fStop = True Then
MsgBox "処理が中断されました"
Exit For
End If
Next i
End Sub
`********** stopPartsを追加(Module内に追加)
Sub stopParts()
fStop = True
End Sub
'**********
Private Sub CommandButton1_Click()
Call Sample
End Sub
'********** Call stopPartsを呼び出して、stopPartsの中でTrueをセットするように変更
Private Sub Command1_Click()
Call stopParts
End Sub

お礼日時:2010/07/12 18:28

>(長時間の印刷中の処理中断に応用したいと思っています)


プリンタ・データを、プリンタ・スプールに送ってしまうのですから、マクロは関与できません。Printer をAbortDocなどを使って制御することを考えるかもしれませんが、それでは、おおごと過ぎると思います。

だから、Wait やSleep を入れ、一枚ずつ印刷するようにし、印刷とマクロの状態を同期させます。

こちらでは、以下のコードを実際に試してはいませんから、様子をみていだくしかありません。
なお、ページを入れる場合には、PageSetup で、ページをそれぞれ付けてください。

'//標準モジュール
Private Declare Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds As Long)
Sub PrintPage()
 Dim lngPageTotal As Long
 Dim i As Long
 Dim FrontPage As Integer
 On Error GoTo StopLine
 Application.EnableCancelKey = xlErrorHandler 'Escape で、止めます。
 FrontPage = 1
 lngPageTotal = Application.ExecuteExcel4Macro("GET.DOCUMENT(50)")
 For i = FrontPage To lngPageTotal
  'ActiveSheet.PageSetUp.CenterFooter = CStr(i) 'ページを入れる
  ActiveSheet.PrintOut From:=i, To:=i, Preview:=False
  Sleep 500 '←ここで調整します。500 は、0.5秒
  DoEvents
 Next
StopLine:
  MsgBox "Page" & CStr(i) & "で、印刷を中止しました。", vbInformation
  Application.EnableCancelKey = xlInterrupt
End Sub
    • good
    • 0

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

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


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