OKWAVEのAI「あい」が美容・健康の悩みに最適な回答をご提案!
-PR-
解決
済み

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

  • すぐに回答を!
  • 質問No.120709
  • 閲覧数2858
  • ありがとう数1
  • 気になる数0
  • 回答数1
  • コメント数0

EXCELのVBAで、シートを自動印刷するような処理を作成したのですが、
実際に印刷をかける前にプリンタと通信可能、ケーブルが接続されている・
プリンタの電源が入っているなどのチェックをかける処理を入れたいのですが
どのことは可能なのでしょうか?
通報する
  • 回答数1
  • 気になる
    質問をブックマークします。
    マイページでまとめて確認できます。

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

  • 回答No.1
レベル11

ベストアンサー率 49% (139/279)

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
-PR-
-PR-
このQ&Aのテーマ
このQ&Aで解決しましたか?
関連するQ&A
-PR-
-PR-
こんな書き方もあるよ!この情報は知ってる?あなたの知識を教えて!
このQ&Aにはまだコメントがありません。
あなたの思ったこと、知っていることをここにコメントしてみましょう。

その他の関連するQ&A、テーマをキーワードで探す

キーワードでQ&A、テーマを検索する
-PR-
-PR-
-PR-

特集


いま みんなが気になるQ&A

関連するQ&A

-PR-

ピックアップ

-PR-
ページ先頭へ