Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


11027 / 13644 ツリー ←次へ | 前へ→

【18184】プリンタコードの取得 kuma 04/9/17(金) 11:54 質問[未読]
【18186】Re:プリンタコードの取得 IROC 04/9/17(金) 14:14 回答[未読]
【18187】Re:プリンタコードの取得 kuma 04/9/17(金) 15:41 発言[未読]
【18188】Re:プリンタコードの取得 IROC 04/9/17(金) 16:32 回答[未読]
【18192】Re:プリンタコードの取得 ichinose 04/9/17(金) 18:25 発言[未読]
【18214】Re:プリンタコードの取得 訂正 ichinose 04/9/18(土) 13:25 発言[未読]
【18238】Re:プリンタ一覧の取得 shousuke 04/9/18(土) 23:55 発言[未読]
【18239】Re:プリンタ一覧の取得 shousuke 04/9/18(土) 23:58 発言[未読]
【18314】Re:プリンタ一覧の取得 kuma 04/9/21(火) 11:44 お礼[未読]
【18358】Re:プリンタ一覧の取得 ichinose 04/9/21(火) 22:11 発言[未読]
【18431】Re:プリンタ一覧の取得 shousuke 04/9/23(木) 18:27 お礼[未読]
【18585】Re:プリンタ一覧の取得 kuma 04/9/30(木) 12:15 お礼[未読]

【18184】プリンタコードの取得
質問  kuma  - 04/9/17(金) 11:54 -

引用なし
パスワード
   職場ごと機種別に数台のプリンタを使用しております。
あるマクロが完成しましたが、各職場のプリンタが違うためプリントアウトの段階でつまづいております。
1台のPCに数台のプリンタが使用可能になっています、このコードをマクロで取得しプリントアウトまで自動化したいのですが、各PCが使用可能なプリンタコードの取得方法を、ご教授お願いします。(マクロの記録でプリンタコードの取得はしましたが自動化につなげることができませんでした)
過去ログに、通常使うプリンタのチェックのオンオフがあり、加工しようとしましたが能力不足で解析すらできない状態でした。mmm・・・・

【18186】Re:プリンタコードの取得
回答  IROC  - 04/9/17(金) 14:14 -

引用なし
パスワード
   プリンタコードって何ですか?

ネットワークプリンタならIPアドレスで指定できませんか?

【18187】Re:プリンタコードの取得
発言  kuma  - 04/9/17(金) 15:41 -

引用なし
パスワード
   ▼IROC さん:
>プリンタコードって何ですか?

Application.ActivePrinter = "NEC MultiWriter *****"
こんなものです
 
 使用可能なプリンタが数台あり目的により使い分けしていますが、職場によって機種がさまざまなため、マクロが走り始めたら上記のコードを取得しておきたいのですができるでしょうか?

>ネットワークプリンタならIPアドレスで指定できませんか?

 具体的にどのように指定したらよいのでしょうか?(レベル「低」ですみません)

【18188】Re:プリンタコードの取得
回答  IROC  - 04/9/17(金) 16:32 -

引用なし
パスワード
   エクスプローラのネットワークから、そのプリンタは見えますか?

【18192】Re:プリンタコードの取得
発言  ichinose  - 04/9/17(金) 18:25 -

引用なし
パスワード
   IROC さん、kumaさん、こんばんは。

このサイトにAPIを使用した取得方法が掲載されていたはずなんですが、
V3まで探したけど、みつかりませんでした。
で、ちょっと遅いけど、こんな方法を試してみて下さい。

標準モジュール(Module1)に
'================================================================
Sub プリンター取得()
'アクティブシートのセルA1からプリンタ名を設定する
  Dim pr_name
  If open_printer = True Then
    idx = 1
    pr_name = get_printer(True)
    Do While pr_name <> ""
     Cells(idx, 1).Value = pr_name
     idx = idx + 1
     pr_name = get_printer(False)
     Loop
    Call close_printer
    End If
 
End Sub

別の標準モジュール(Module2)に
'====================================================================
'=======================================================
' プリンター名i/oプロシジャーパック
'=======================================================
Private fol
Private folds
Private pr_array() As String
Private pr_idx()
Private e_app As Application
Private job_pr, cur_pr
'=================================================================
Function open_printer() As Boolean
'プリンター名をpr_arrayに、FolderitemのIDをpr_idx()にセット
'  output open_printer true 正常終了
'             false 異常終了
  On Error GoTo err_open_printer
  Dim myshell
  open_printer = True
  Erase pr_array
  Erase pr_idx
  Set myshell = CreateObject("shell.application")
  Set fol = myshell.NameSpace(4)
  Set folds = fol.items
  idx = 0: jdx = 1
  Do While idx <= folds.Count - 1
    Set fold = folds.Item(idx)
    If Not fold.Name Like "プリンタ*" Then
     

     ReDim Preserve pr_array(1 To jdx)
     pr_array(jdx) = fold.Name
     ReDim Preserve pr_idx(1 To jdx)
     pr_idx(jdx) = idx
     jdx = jdx + 1
     End If
    idx = idx + 1
    Loop
