• ベストアンサー

VBAで印刷スプール終了の判定をする

Excel97からWord98を操作して、Wordを連続印刷した後にWordを自動的に保存せず に終了するようなマクロを組もうと考えています。しかし、Wordのスプール処理に時間が かかる為、スプールしている間に印刷処理のマクロを抜けて終了処理のマクロを実行して しまい、スプール処理の終わっていないデータが全て破棄されるという事態に 陥ってしまいました。ここでプリンタのスプール処理が終わったことを判定 出来れば、それを検知してからWordの終了処理を実行すれば、全て上手くいく のです。環境はプリンタがLANで接続されているPCを使っています。 (あまり良く分かりません) すみませんが、どなたか教えて下さい!

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

  • ベストアンサー
  • todo36
  • ベストアンサー率58% (728/1234)
回答No.2

"バックグラウンドで印刷する"をoffにすればよい PrintBackgroundプロパティ参照

参考URL:
http://www.microsoft.com/JAPAN/developer/library/off2000/vbawrd/woproPrintBackground.htm
sakocchi
質問者

お礼

非常に簡単、且つ効果的な手段でした。これでバッチリです。 有難うございました。 ただ、VBAのヘルプではPrintBackgroundの説明が見つからなかったので ちょっと不便さを感じてます。 ヘルプも万能ではないんですね・・・。By初心者

その他の回答 (1)

  • TAGOSAKU7
  • ベストアンサー率65% (276/422)
回答No.1

