VBでシリアルプリンタを制御するアプリケーションを開発しています。
プリンタに状態(ヘッドが開いているとかリボンがないとか)を問い合わせる関数をTimer1_Timer()で呼び出しています。
その関数内、プリンタに問い合わせてからの応答待ちにDo~Loopを使っています。
そのループ内にDoeventsがあります。
プリンタとPCを繋げていると起こらないのですが、繋げてないと、
(1)アプリケーションを終了してもタスクマネージャを覗くとプロセスが残っている
(2)デバグしてみるとform.unload()時にTimer1.enabled=falseにしているのにform.unload()が終わるとTimer1.enabled=trueになってしまう
(3)(2)の後、Timer1_Timer()に記述したプリンタの状態チェックする関数内のDoeventsに移動して無限ループになってしまう
というような現象が起こります。
多分Doeventsの使い方が悪いと思われます。
これを回避する方法を教えてください。
No.1ベストアンサー
- 回答日時:
Timerイベントが走っている間は、自分に
返ってこないようにしてみてはどうでしょう?
private sub Timer1_Timer()
timer1.enabled=false '追加
do
プリンターの処理
doevents
loop
timer1.enabled=true '追加
end sub
この回答への補足
ありがとうございます。テストしてみます。
一応不完全ながら現在のソースを以下に記します。
'標準モジュール内
'timeGetTime関数
Public Declare Function timeGetTime Lib "winmm.dll" () As Long
'グローバル変数
Dim BUF As String 'プリンタの状態を格納
'起動時
Private Sub Form_Load()
'ポートを開く
MSComm1.PortOpen = True
'プリンタの状態チェック用のタイマー開始
Timer1.Enabled = True
Timer1.Interbal = 1000
End If
End Sub
'終了時
Private Sub Form_Unload(Cancel As Integer)
'プリンタの状態チェックタイマー終了
Timer1.Enabled = False
'ポートを閉じます。
Timer1.Interbal = 0
MSComm1.PortOpen = False
End Sub
'プリンタからの状態データを取得する
Private Sub MSComm1_OnComm()
Dim TimeOut As Long
Dim sTime As Long
Dim eTime As Long
Select Case MSComm1.CommEvent
'受信
Case comEvReceive
'タイマ開始
TimeOut = 1000
sTime = timeGetTime
'全バッファ取得待ち
Do
'タイムアウトなら
If (TimeOut - eTime) < 0 Then
'ループを抜ける
Exit Do
End If
eTime = (timeGetTime - sTime)
Loop Until MSComm1.InBufferCount >= 82
'プリンタの状態取得
PBUF = MSComm1.Input
End Select
End Sub
'プリンタの状態チェックのタイマ
Private Sub Timer1_Timer()
Call CheckPrint
End Sub
'プリンタの状態チェック
Private Sub CheckPrint()
Dim sTime As Long
Dim eTime As Long
Dim TimeOut As Long
PBUF = ""
'プリンタの情報取得コマンド
MSComm1.Output = "~HS"
'タイマ開始
TimeOut = 4000
sTime = timeGetTime
eTime = 0
'コマンド取得待ち
Do
DoEvents
'コマンド取得なら
If BUF <> "" Then
'ループを抜ける
Exit Do
End If
eTime = (timeGetTime - sTime)
'タイムアウト
Loop Until TimeOut - eTime < 0
If PBUF <> "" Then
・・・
・・・
・・・
End Sub
早速試してみました。
問題の解決には至りませんでしたが、動作が安定しました。今回はありがとうございました。
よくよく調べてみるとやはりdoeventsは使い方に気をつけないとまずいらしいです。
No.2
- 回答日時:
単純にMSComm1オブジェクトを解放していないために発生しているのではないでしょうか?
プログラムを終了するときは
MsComm1 = Nothing
としないとダメですよ。
おそらく、プリンタと接続されていない場合、
オープンできないのでクローズもできず、オブジェクトを解放できずにいるのではないでしょうか?
テストしてみましたが、MSCOMM1=Nothingはコンパイルでエラーが起こります。不正なプロパティとか…云々。
でもたぶん貴殿のおっしゃる通りのことだと思います。
これからよく調べてみます。(といっても納期は過ぎてしまいましたが・・・他のハードが揃ってないことを言い訳にしてがんばってみます)
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) vba Sleep関数について教えてください 1 2023/01/18 10:18
- Visual Basic(VBA) vba メモリ節約 3 2022/09/16 21:45
- Windows Me・NT・2000 IMEオプションが開かない 2 2023/04/07 18:04
- Visual Basic(VBA) vba GetAsyncKeyState関数について 1 2023/08/24 12:08
- その他(ソフトウェア) FEPがatokになってしまう 1 2022/07/03 13:51
- プリンタ・スキャナー 印刷 キャンセル&印刷できない 2 2022/11/29 16:45
- Word(ワード) IMEパッドがショートカットキーで開かないのですが。。。 5 2023/06/11 09:23
- Windows 10 Microsoft IMEを無効化する方法 1 2022/07/28 08:20
- iOS システムの復元の実行 3 2023/08/28 22:26
- Visual Basic(VBA) VBA ステータスバー DoEvents 1 2023/03/30 12:22
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
アクセスVBAのMe!と[ ]
-
VBA エンターキーでイベントに...
-
【エクセル】複数のTextBoxに共...
-
日本語の文字化けを直す方法
-
Imageコントロールにグラフを表...
-
Excel VBAでマウスの左クリック...
-
C++Builder 6 でドラッグ&ドロ...
-
Excel2007 でのチェックボック...
-
【エクセルのマクロ】クリップ...
-
エクセルのデータをwebフォーム...
-
ユーザーフォームのインポート...
-
エクセルVBAでセル番地を指定し...
-
現在アクティブになっているオ...
-
文字列で小数点以下の0を削除し...
-
PowerpointVBAで指定のShapeオ...
-
WebBrowserオブジェクトにて、...
-
Access からオブジェクトとして...
-
VBAで選択範囲外の図形(オブジ...
-
アクセス 名前のつけ方について。
-
CreateSolidBrushで作成したオ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBA エンターキーでイベントに...
-
アクセスVBAのMe!と[ ]
-
文字列で小数点以下の0を削除し...
-
Excel VBAでマウスの左クリック...
-
【エクセルのマクロ】クリップ...
-
エクセルVBAでセル番地を指定し...
-
Accessのフォーム上にエクセル...
-
コードでオブジェクトを最前面に
-
日本語の文字化けを直す方法
-
現在アクティブになっているオ...
-
Imageコントロールにグラフを表...
-
Excel2007 でのチェックボック...
-
PowerpointVBAで指定のShapeオ...
-
Access からオブジェクトとして...
-
エクセルのデータをwebフォーム...
-
【エクセル】複数のTextBoxに共...
-
[C#] DataGridViewの項目名
-
カッコ付けのオブジェクト名を...
-
ExcelのシートをAccessで表示し...
-
ユーザーフォームのインポート...
おすすめ情報