ret_open_printer:
  Set myshell = Nothing
  On Error GoTo 0
  Exit Function
err_open_printer:
  MsgBox Error$(Err.Number)
  open_printer = False
  Resume ret_open_printer
End Function
'=====================================================================
Function get_printer(Optional first As Boolean = False)
' プリンターを取り出す(dir関数に使い方が似てる?)
' input  first : true  最初のプリンタ
'          false 次のプリンタ
' output get_printer_name : プリンタ
  
  On Error Resume Next
  Static idx
  If first = True Then
    If e_app Is Nothing Then
     e_app.Quit
     Set e_app = Nothing
     End If
    Set e_app = CreateObject("excel.application")
    job_pr = e_app.ActivePrinter
    cur_pr = ActivePrinter
    idx = 1
    End If
  get_printer = ""
  If idx <= UBound(pr_array()) Then
    nm = pr_array(idx)
    Call set_used_printer(nm)
    DoEvents
    get_printer = e_app.ActivePrinter
    idx = idx + 1
  Else
    Call set_used_printer(Trim(Split(job_pr, "on")(0)))
    Application.Wait [now()] + TimeValue("00:00:01")
    e_app.Quit
    Set e_app = Nothing
    ActivePrinter = cur_pr
    End If
   On Error GoTo 0
End Function
'==================================================================
Function set_used_printer(pr_nm) As Long
'指定されたプリンタ名に該当するプリンタを通常使うプリンタに設定
'input pr_nm : プリンタ名
'output set_used_printer 0:正常 その他:失敗
  On Error Resume Next
  Dim id
  id = WorksheetFunction.Match(pr_nm, pr_array(), 0)
  If Err.Number = 0 Then
    set_used_printer = 0
    folds.Item(pr_idx(id)).InvokeVerb "通常使うプリンタに設定(&F)"
    If Err.Number <> 0 Then
     set_used_printer = Err.Number
     End If
   Else
    set_used_printer = 1
    End If
  On Error GoTo 0
End Function
'========================================================================
Sub close_printer()
'プリンタ名i/oの終了
  On Error Resume Next
  If Not app Is Nothing Then
    Call set_used_printer(Trim(Split(job_pr, "on")(0)))
    Application.Wait [now()+1/864000]
    e_app.Quit
    Set e_app = Nothing
    ActivePrinter = cur_pr
    End If
  Erase pr_array
  Erase pr_idx
  Set fol = Nothing
  Set folds = Nothing
  On Error GoTo 0
End Sub


確認してみて下さい。私の環境(Win98+Excel2000)では
うまく動いてくれました。

【18214】Re:プリンタコードの取得 訂正
発言  ichinose  - 04/9/18(土) 13:25 -

引用なし
パスワード
   IROC さん、kumaさん、こんにちは。

訂正です。


>このサイトにAPIを使用した取得方法が掲載されていたはずなんですが、
>V3まで探したけど、みつかりませんでした。
>で、ちょっと遅いけど、こんな方法を試してみて下さい。
>標準モジュール(Module1)に
>'================================================================
>Sub プリンター取得()
>'アクティブシートのセルA1からプリンタ名を設定する
>  Dim pr_name
>  If open_printer = True Then
>    idx = 1
>    pr_name = get_printer(True)
>    Do While pr_name <> ""
>     Cells(idx, 1).Value = pr_name
>     idx = idx + 1
>     pr_name = get_printer(False)
>     Loop
>    Call close_printer
>    End If
> 
>End Sub

