ポート名(?)付きのプリンタ名を返すFunction


ポート名(?)付きのプリンタ名を返すFunction

前回、

akashi-keirin.hatenablog.com

前々回

akashi-keirin.hatenablog.com

の集大成。

コード

プリンタの名前を渡したら、ポート名(?)付きのプリンタ名を返すFunctionを作ってみた。

前回同様、オブジェクト名は「InstalledPrinter」とし、PredeclaredIdTrueにしている。

リスト1 クラスモジュール
Public Function getPrinterNameWithPort( _
                  ByVal printerName As String) As String
  getPrinterNameWithPort = ""
  Dim printersCount As Long
  printersCount = getPrintersCount
  Dim tmp As String
  tmp = Application.ActivePrinter
  On Error Resume Next
  Dim i As Long
  For i = 0 To printersCount - 1    '……(1)'
    Dim ret As String
    ret = printerName & " on Ne" & Format(i, "0#") & ":"
    If Me.isExistPrinter(ret) Then GoTo Finalizer
    Err.Clear
  Next
  ret = printerName & " on nul:"    '……(2)'
  If Not Me.isExistPrinter(ret) Then ret = ""
Finalizer:
  On Error GoTo 0
  Application.ActivePrinter = tmp
  getPrinterNameWithPort = ret
End Function

Public Function getPrintersCount() As Long
  Dim shellApp As New Shell
  getPrintersCount = shellApp.Namespace(ssfPRINTERS).Items.Count
  Set shellApp = Nothing
End Function

Public Function isExistPrinter( _
                  ByVal printerName As String) As Boolean
  isExistPrinter = False
  Dim tmp As String
  tmp = Application.ActivePrinter
  On Error Resume Next
  Application.ActivePrinter = printerName
  Application.ActivePrinter = tmp
  If Err.Number > 0 Then Exit Function
  On Error GoTo 0
  isExistPrinter = True
End Function

(1)からの6行

For i = 0 To printersCount - 1
  Dim ret As String
  ret = printerName & " on Ne" & Format(i, "0#") & ":"
  If Me.isExistPrinter(ret) Then GoTo Finalizer
  Err.Clear
Next

Forループで、 on NeXX:の「XX」の部分をインクリメントしながらプリンタ名に附加してisExistPrinterメソッドで判定。

存在するプリンタ名だったら、ループを抜けてreturn。

(2)からの2行

ret = printerName & " on nul:"
  If Not Me.isExistPrinter(ret) Then ret = ""

これは、プリンタ名の末尾が

f:id:akashi_keirin:20180929193941j:plain

のように「 on nul:」となっていることがあるために追加。

Forループを抜けるということは、プリンタ名がヒットしていないということだから、最後の手段としてプリンタ名に「 on nul:」を附加することを試みる。

これでダメなら「""」を返す。

実行

イミディエイト・ウインドウに、それぞれ次のように入力して[Enter]をぶっ叩く。

?InstalledPrinter.getPrinterNameWithPort("Microsoft XPS Document Writer")

?Application.ActivePrinter

?InstalledPrinter.getPrinterNameWithPort("Microsoft Print to PDF")

?InstalledPrinter.getPrinterNameWithPort("Send To OneNote 2013")

実行結果は次の通り。

f:id:akashi_keirin:20180929194023j:plain

f:id:akashi_keirin:20180929194031j:plain

f:id:akashi_keirin:20180929194037j:plain

f:id:akashi_keirin:20180929194045j:plain

おわりに

Shellを使ったら、プリンタ名の取得はできるので、ユーザーフォームでプリンタ名を選ばせるかして、このFunctionと組みあわせたら、端末を問わずにプリンタを適切に指定できるようになるのではなかろうか。

ただ、プリンタのことがよく分かっていないので、ポート名(?)が網羅できているかは自信がない。