• ベストアンサー

プリンタが通信可能か調査する

EXCELのVBAで、シートを自動印刷するような処理を作成したのですが、 実際に印刷をかける前にプリンタと通信可能、ケーブルが接続されている・ プリンタの電源が入っているなどのチェックをかける処理を入れたいのですが どのことは可能なのでしょうか?

noname#149114
noname#149114

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

  • ベストアンサー
  • arata
  • ベストアンサー率49% (139/279)
回答No.1

APIを使えば、できなくなないのですが、結構 難しいです。難しい割に、あまり使えません。 というのは、ステータスを聞きにいっても、プリンタ に問い合わせを行うわけでなく、現在のプリント マネージャの知っている状態で答えが返ってくる ためで、あたりまえですが、紙がきれていても、 エラーが発生してなければ、エラーとはなりません。 という訳ですが、一応プログラムをつけておきます。 はっきりいって、テスト不足です。実際にお使いに なる場合は、チェックをしてからにしてください。 Option Explicit ' プリンタアクセス権を定義する構造体の宣言 Private Type PRINTER_DEFAULTS pDatatype As Long pDevMode As Long DesiredAccess As Long End Type ' 標準的な権利を要求することを示す定数の宣言 Private Const STANDARD_RIGHTS_REQUIRED = &HF0000 ' プリンタアクセス権の管理者権限を示す定数の宣言 Private Const PRINTER_ACCESS_ADMINISTER = &H4& ' プリンタアクセス権のユーザー権限を示す定数の宣言 Private Const PRINTER_ACCESS_USE = &H8& ' プリンタアクセス権すべての権限を示す定数の宣言 Private Const PRINTER_ALL_ACCESS = _ (STANDARD_RIGHTS_REQUIRED Or _ PRINTER_ACCESS_ADMINISTER Or _ PRINTER_ACCESS_USE) ' プリンタのオブジェクトハンドルを取得する関数の宣言 Private Declare Function OpenPrinter Lib "WINSPOOL.DRV" _ Alias "OpenPrinterA" _ (ByVal pPrinterName As String, _ phPrinter As Long, _ pDefault As Any) As Long ' 詳細なプリンタ情報を定義する構造体の宣言 Private Type PRINTER_INFO_2 pServerName As Long pPrinterName As Long pShareName As Long pPortName As Long pDriverName As Long pComment As Long pLocation As Long pDevMode As Long pSepFile As Long pPrintProcessor As Long pDatatype As Long pParameters As Long pSecurityDescriptor As Long Attributes As Long Priority As Long DefaultPriority As Long StartTime As Long UntilTime As Long Status As Long cJobs As Long AveragePPM As Long End Type ' プリンタの詳細な情報を取得する関数の宣言 Private Declare Function GetPrinter Lib "WINSPOOL.DRV" _ Alias "GetPrinterA" _ (ByVal hPrinter As Long, _ ByVal Level As Long, _ pPrinter As Any, _ ByVal cbBuf As Long, _ pcbNeeded As Long) As Long ' 日付と時刻を定義する構造体の宣言 Private 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 ' 印刷ジョブ情報を定義する構造体の宣言 Private 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 ' 一時停止を示す定数の宣言 Private Const JOB_STATUS_PAUSED = &H1 ' エラーを示す定数の宣言 Private Const JOB_STATUS_ERROR = &H2 ' 削除中を示す定数の宣言 Private Const JOB_STATUS_DELETING = &H4 ' スプールを示す定数の宣言 Private Const JOB_STATUS_SPOOLING = &H8 ' 印刷中を示す定数の宣言 Private Const JOB_STATUS_PRINTING = &H10 ' オフラインを示す定数の宣言 Private Const JOB_STATUS_OFFLINE = &H20 ' 用紙切れを示す定数の宣言 Private Const JOB_STATUS_PAPEROUT = &H40 ' 完了を示す定数の宣言 Private Const JOB_STATUS_PRINTED = &H80 ' 削除を示す定数の宣言 Private Const JOB_STATUS_DELETED = &H100 ' ドライバエラーを示す定数の宣言 Private Const JOB_STATUS_BLOCKED_DEVQ = &H200 ' 機器不良を示す定数の宣言 Private Const JOB_STATUS_USER_INTERVENTION = &H400 ' 再起動中を示す定数の宣言 Private Const JOB_STATUS_RESTART = &H800 ' プリンタの印刷ジョブを列挙する関数の宣言 Private 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 ' ある位置から別の位置にメモリブロックを移動する関数の宣言 Private Declare Sub MoveMemory Lib "kernel32.dll" _ Alias "RtlMoveMemory" _ (Destination As Any, _ Source As Any, _ ByVal length As Long) ' 文字列をバッファにコピーする関数の宣言 Private Declare Function lstrcpy Lib "kernel32.dll" _ Alias "lstrcpyA" _ (lpString1 As Any, _ lpString2 As Any) As Long ' プリンタのオブジェクトハンドルを破棄する関数の宣言 Private Declare Function ClosePrinter Lib "WINSPOOL.DRV" _ (ByVal hPrinter As Long) As Long Private Const PRINTER_STATUS_BUSY = &H200 Private Const PRINTER_STATUS_DOOR_OPEN = &H400000 Private Const PRINTER_STATUS_ERROR = &H2 Private Const PRINTER_STATUS_INITIALIZING = &H8000 Private Const PRINTER_STATUS_IO_ACTIVE = &H100 Private Const PRINTER_STATUS_MANUAL_FEED = &H20 Private Const PRINTER_STATUS_NO_TONER = &H40000 Private Const PRINTER_STATUS_NOT_AVAILABLE = &H1000 Private Const PRINTER_STATUS_OFFLINE = &H80 Private Const PRINTER_STATUS_OUT_OF_MEMORY = &H200000 Private Const PRINTER_STATUS_OUTPUT_BIN_FULL = &H800 Private Const PRINTER_STATUS_PAGE_PUNT = &H80000 Private Const PRINTER_STATUS_PAPER_JAM = &H8 Private Const PRINTER_STATUS_PAPER_OUT = &H10 Private Const PRINTER_STATUS_PAPER_PROBLEM = &H40 Private Const PRINTER_STATUS_PAUSED = &H1 Private Const PRINTER_STATUS_PENDING_DELETION = &H4 Private Const PRINTER_STATUS_PRINTING = &H400 Private Const PRINTER_STATUS_PROCESSING = &H4000 Private Const PRINTER_STATUS_TONER_LOW = &H20000 Private Const PRINTER_STATUS_USER_INTERVENTION = &H100000 Private Const PRINTER_STATUS_WAITING = &H2000 Private Const PRINTER_STATUS_WARMING_UP = &H10000 Private Sub GetPrintStatus() If IsPrinterError() Then MsgBox "エラーです。" Else MsgBox "プリンタは正常です。" End If End Sub ' ' プリンタにエラーが発生しているとTrueを返す関数 ' Function IsPrinterError() As Boolean Dim strPrinterDeviceName As String Dim udtPrinterDefaults As PRINTER_DEFAULTS 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 lngWin32apiResultCode As Long Dim lngPrinterInfo2Level As Long Dim lngPrinterInfo2Needed As Long Dim bytPrinterInfo2Buffer() As Byte Dim udtPrinterInfo2 As PRINTER_INFO_2 Dim sPrinterName As String IsPrinterError = False ' プリンタ名を指定 ' VBの場合は、Printer.DeviceNameでOK ' strPrinterDeviceName = _ ' Printer.DeviceName sPrinterName = Application.ActivePrinter If InStr(sPrinterName, " on ") > 0 Then sPrinterName = Left(sPrinterName, InStr(sPrinterName, " on ") - 1) End If If InStr(sPrinterName, " の ") > 0 Then sPrinterName = Left(sPrinterName, InStr(sPrinterName, " の ") - 1) End If strPrinterDeviceName = _ sPrinterName ' プリンタアクセス権を指定 With udtPrinterDefaults .DesiredAccess = PRINTER_ALL_ACCESS End With ' プリンタのオブジェクトハンドルを取得 lngWin32apiResultCode = _ OpenPrinter(strPrinterDeviceName, _ lngPrinterHandle, _ udtPrinterDefaults) ' 構造体のレベルを指定 lngPrinterInfo2Level = 2 ' バッファに必要なサイズを取得 lngWin32apiResultCode = _ GetPrinter(lngPrinterHandle, _ lngPrinterInfo2Level, _ ByVal vbNullString, _ 0, _ lngPrinterInfo2Needed) ' バッファを確保 ReDim _ bytPrinterInfo2Buffer _ (lngPrinterInfo2Needed - 1) ' 詳細なプリンタ情報を取得 lngWin32apiResultCode = _ GetPrinter(lngPrinterHandle, _ lngPrinterInfo2Level, _ bytPrinterInfo2Buffer(0), _ lngPrinterInfo2Needed, _ lngPrinterInfo2Needed) ' 取得した詳細なプリンタ情報を構造体へ移動 MoveMemory _ udtPrinterInfo2, _ bytPrinterInfo2Buffer(0), _ Len(udtPrinterInfo2) 'プリンタのステータスの取得 If udtPrinterInfo2.Status And _ (PRINTER_STATUS_ERROR Or _ PRINTER_STATUS_PAPER_JAM Or _ PRINTER_STATUS_PAPER_OUT Or _ PRINTER_STATUS_PAPER_PROBLEM Or _ PRINTER_STATUS_OUTPUT_BIN_FULL Or _ PRINTER_STATUS_NOT_AVAILABLE Or _ PRINTER_STATUS_NO_TONER Or _ PRINTER_STATUS_OUT_OF_MEMORY Or _ PRINTER_STATUS_OFFLINE Or _ PRINTER_STATUS_DOOR_OPEN) <> 0 Then MsgBox "プリンタステータス=" & Hex$(udtPrinterInfo2.Status) IsPrinterError = True GoTo TerminateEnumJobs End If ' 最初に列挙する印刷ジョブを指定 lngJobInfo1FirstJob = 0 ' 列挙する印刷ジョブの総数を指定 lngJobInfo1EnumerateJob = 99 ' 構造体のレベルを指定 lngJobInfo1Level = 1 ' バッファに必要なサイズを取得 lngWin32apiResultCode = _ EnumJobs(lngPrinterHandle, _ lngJobInfo1FirstJob, _ lngJobInfo1EnumerateJob, _ lngJobInfo1Level, _ ByVal vbNullString, _ 0, _ lngJobInfo1Needed, _ lngJobInfo1Returned) ' 印刷ジョブが取得できないときは If lngJobInfo1Needed <= 0 Then IsPrinterError = False ' 取得できないときの終了処理へ分岐 GoTo TerminateEnumJobs End If ' バッファを確保 ReDim _ bytJobInfo1Buffer _ (lngJobInfo1Needed - 1) ' 印刷ジョブ情報を取得 lngWin32apiResultCode = _ EnumJobs(lngPrinterHandle, _ lngJobInfo1FirstJob, _ lngJobInfo1EnumerateJob, _ lngJobInfo1Level, _ bytJobInfo1Buffer(0), _ lngJobInfo1Needed, _ lngJobInfo1Needed, _ lngJobInfo1Returned) ' 取得した印刷ジョブ情報の構造体を確保 ReDim _ udtJobInfo1 _ (lngJobInfo1Returned - 1) ' 取得した印刷ジョブ情報を構造体へ移動 MoveMemory _ udtJobInfo1(0), _ bytJobInfo1Buffer(0), _ Len(udtJobInfo1(0)) * lngJobInfo1Returned ' バッファに印刷ジョブ情報がある間は For lngJobInfo1Count = 0 To lngJobInfo1Returned - 1 ' 状態を表示 If udtJobInfo1 _ (lngJobInfo1Count).Status And _ JOB_STATUS_PRINTING Then If udtJobInfo1 _ (lngJobInfo1Count).Status And _ (JOB_STATUS_ERROR Or _ JOB_STATUS_OFFLINE Or _ JOB_STATUS_PAPEROUT Or _ JOB_STATUS_BLOCKED_DEVQ) Then MsgBox "プリンタジョブステータス=" & Hex$(udtJobInfo1(lngJobInfo1Count).Status) IsPrinterError = True Exit For End If End If Next TerminateEnumJobs: ' プリンタオブジェクトをクローズ lngWin32apiResultCode = _ ClosePrinter(lngPrinterHandle) End Function