>別の標準モジュール(Module2)に
↓を差し替えて下さい
'=======================================================
' プリンター名i/oプロシジャーパック
'=======================================================
Private fol
Private folds
Private pr_array() As String
Private pr_idx()
Private e_app As Application
Private job_pr, job_prnm, cur_pr
Private gpflg As Boolean
'============================================================
Function open_printer() As Boolean
'プリンター名をpr_arrayに、FolderitemのIDをpr_idx()にセット
'  output open_printer true 正常終了
'             false 異常終了
  On Error GoTo err_open_printer
  Dim myshell
  open_printer = True
  Erase pr_array
  Erase pr_idx
  Set e_app = Nothing
  Set myshell = CreateObject("shell.application")
  Set fol = myshell.NameSpace(4)
  Set folds = fol.items
  gpflg = False
  idx = 0: jdx = 1
  Do While idx <= folds.Count - 1
    Set fold = folds.Item(idx)
    If IsNumeric(fol.GetDetailsOf(fold, 1)) Then
     ReDim Preserve pr_array(1 To jdx)
     pr_array(jdx) = fold.Name
     ReDim Preserve pr_idx(1 To jdx)
     pr_idx(jdx) = idx
     jdx = jdx + 1
     End If
    idx = idx + 1
    Loop
ret_open_printer:
  Set myshell = Nothing
  On Error GoTo 0
  Exit Function
err_open_printer:
  MsgBox Error$(Err.Number)
  open_printer = False
  Resume ret_open_printer
End Function

'============================================================
Function get_printer(Optional first As Boolean = False)
' プリンターを取り出す(dir関数に使い方が似てる?)
' input  first : true  最初のプリンタ
'          false 次のプリンタ
' output get_printer_name : プリンタ
  
  On Error Resume Next
  Static idx
  If first = True Then
    Set e_app = CreateObject("excel.application")
    job_pr = e_app.ActivePrinter
    e_app.Quit
    Set e_app = Nothing
    For idx = 1 To UBound(pr_array())
     ans = InStr(job_pr, pr_array(idx))
     If ans > 0 Then
       job_prnm = pr_array(idx)
       Exit For
       End If
     Next
    cur_pr = ActivePrinter
    ActivePrinter = job_pr
    gpflg = True
    idx = 1
    End If
  get_printer = ""
  If idx <= UBound(pr_array()) Then
    nm = pr_array(idx)
    Call set_used_printer(nm)
    If idx = 1 Then Call set_used_printer(nm)
    Do Until ActivePrinter Like "*" & nm & "*"
     DoEvents
     Loop
    get_printer = ActivePrinter
    idx = idx + 1
  Else
    ActivePrinter = cur_pr
    Call set_used_printer(job_prnm)
    Do Until ActivePrinter = job_pr
     DoEvents
     Loop
    ActivePrinter = cur_pr
    gpflg = False
    End If
   On Error GoTo 0
End Function
'============================================================
Function get_printer_job_count(pr_nm)
'指定されたプリンタ名に該当するプリンタのジョブ数を取得する
'input pr_nm : プリンタ名
'output get_printer_job_count 数値:正常ジョブ数 false:失敗
  On Error Resume Next
  Dim id
  id = WorksheetFunction.Match(pr_nm, pr_array(), 0)
  If Err.Number = 0 Then
    get_printer_job_count = fol.GetDetailsOf(folds.Item(pr_idx(id)), 1)
    If Err.Number <> 0 Then
     get_printer_job_count = False
     End If
   Else
    get_printer_job_count = False
    End If
  On Error GoTo 0
End Function
'============================================================
Function set_used_printer(pr_nm) As Long
'指定されたプリンタ名に該当するプリンタを通常使うプリンタに設定
'input pr_nm : プリンタ名
'output set_used_printer 0:正常 その他:失敗
  On Error Resume Next
  Dim id
  id = WorksheetFunction.Match(pr_nm, pr_array(), 0)
  If Err.Number = 0 Then
    set_used_printer = 0
    folds.Item(pr_idx(id)).InvokeVerb "通常使うプリンタに設定(&F)"
    If Err.Number <> 0 Then
     set_used_printer = Err.Number
     End If
   Else
    set_used_printer = 1
    End If
  On Error GoTo 0
End Function
'============================================================
Sub close_printer()
'プリンタ名i/oの終了
  On Error Resume Next
  If gpflg = True Then
    ActivePrinter = cur_pr
    Call set_used_printer(job_prnm)
    Do Until ActivePrinter = job_pr
     DoEvents
     Loop
    ActivePrinter = cur_pr
    End If
  Erase pr_array
  Erase pr_idx
  Set fol = Nothing
  Set folds = Nothing
  On Error GoTo 0
End Sub


>
>確認してみて下さい。私の環境(Win98+Excel2000)では
>うまく動いてくれました。

【18238】Re:プリンタ一覧の取得
発言  shousuke WEB  - 04/9/18(土) 23:55 -

引用なし
パスワード
   Public Sub プリンタ名設定()
