2022年7月15日金曜日

同一機種で複数が登録されたネットワークプリンタを、VBAでちゃんと指定できるコードは、かなり難儀なのであった ー Application.ActivePrinter(VBA)

     
PostScriptは、英語で”追伸”を意味しますが、文中では”P.S.”と表現しますね。
一方、コンピュータの世界では、印刷に使用されるページ記述言語の意味です。

なぜ、追伸の意味が使われるのかは、PCがデータを送信する役目だけだから。
つまり、後書きのようにプリンタにあるこの言語が、データを処理印刷します。

そんな意味を込めてAdobe社が開発し命名しましたが、今やスタンダードです。
一方、紙の媒体へプリントする以外で、この方式はPDFの出力でも使われます。

これも同社がPostScriptと共に開発したものですが、電子文書ファイルの形式。
実際に、PCでPDFファイルを作成したかったら、作業は印刷とほぼ同じです。

結果が電子ファイルになるだけで、このプロセスにもPostScriptが使われるな。
実際に、エクセルで作ろうと思えば、印刷設定でPDFドライバーを選びますね。

例えば、”Micorosoft Print to PDF”は、その印刷のための下層ドライバーです。
けれども、プリンターと同じ扱いになっていて、設定上、ポート番号があるの。

ちゃんと振られていて、自分のは、”Microsoft Print to PDF on Ne02:”です。
他にも、”CubePDF on Ne06:”や”DocuWorks PDF on Ne07:”が存在するな。

実際、こういうPDFファイルのアプリは、使わなくなると削除したりもします。
その結果、ポート番号が変わってしまい、VBAのコードでも問題が発生したり。

例えば、”Application.ActivePrinter”のコマンドは、ポート番号も指定します。
この番号は、登録の順番で付けられているようですが、この増減で変化もする。

[ プリンター指定方法 ]
 Application.ActivePrinter = "Canon Printer on Ne02:"  'ポート番号付指定
 ActiveSheet.PrintOut ActivePrinter:="¥¥http://アドレス¥プリンタ名"
 Application.Dialogs(xlDialogPrint).Show 'プリンタ選択ダイアログで指定

つまり、不要になったPDFのアプリを削除すると、番号が変化してしまうんだ。
他方、このポート番号の要らない設定方法もあるのですが、ここで気が付いた。

それは、ネットワークプリンタ―で、同一モデルがPCに登録されている場合。
つまり、同じフロアで距離を置いて配置されて、IPアドレスの違いだけとか。

こういった場合、ポート番号を指定しないと目的のプリンターで印刷できない。
ダイアログでプリンターの選択を呼び出すコマンドもあるが、上手く行かない。

できたりできなかったりと動作が不安定なのを実際に実験して確認できました。
となれば、印刷に使うプリンタをポート番号込みで探し当てるコマンド作りだ。

という分けで、ネットで色々探しつつ、参考にしながら書き上げてみましたな。
これを使えば、VBAコードで、複数登録された同一機種を、IPアドレスの違いで見分けながら、目的の機種登録をポート番号が付いた内容で取得して指定させられるので、ポート番号が変わっても随時対応できるなと、自画自賛してしまったのでした。

※サンプルコード
Option Explicit 'モジュールの記述先頭から(ここはネットからパクリ)
Private Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias _
"RegOpenKeyExA" _
    (ByVal hKey As Long, ByVal lpSubKey As String, _
    ByVal ulOptions As Long, ByVal samDesired As Long, _
    phkResult As Long) As Long
Private Declare Function RegCloseKey Lib "advapi32.dll" _
(ByVal hKey As Long) As Long
Private Declare Function RegQueryValueEx Lib _
"advapi32.dll" Alias "RegQueryValueExA" (ByVal hKey As Long, _
ByVal lpValueName As String, ByVal lpReserved As Long, _
lpType As Long, lpData As Any, lpcbData As Long) As Long
Private Const KEY_QUERY_VALUE = &H1
Private Const HKEY_CURRENT_USER = &H80000001

Private Function RegRead_API(lRoot As Long, sSubRoot As String, _
sEntryName As String) As String 'レジストリを開く・読み込む・閉じる
Dim lRet As Long, hWnd As Long, sVal As String
    hWnd = Application.hWnd
    lRet = RegOpenKeyEx(lRoot, sSubRoot, 0, KEY_QUERY_VALUE, _
hWnd)
    sVal = String(255, " ")
    lRet = RegQueryValueEx(hWnd, sEntryName, 0, 0, ByVal sVal, _
LenB(sVal))
    RegCloseKey hWnd
    sVal = Left$(sVal, InStr(sVal, vbNullChar) - 1)
    RegRead_API = sVal
End Function

Public Sub Get_Printers()
 'このプロシージャの実行でポート番号付きプリンター設定を変更
Dim objWSH As Object, objPrinter As Object, Str As String
Dim sPrinterList() As String, sTemp1 As String, sTemp2 As String
Dim i As Long, ctr As Long, Splt As Variant
  Const SUB_ROOT = _
"Software\Microsoft\Windows NT\CurrentVersion\Devices"
    Set objWSH = CreateObject("WScript.Network")
    Set objPrinter = objWSH.EnumPrinterConnections
      If objPrinter.Count < 2 Then
        MsgBox "プリンタを取得できません", vbExclamation
        GoTo Exit_Proc
      Else
        ctr = 0
        For i = 0 To objPrinter.Count - 1 Step 2
            ReDim Preserve sPrinterList(ctr)
            sPrinterList(ctr) = objPrinter(i + 1)
            ctr = ctr + 1
        Next
      End If
For i = 0 To ctr - 1
   sTemp1 = RegRead_API(HKEY_CURRENT_USER, _
   SUB_ROOT, sPrinterList(i))
   sTemp1 = Replace(sTemp1, "winspool,", "")
   If InStr(sTemp2 & sPrinterList(i) & " on " & sTemp1, _
   "(22.06)") = 50 Then 'InStr関数でIPアドレスが何文字目にあるか判定
   Str = "" 'クォーテーションマークで囲うため
   Str = Str & sTemp2
   Str = Str & sPrinterList(i)
   Str = Str & " on "
   Str = Str & sTemp1
   Str = Str & ""
   Application.ActivePrinter = Str
   '手差し用の"Hoge_FX DocuCentre-Ⅵ C5571(22.06)"で登録し直し
   End If
Next i
Exit_Proc:
    Set objPrinter = Nothing
    Set objWSH = Nothing
End Sub



いいねと思ったら、三つポチっとね!
にほんブログ村 スキースノボーブログへにほんブログ村 スキースノボーブログ スキーへにほんブログ村 旅行ブログ 旅日記・旅の思い出へ
にほんブログ村    にほんブログ村      にほんブログ村 



0 件のコメント:

コメントを投稿