関連するQ&A

  • プリンターと通信できません

    MG3630を使っています。スマホとプリンターのダイレクト印刷ですが「プリンターと通信できません」とスマホに表示されて印刷できません。数日前まで問題なく印刷できていたのですが。電源を入れたり切ったりしてみましたが変化なく困っています。 ※OKWAVEより補足:「キヤノン製品」についての質問です。

  • 通常使うプリンタを変更したい

    Access2000にて、フォームで画面に表示したデータを Excelに出力し、そのExcelシートを印刷する プログラムを作成しています。 (一連の処理はフォームのモジュールで記述しています) Excelシートを印刷する際に、プログラムを使う ユーザー毎に使用するプリンタドライバを定めています。 (別のテーブルにそのプリンタドライバの情報は持たせて 印刷する前にそのテーブルを参照します) ユーザー毎に出力するプリンタを変更させたいのですが、 通常使うプリンタの変更をAccess2000で記述するには どのようにしたらいいのでしょうか? あと、ユーザー毎に別テーブルに設定した プリンタドライバがインストールされているかどうかの チェックをし、インストールされていなければ メッセージを表示する処理も合わせて行いたいのですが、 こちらもどのようにすればよろしいのでしょうか? わかりづらい文章になってしまってすいません。 どうぞよいアドバイスを宜しくお願いします。

  • プリンタに通信できません

    プリンタに通信できません と出て、印刷されません。 プリンタ側でノズルチェックをさせても 出ず、 Network Configuration Page が出てきます。 電源の入り切りは何度も試しました PCだけでなく、スマホからもプリントできなくなりました。 原因が全くわかりません よろしくお願い致します。 ※OKWAVEより補足:「キヤノン製品」についての質問です。

  • プリンターと通信できません。

    キャノンMP610です。プリンターの電源を入れて、印刷開始すると、【プリンターと通信できません。 双方向通信をサポートする設定にしてください」とメッセージが出ます。しかし、印刷はできます。 でも毎回のエラーメッセージがうるさいのです。何とかなりませんか。

  • プリンタと通信できない

    CanonBJF600を新しいパソコンに認識させようとしても、認識してくれません。詳しい状況は以下のとおりです。 M/BはAOpenのAX3SMAXです。OSは2年ぐらい前に買ったWindows2000proをSP3にアップグレードしたものです。そもそもドライバを入れずに起動したときに自動認識にかからないこともおかしいのですが、BJF600のプリンタドライバの最新版をダウンロードしてインストールしても、プリンタのステイタスモニタを開くとプリンタと通信できないと表示されます。デバイスマネージャーでプリンタポートのプロパティを見ても正常に動作していると表示されます。 ではプリンタ自体がおかしいのかと思い、このプリンタをプリンタケーブルも同じもので別のノートPCのWindowsMeの環境で、WindosMe用のドライバをダウンロードしてインストールすると認識されます。 なんかもうSP3のバグではないかという疑いまで感じ始めてしまっています。ただバグだといいはれるほど上級者でもないし・・・ 電源が入っているか、接続が正しいかなどは何度もみなおしました。一体どうなっているんでしょうか? この場で手取り足取り教えていただくのは無理でしょうから、私がチェックし忘れていそうなところを「ここは見たか、あそこは見たか」といった感じで指摘していただくとやり易いです。 よろしくお願いします。

  • EPSONプリンターの通信エラー

    エプソンのLP-6100のプリンターを購入しました。 XPのPCへ接続(パラレル接続)し、印刷は正常に終了します。ですが、プリンターを共有し、他のPC(95,98,XP)より印刷すると、「通信エラーが発生しました。ケーブル、電源の状態を確認して下さい。」のメッセージが表示されます。OKを押せば印刷できますが、原因がわかりません。このエラーメッセージは印刷しなくても、共有プリンターのプロパティを表示する時も必ずエラーが表示します。また、パラレル接続ではなく、USB接続にしても同様のメッセージが表示されます。

  • プリンターの通信エラー

    4年ほど前に購入した、FMV DESKPOWER WIN98にNECのPICTY700をつないで使っています。 今までのプリンターの使用頻度は、少ない方です。 先月、プリンターの清掃をしてから調子が悪く、だましだまし使っていたのでが、デジカメを購入し付属のCD-R PIXELA imagemixerをインストールしてから、さらに調子が悪くなったようです。 今の状態は、印刷ボタンを押すと、用紙がプリンターには入っていくのですが、その後エラー表示が出て、「プリンターとの通信が出来ません」と出ます。途中まで印刷できて、その後エラーが出る場合もあります。 アドバイス通りに、プリンターとPCを、再起動してもう一度してみても同じです。 印刷を中止して、プリンターとの通信テストをすると正常と出るのですが、その後すぐに印刷をしようとしても、また同じエラーが出ます。 もう一つのエラーは、何も触っていない状態で、プリンターのスイッチをオフにしないで、電源が切られましたというメッセージも、時々出ます。 プリンタドライバを一度削除し、再インストールしても同じです。 ケーブルもきちんと接続してあります。 年賀状の印刷も控えてますので、早急に解決したいと思っていますので、よろしくお願い致します。

  • プリンタ通信ができません

    パソコンがウィルスチェック中にフリーズ。電源ボタン長押しでシャットダウンし再起動したところ、立ち上がらず、結局ウィンドウズを再インストールしました。プリンタドライバーもダウンロードしプリンタ設定したのですが、プリンタとの通信ができないとのエラーメッセージが出て印刷できません。対処法を教えてください。 ※OKWaveより補足:「キヤノン製品」についての質問です。

  • エクセルに関連付けられたプリンタ情報削除

    VBAでエクセルのファイルに有るプリンタ情報を消すことは可能でしょうか? office2010をWindowsXPで使用しているのですが、 会社内で色々な部署からエクセルファイルをもらって、チェックをして、 別の部署に引き渡すという作業をしています。 最終的に引き渡された部署(40箇所ぐらい)の方々が、ファイルを印刷するのですが、 印刷情報がエクセルに組み込まれているファイルがあるようで、 白黒で出てくる、両面印刷で出てくる、トナーセーブで出てくる、 想定外のプリンタから出てくるなどクレームが上がってくる事があります。 月に800ファイルほどチェックするので、1つずつ対処するのは大変です。 そこでVBAでプリンタ情報を消すことは可能でしょうか? 処理するパソコンのデフォルトの設定で印刷できるようにしたいです。 沢山のファイルを一気にチェックするVBAなどは作ってあるので、 それに組み込もうと思います。 よろしくお願いします。

  • キャノンプリンター 通信できない

    キャノンプリンターMG6730でのスキャンができません。 通常の印刷はできるのですが、スキャンしようと思うと、次のようなメッセージが出てきて 止まってしまいます。 概略は 以下の理由でスキャナーと通信できません。 電源が入っていない LANに接続されていない スキャナーを選択しなさい code5,157,69 以上のようなことです。 電源は当然入っていますし、印刷はできるので接続もされています。 以上のことから何かわかることがあれば教えてください。 よろしくお願いします。