Sheets("List").Select
ActiveSheet.Range("E3:E20").ClearContents
ActiveSheet.Range("E3").Select

Dim vntArray As Variant, Element As Variant
Dim intCount As Integer, strPrinter As String, intPos As Integer, strPort As String

'エントリ検索
vntArray = API_GetProfileString("Devices", vbNullString, "NotFound", 1024, Chr(0))

If IsEmpty(vntArray) = False Then

  For intCount = LBound(vntArray) To UBound(vntArray)
    
    'キー検索
    strPrinter = vntArray(intCount)                   'プリンタ名
    Element = API_GetProfileString("Devices", strPrinter, "NotFound", 1024, Chr(0))
    
    If IsEmpty(Element) = False Then
      
      intPos = InStr(1, Element(0), ",")              
'区切り文字(,)位置
      If intPos <> 0 Then strPort = Mid(Element(0), intPos + 1, Len(Element(0)) - intPos)
      
        '====================
        Debug.Print strPort & " on " & strPrinter
        '====================
'アクティブなセルへプリンタ名を代入する
     
        ActiveCell = strPrinter & " on " & strPort
        ActiveCell.Offset(1, 0).Select 'アクティブセルの移動
                 
          
      End If
  
   Next intCount
  
End If

End Sub


'以下は関数***
Public Function API_GetProfileString(strAppName As String, strKeyName As String, strDefault As String, _
  lngSize As Long, strDelimiter As String) As Variant

Dim strBuf As String                              '情報を取得するためのバッファ
Dim lngResult As Long                              '戻り値
Dim lngStart As Long, lngPos As Long
Dim strTemp As String, strArray() As String, intCount As Integer

'On Error Resume Next

  '---------------------------------------------------------------------------
  '関数の呼び出し
  '---------------------------------------------------------------------------
  'WIN.INI からの情報を取得するためのバッファ
  strBuf = Space(lngSize)
  
  'WIN.INI から指定したエントリないでキーを検索、該当データのバイト数を返す
  lngResult = GetProfileString(strAppName, strKeyName, strDefault, strBuf, lngSize)
  
  '戻り値(テンポラリ)
  strTemp = Trim(Left(strBuf, lngResult))
  
  '---------------------------------------------------------------------------
  '戻り値チェック
  '---------------------------------------------------------------------------
  If strTemp = Empty Then API_GetProfileString = Empty: Exit Function     'キーなし時
  If strTemp = strDefault Then API_GetProfileString = Empty: Exit Function  '該当なし時
  
  lngStart = 1: intCount = Empty
  
  '**********
  '複数戻り値の場合のチェック
  Do
    lngPos = InStr(lngStart, strTemp, strDelimiter)             'データ区切り位置検出
    
    If lngPos = 0 And (lngStart > 1) Then Exit Do              'データ区切りなし時終了
    
    If Mid(strTemp, lngStart, 1) <> strDelimiter Then
      
      '区切られたデータを配列に格納
      ReDim Preserve strArray(intCount) As String
      If lngPos = 0 Then
        strArray(intCount) = strTemp
      Else
        strArray(intCount) = Mid(strTemp, lngStart, lngPos - lngStart)
      End If
    
    End If
    
    lngStart = lngPos + 1                          '検索開始位置
    intCount = intCount + 1                         '配列の要素インデックス増
    
  Loop Until lngPos = 0
  '**********
  
  '戻り値
  API_GetProfileString = strArray
  
End Function

【18239】Re:プリンタ一覧の取得
発言  shousuke WEB  - 04/9/18(土) 23:58 -

引用なし
パスワード
   何もコメントせずに載せてしまいました。
此でどうでしょうか?

今のところ、XPでも大丈夫見たいです。

普段使っている物をそのまま載せてますので、適宜変更してください。

【18314】Re:プリンタ一覧の取得
お礼  kuma  - 04/9/21(火) 11:44 -

引用なし
パスワード
   ▼IROC さん ichinose さん shousuke さん:
返答が遅くなってしまって申し訳ありません。
皆様のご回答によりプリンタコードを取得することができました。
ありがとうございました。また手詰まりになりましたらご教授おねがいします。

【18358】Re:プリンタ一覧の取得
発言  ichinose  - 04/9/21(火) 22:11 -

引用なし
パスワード
   ▼shousuke さん:
こんばんは。あー、こっちの方が断然速いですね!!
API宣言が抜けていたので、
Public Declare Function GetProfileString Lib "kernel32" Alias _
     "GetProfileStringA" (ByVal lpAppName As String, _
               ByVal lpKeyName As String, _
               ByVal lpDefault As String, _
               ByVal lpReturnedString As String, _
               ByVal nSize As Long) As Long