どもども田吾作7です。 一応EXCEL2000でのサンプル作りました。っていうか、ほとんど参考URLのパクリです。 (http://f-ga.com/Lib/PrintJob.lzh) サンプルプログラムは印刷ジョブを取得するプログラムです。 存在するジョブに、指定のファイルが出したジョブ名が存在したら、スプール完了としてみてはどうでしょうか? (ネットワーク先のプリンタのジョブって見れたっけ?ちと不安・・・) 参考URLではPrinterで通常使うプリンタを使用していますが、Officeでは使用できないので、別の方法で通常使うプリンタを取得しています。 ※サンプルを再現するために必要なもの ユーザーフォーム その中にListBox1とCommandButton1 標準モジュール ******ユーザフォームのソース ここから****** Private Sub CommandButton1_Click() Dim strPrinterDeviceName As String Dim lngPrinterHandle As Long Dim lngJobInfo1FirstJob As Long Dim lngJobInfo1EnumerateJob As Long Dim lngJobInfo1Level As Long Dim lngJobInfo1Needed As Long Dim lngJobInfo1Returned As Long Dim bytJobInfo1Buffer() As Byte Dim udtJobInfo1() As JOB_INFO_1 Dim lngJobInfo1Count As Long Dim bytDocumentBuffer(64) As Byte Dim strDocument() As String Dim strStatus() As String ' リストボックスを初期化 ListBox1.Clear ' 通常使うプリンタ名を取得 strPrinterDeviceName = getConstantPrinter ' プリンタのオブジェクトハンドルを取得 Call OpenPrinter(strPrinterDeviceName, lngPrinterHandle, ByVal vbNullString) ' 最初に列挙する印刷ジョブを指定 lngJobInfo1FirstJob = 0 ' 列挙する印刷ジョブの総数を指定 lngJobInfo1EnumerateJob = 99 ' 構造体のレベルを指定 lngJobInfo1Level = 1 ' バッファの必要なサイズを取得 Call EnumJobs(lngPrinterHandle, lngJobInfo1FirstJob, lngJobInfo1EnumerateJob, lngJobInfo1Level, _ ByVal vbNullString, 0, lngJobInfo1Needed, lngJobInfo1Returned) ' 印刷ジョブが存在する場合は If lngJobInfo1Needed > 0 Then ' バッファを確保 ReDim bytJobInfo1Buffer(lngJobInfo1Needed - 1) ReDim udtJobInfo1(lngJobInfo1Needed - 1) ReDim strUserName(lngJobInfo1Needed - 1) ReDim strDocument(lngJobInfo1Needed - 1) ReDim strStatus(lngJobInfo1Needed - 1) ' 印刷ジョブの情報を取得 Call EnumJobs(lngPrinterHandle, lngJobInfo1FirstJob, lngJobInfo1EnumerateJob, lngJobInfo1Level, bytJobInfo1Buffer(0), _ lngJobInfo1Needed, lngJobInfo1Needed, lngJobInfo1Returned) ' 印刷ジョブが取得できた場合は If lngJobInfo1Returned > 0 Then ' 取得した印刷ジョブの情報を構造体へ移動 MoveMemory udtJobInfo1(0), bytJobInfo1Buffer(0), Len(udtJobInfo1(0)) * lngJobInfo1Returned ' プリンタドライバ情報を切り出し For lngJobInfo1Count = 0 To lngJobInfo1Returned - 1 With udtJobInfo1(lngJobInfo1Count) ' ドキュメント名のアドレスを取得 Call lstrcpy(bytDocumentBuffer(0), ByVal .pDocument) ' ドキュメント名をバイト型から文字列へ変換 strDocument(lngJobInfo1Count) = StrConv(bytDocumentBuffer(), vbUnicode) ' 印刷ジョブの状態を取得 strStatus(lngJobInfo1Count) = "" If .Status And JOB_STATUS_PAUSED Then: If .Status And JOB_STATUS_ERROR Then: If .Status And JOB_STATUS_DELETING Then: If .Status And JOB_STATUS_SPOOLING Then: If .Status And JOB_STATUS_PRINTING Then: If .Status And JOB_STATUS_OFFLINE Then: If .Status And JOB_STATUS_PAPEROUT Then: If .Status And JOB_STATUS_PRINTED Then: If .Status And JOB_STATUS_DELETED Then: If .Status And JOB_STATUS_BLOCKED_DEVQ Then: If .Status And JOB_STATUS_USER_INTERVENTION Then: strStatus(lngJobInfo1Count) = strStatus(lngJobInfo1Count) & "/ユーザ介在" ' 印刷ジョブを表示 ListBox1.AddItem .JobId & "-" & _ Left(strDocument(lngJobInfo1Count), _ InStr(strDocument(lngJobInfo1Count), vbNullChar) - 1) & vbTab & _ strStatus(lngJobInfo1Count) End With Next lngJobInfo1Count Else ListBox1.AddItem "印刷ジョブが取得できません。" End If Else ListBox1.AddItem "印刷ジョブはありません。" End If ' プリンタオブジェクトをクローズ Call ClosePrinter(lngPrinterHandle) End Sub '通常使うプリンタの取得 Function getConstantPrinter() As String Dim strSection As String Dim strKey As String Dim strDefault As String Dim strBuff As String * 1024 ' セクションを指定 strSection = "windows" ' キーを指定 strKey = "device" ' デフォルト値を指定 strDefault = "" ' 取得 Call GetProfileString(strSection, strKey, strDefault, strBuff, Len(strBuff)) getConstantPrinter = Left(strBuff, InStr(strBuff, ",") - 1) End Function ******ユーザフォームのソース ここまで****** ******標準モジュールのソース ここから****** ' プリンタのオブジェクトハンドルを取得する関数の宣言 Public Declare Function OpenPrinter Lib "winspool.drv" Alias "OpenPrinterA" _ (ByVal pPrinterName As String, _ phPrinter As Long, _ pDefault As Any) As Long ' プリンタのオブジェクトハンドルを破棄する関数の宣言 Public Declare Function ClosePrinter Lib "winspool.drv" _ (ByVal hPrinter As Long) As Long ' プリンタの印刷ジョブを列挙する Public Declare Function EnumJobs Lib "winspool.drv" Alias "EnumJobsA" _ (ByVal hPrinter As Long, _ ByVal FirstJob As Long, _ ByVal NoJobs As Long, _ ByVal Level As Long, _ pJob As Any, _ ByVal cdBuf As Long, _ pcbNeeded As Long, _ pcReturned As Long) As Long ' 日付と時刻を定義する構造体 Public Type SYSTEMTIME wYear As Integer wMonth As Integer wDayOfWeek As Integer wDay As Integer wHour As Integer wMinute As Integer wSecond As Integer wMilliseconds As Integer End Type ' 印刷ジョブの情報を定義する構造体 Public Type JOB_INFO_1 JobId As Long pPrinterName As Long pMachineName As Long pUserName As Long pDocument As Long pDatatype As Long pStatus As Long Status As Long Priority As Long Position As Long TotalPages As Long PagesPrinted As Long Submitted As SYSTEMTIME End Type Public Const JOB_STATUS_PAUSED = &H1 Public Const JOB_STATUS_ERROR = &H2 Public Const JOB_STATUS_DELETING = &H4 Public Const JOB_STATUS_SPOOLING = &H8 Public Const JOB_STATUS_PRINTING = &H10 Public Const JOB_STATUS_OFFLINE = &H20 Public Const JOB_STATUS_PAPEROUT = &H40 Public Const JOB_STATUS_PRINTED = &H80 Public Const JOB_STATUS_DELETED = &H100 Public Const JOB_STATUS_BLOCKED_DEVQ = &H200 Public Const JOB_STATUS_USER_INTERVENTION = &H400 ' Windows 95 Only Public Const NO_PRIORITY = 0 Public Const MAX_PRIORITY = 99 Public Const MIN_PRIORITY = 1 Public Const DEF_PRIORITY = 1 ' ある位置から別の位置にメモリブロックを移動する関数の宣言 Public Declare Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" _ (Destination As Any, _ Source As Any, _ ByVal Length As Long) ' 文字列をバッファにコピーする関数の宣言 Public Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" _ (lpString1 As Any, _ lpString2 As Any) As Long 'WIN.INIの中の値を取得 Declare Function GetProfileString Lib "kernel32.dll" _ Alias "GetProfileStringA" _ (ByVal lpAppName As String, _ ByVal lpKeyName As String, _ ByVal lpDefault As String, _ ByVal lpReturnedString As String, _ ByVal nSize As Long) As Long ******標準モジュールのソース ここまで****** もしジョブを得ることが出来なかったら、スプールした時に現れるダイアログウィンドウを監視する方法もあります。こちらの方法はあまりお勧めしませんが、上記の方法で実現不可能だったら、調査してサンプルを作ってみますよ。 でわでわ

参考URL:
http://www.galliver.co.jp/vbtips/sample/vbt0124.html
sakocchi
質問者

お礼

有難うございました。 でも、ちょっと私には難し過ぎたようです。 構造体やバッファを制御する文が見うけられましたが、 これらのプログラムを組み込むには、ちょっと勉強が必要なレベルなんです。 今書いているVBAプログラムよりもこの処理文だけで それを遥かに越えてしまってるようで・・・。 でもレベルがあがったら参考にしたと思います。

関連するQ&A

  • (*_*) Windowsで、「スプール中は削除できません」「スプール中は終了できません」と・・・? 「スプール」とは?

     デスクトップのVALUESTARに、Win98SEが入ってます。うっかりプリンタ(Canon BJ-F300)のスイッチを切ったまま、印刷開始のボタンを押したため、パソコンのきげんがわるく(?)なったようです。  すぐにプリンタのスイッチを入れて、リセットボタンを押しても、印刷できませんでした。  削除しようとすると「スプール中は削除できません」と表示が出ますし、Windoowsを終了しようとすると「スプール中はBJバックグラウンドモニタを終了できません」と表示が出て、こまっています。  とにかくパソコンを終了させたいのですが、どうしたらいいんでしょうか? 印刷のことなんか、もうどうでもいいのですが……

  • スプールの中身を印刷。

    たとえば、エクセルのデータを印刷します。そのときプリンタの電源を切っておきます。そうするとスプールに印刷データがたまってます。エクセルのデータを保存しないで終了させます。 その時、スプールにたまってるデータをエクセルで見ることは出来ますか?

  • TR9530でスプールがある状態だと印刷ができない

    TR9530で印刷を実行すると、スプールされているデータがある場合に印刷が部分的にしかされない状況が起きています。 プリンタのプロパティから「プリンターに直接印刷データを送る」にすれば印刷はできるのですが、基本的にはスプールは有効化して使いたいと考えています。 考えられる原因と対策について、ご教示いただけますでしょうか。 ※OKWAVEより補足:「キヤノン製品」についての質問です。

  • スプール中がすぐ消えて印刷できない

    プリンター DCP-J968N パソコン dynabook(東芝) ウィンドウズ10 パソコンとプリンター接続方法 無線LAN(Wi-Fi) 大学の講義資料(PowerPointのスライド50枚ほど)を印刷しようとしています。モノクロ、a4、両面印刷、1ページに4スライドです。 印刷ボタンを押すと、スプール中が表示された後すぐに消えてしまい、印刷したい物も消えます。 初めは容量が大きいのかなと思って、1~8枚のスライド、つまり両面1枚を印刷しようとすると、何回かチャレンジの後、印刷できました。 ですがそれから先が全く印刷できないです。 他のドキュメントは残っておらず、相変わらずスプール中がすぐ消えて印刷したい物が消える…エンドレスです。 プリンターの電源を切ったり、パソコンを再起動したり、ルーターを切ったりしましたが改善しませんでした。 どなたか改善方法を知っている方いましたら教えてください。 他のpdf、ワード等は、問題なく印刷できます。 ※OKWAVEより補足:「ブラザー製品」についての質問です。

  • プリンタのスプール設定について

    プリンタのプロパティで[詳細設定]というタグの中に ・印刷ドキュメントをスプールし、プログラムの印刷処理を高速に行う とありますが、標準設定ではスプールする様になってます。印刷時の問題により「プリンタに直接印刷データを送る」に設定変更していますがこの場合なにか問題(スプール設定でなければいけないような)があるのでしょうか? 注意しなければならないことなどありましたら教えてください。 よろしくお願いします。

  • WindowsXPでの印刷でスプール中

    図入りWord文書(800KB/9ページ)を印刷するとき、 Windows2000では印刷できますが、WindowsXPではスプール中となり固まります。ただ、7ページくらいにすると、WindowsXPでも印刷できます。 NECと富士ゼロックスのプリンターで試し、パソコンもXP、2000とも2台ずつ試しましたが、同様の現象でした。OSが新しくなったのに、印刷できる範囲が狭くなるのは非常に納得できないのですが、そういうものでしょうか?それとも設定変更により改善できるのでしょうか?はたまた私の勘違いでしょうか? すみませんが、よろしくお願いします。

  • PCがスプール処理をせず,突然ダイレクト印刷になった

    PCコーナーとプリンタコーナーどっちに質問した方が的確か迷いました。(管理人様すみません) プリンタはNEC MaltiWriter2050,使用OSはWin95です。シリアルで直につないでいます。 プリンタへのデータ転送が突然遅くなりました。昨日までは,ちゃんとスプール処理をしていたのですが,今日から突然ダイレクト印刷になってしまい,大量印刷の場合など,その間中PCが使えません。 ちなみに,このプリンタには他にMeやXPもLAN使用していますが,他のPCからはちゃんとスプール処理します。 なにが原因かご存知の方,解決法か,解決法のあるサイトを教えていただければ幸いです。 また補足不足があればご指示ください。

  • 印刷スピードについて スプール 筆王 筆休め

    質問致します。 印刷についてですが、 プリンタ:HP Photosmart C7180 を使用しております。 各種ソフトウェアで(WORD、EXCEL、はがきソフト等)印刷開始ボタンを押し 印刷データがスプールされ、まとめて印刷されたりしますが、 その際、ソフトによってスプールの出力される方法が違います。 下記に例を4個あげましたが、 スプールドキュメント自体はどのパソコン・プリンタも同じだと思います。 それで問題なのが、印刷スピードです。 スプールドキュメントの個数が多いと印刷に時間が掛かってしまいます。 その原因はHPのプリンタがスプールドキュメント1個毎に、 ウィーン♪ガチャン♪ガチャ♪ウィーン♪ウィーン♪ガチャン♪ガチャ♪ウィーン♪ と音を立ててウォーミングアップをしてしまい動作・印刷が遅いのです。 ★★★ただ、例:WORDや例:はがきソフト(筆休め1999)では 部数分をスプールドキュメント1個にまとめて印刷される為、 ウォーミングアップをせず連続して印刷され動作・印刷が速いです。 これはプリンタの性能・構造に問題もあるかと思いますが、 以前SHARP AJ-6010(HPの製品よりだいぶ古い6、7年前の物です。)を使用しており、 HPのプリンタの方がかなり遅くなりました。 パソコン自体 Pen4 3.8GHz HT MEM 1GB なので、快適です。 長くなりましたが、このスプールドキュメンを解決したいのです。 印刷関連のソフトウェアで解決できる方法などありましたら教えて下さい。 (スプールドキュメントを一括に圧縮・まとめるなど) その他、設定によって解決方法があればそれでもかまいません。 尚、筆王2003はi4時代の物で、筆休め1999はソースネクストの物で 今ソースネクストから筆王ZEROが出ていますが、スプールドキュメントの状況はどうなっていますでしょうか?また、筆休めは2006まで出ていますが、他はがきソフトについて状況を、 お持ちの方教えて下さい。 上記の通りソフトウェアや設定方法で解決出来れば、その他の同様の事態にも対応出来るかと思いますので、一番良いです。 宜しくお願い致します。 例:WORD 文章1ページを印刷する 部数5にする 印刷開始でスプールドキュメントが1個、ページ数が1/5となり印刷されます。 ドキュメント名 状態 所有者 ページ数 サイズ ... サンプルWORD  印刷中 USERNAME 1/5   ○○MB ... 例:EXCEL 1ページを印刷する 部数5にする 印刷開始でスプールドキュメントが5個、ページ数が1/1となり印刷されます。 ドキュメント名 状態 所有者 ページ数 サイズ ... サンプルEXCEL 印刷中 USERNAME 1/1   ○○MB ... サンプルEXCEL     USERNAME 1/1   ○○MB ... サンプルEXCEL     USERNAME 1/1   ○○MB ... サンプルEXCEL     USERNAME 1/1   ○○MB ... サンプルEXCEL     USERNAME 1/1   ○○MB ... 例:はがきソフト(筆王2003(Ver.7.0)) 表面(宛名)50件(名)を印刷する 印刷開始でスプールドキュメントに50個、ページ数が1/1となり印刷されます。 ドキュメント名 状態 所有者 ページ数 サイズ ... サンプル筆王  印刷中 USERNAME 1/1   ○○MB ... サンプル筆王      USERNAME 1/1   ○○MB ... サンプル筆王      USERNAME 1/1   ○○MB ... サンプル筆王      USERNAME 1/1   ○○MB ... サンプル筆王      USERNAME 1/1   ○○MB ... ...............以下45個 例:はがきソフト(筆休め1999) 表面(宛名)50件(名)を印刷する 印刷開始でスプールドキュメントに1個、ページ数が1/50となり印刷されます。 ドキュメント名 状態 所有者 ページ数 サイズ ... サンプル筆休め 印刷中 USERNAME 1/50   ○○MB ...

  • Excel VBA の印刷後の判定

    いつもお世話になっています。 Excel VBA で不明な点が出てきたので質問させていただきます。 処理順として 1.AccessからExcelを出力し、出力後はそのまま表示しておく。 2.表示してあるExcelをユーザーが印刷する。 3.印刷したシートの見出しの色を変更する。 の3つなのですが、3の処理をExcelマクロで実行する際に、 印刷が実行されたかどうかの判別方法がわからないのです。 印刷直前でも構わないと思い、BeforePrint イベントを調べて使用してみたのですが、 印刷プレビューでもイベントが走ってしまい、ダメでした。 印刷実行なのか、プレビューなのか区別が出来る方法があればとも思っているのですが…。 ご存知の方、ご教授お願いいたします。

  • VBAで印刷の成功判定

    Excel2003でVBAをくんでいます。 印刷の成功判定を行いたくて、以下のFunctionをくみました。(印刷失敗時にFalseを返したい)しかし、印刷する処理で、実行エラーが発生してしまいます。 原因がわかりません。どなたかお教えください。よろしくお願いします。 '決裁処理用自動印刷機能 印刷処理の成功失敗を知りたい Function PrintAuto() PrintAuto = True '通常使うプリンタで印刷 Arrayに複数シート設定 Sheets(Array(SHEET_DETAIL1, SHEET_DETAIL2, SHEET_DETAIL3)).Select Sheets("ほげほげ").Activate ↓ここでコンパイルエラー発生(Functionまたは変数が必要です) PrintAuto = ActiveWindow.SelectedSheets.PrintOut(Copies:=1, Collate:=True) Sheets(SHEET_DETAIL1).Select Sheets(SHEET_DETAIL1).Activate End Function