>Public Sub プリンタ名設定()
'Sheets("List").Select これでアクティブシートに表示されますね?
>ActiveSheet.Range("E3:E20").ClearContents
>ActiveSheet.Range("E3").Select
>
>Dim vntArray As Variant, Element As Variant
>Dim intCount As Integer, strPrinter As String, intPos As Integer, strPort As String
>
>'エントリ検索
>vntArray = API_GetProfileString("Devices", vbNullString, "NotFound", 1024, Chr(0))
>
>If IsEmpty(vntArray) = False Then
>
>  For intCount = LBound(vntArray) To UBound(vntArray)
>    
>    'キー検索
>    strPrinter = vntArray(intCount)                   'プリンタ名
>    Element = API_GetProfileString("Devices", strPrinter, "NotFound", 1024, Chr(0))
>    
>    If IsEmpty(Element) = False Then
>      
>      intPos = InStr(1, Element(0), ",")              
>'区切り文字(,)位置
>      If intPos <> 0 Then strPort = Mid(Element(0), intPos + 1, Len(Element(0)) - intPos)
>      
>        '====================
>        Debug.Print strPort & " on " & strPrinter
>        '====================
>'アクティブなセルへプリンタ名を代入する
>     
>        ActiveCell = strPrinter & " on " & strPort
>        ActiveCell.Offset(1, 0).Select 'アクティブセルの移動
>                 
>          
>      End If
>  
>   Next intCount
>  
>End If
>
>End Sub
>
>
>'以下は関数***
>Public Function API_GetProfileString(strAppName As String, strKeyName As String, strDefault As String, _
>  lngSize As Long, strDelimiter As String) As Variant
>
>Dim strBuf As String                              '情報を取得するためのバッファ
>Dim lngResult As Long                              '戻り値
>Dim lngStart As Long, lngPos As Long
>Dim strTemp As String, strArray() As String, intCount As Integer
>
>'On Error Resume Next
>
>  '---------------------------------------------------------------------------
>  '関数の呼び出し
>  '---------------------------------------------------------------------------
>  'WIN.INI からの情報を取得するためのバッファ
>  strBuf = Space(lngSize)
>  
>  'WIN.INI から指定したエントリないでキーを検索、該当データのバイト数を返す
>  lngResult = GetProfileString(strAppName, strKeyName, strDefault, strBuf, lngSize)
>  
>  '戻り値(テンポラリ)
>  strTemp = Trim(Left(strBuf, lngResult))
>  
>  '---------------------------------------------------------------------------
>  '戻り値チェック
>  '---------------------------------------------------------------------------
>  If strTemp = Empty Then API_GetProfileString = Empty: Exit Function     'キーなし時
>  If strTemp = strDefault Then API_GetProfileString = Empty: Exit Function  '該当なし時
>  
>  lngStart = 1: intCount = Empty
>  
>  '**********
>  '複数戻り値の場合のチェック
>  Do
>    lngPos = InStr(lngStart, strTemp, strDelimiter)             'データ区切り位置検出
>    
>    If lngPos = 0 And (lngStart > 1) Then Exit Do              'データ区切りなし時終了
>    
>    If Mid(strTemp, lngStart, 1) <> strDelimiter Then
>      
>      '区切られたデータを配列に格納
>      ReDim Preserve strArray(intCount) As String
>      If lngPos = 0 Then
>        strArray(intCount) = strTemp
>      Else
>        strArray(intCount) = Mid(strTemp, lngStart, lngPos - lngStart)
>      End If
>    
>    End If
>    
>    lngStart = lngPos + 1                          '検索開始位置
>    intCount = intCount + 1                         '配列の要素インデックス増
>    
>  Loop Until lngPos = 0
>  '**********
>  
>  '戻り値
>  API_GetProfileString = strArray
>  
>End Function

処理が速いのに活用されないといけないので、コメントしておきます。

【18431】Re:プリンタ一覧の取得
お礼  shousuke WEB  - 04/9/23(木) 18:27 -

引用なし
パスワード
   あー はずかしい
宣言がぬけてました....

【18585】Re:プリンタ一覧の取得
お礼  kuma  - 04/9/30(木) 12:15 -

引用なし
パスワード
   ichinose さん shousuke さんありがとうございます。
ichinose さんのプログラムで希望の処理が可能となりました、これからshousuke さんのプログラムで試してみます。
感謝です!

11027 / 13644 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free