プリンタ名を返すProperty

プリンタ名を取得するProperty

前回

akashi-keirin.hatenablog.com

の続き。

前回までに作成したInstalledPrinterクラスにPropertyを追加する。

追加するPropertyは、printerName(ByVal printerIndex As Long)とし、引数にインデックスを渡したら、該当するプリンタの名前を返す、というものにする。

コード

リスト1 クラスモジュール宣言セクション
Private printerNameArray_() As String

まずは、クラスモジュールの宣言セクションに、モジュールレベル変数を置く。

String型の配列変数。取得したプリンタ名を配列として持っておくためのもの。

スト2 クラスモジュール
Public Property Get printerName(ByVal printerIndex As Long) As String
  printerNameArray_() = getInstalledPrinterNameArray()    '……(1)'
  If printerIndex < 0 Or _
     printerIndex >= Me.getPrintersCount Then _
    printerName = "": Exit Property    '……(4)'
  printerName = printerNameArray_(printerIndex)    '……(5)'
End Property

Private Function getInstalledPrinterNameArray() As String()    '……(A)'
  Dim printersCount As Long
  printersCount = Me.getPrintersCount    '……(2)'
  Dim ar() As String
  ReDim ar(getPrintersCount - 1) As String
  Dim n As Long
  n = 0
  Dim shellApp As New Shell    '……(3)'
  Dim targetPrinter As FolderItem
  For Each targetPrinter In shellApp.Namespace(ssfPRINTERS).Items
    ar(n) = targetPrinter.Name
    n = n + 1
  Next
  getInstalledPrinterNameArray = ar
  Set shellApp = Nothing
  Set targetPrinter = Nothing
End Function

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

まず、(1)の

printerNameArray_() = Me.getInstalledPrinterNameArray()

で、モジュールレベル変数「printerNameArray_()」に、(A)のgetInstalledPrinterNameArrayメソッドによってプリンタ名の配列をぶち込む。

(A)のgetInstalledPrinterNameArrayメソッドではまず(2)からの3行

printersCount = Me.getPrintersCount
Dim ar() As String
ReDim ar(getPrintersCount - 1) As String

getPrintersCountを用いて、プリンタの数を取得して要素数を決定し、配列ar()を作成。

あとは、(3)からの6行

Dim shellApp As New Shell
Dim targetPrinter As FolderItem
For Each targetPrinter In shellApp.Namespace(ssfPRINTERS).Items
  ar(n) = targetPrinter.Name
  n = n + 1
Next

で配列ar()にプリンタ名を格納している。

FolderItemオブジェクトとか、Namespace(ssfPRINTERS).Itemsメソッドについては、

akashi-keirin.hatenablog.com

コチラをどうぞ。

ここまでで、モジュールレベル変数「printerNameArray_()」には、プリンタ名が配列として格納されている。

で、処理が(4)の

If printerIndex < 0 Or _
     printerIndex >= Me.getPrintersCount Then _
    printerName = "": Exit Property

に移る。

これはガード節で、引数のチェックをしている。

引数printerIndex0未満だったり、プリンタの数以上だと、「""」を返すようにした。

……って、ガード節なら、こいつがまず一番最初に来るべきだよな。反省。

あとは、(5)の

printerName = printerNameArray_(printerIndex)

で、インデックスに応じたプリンタ名を配列から取得して返す。

実行

f:id:akashi_keirin:20180930163538j:plain

この状態で、次のコードを実行する。

リスト3 標準モジュール
Public Sub Test()
  Dim i As Long
  With InstalledPrinter
    For i = 0 To .getPrintersCount - 1
      Debug.Print .printerName(i)
    Next
  End With
End Sub

プリンタ名を取得して、順にイミディエイト・ウインドウに出力するだけのコード。

こいつを実行すると、

f:id:akashi_keirin:20180930163547j:plain

意図どおりの出力を得た。

おわりに

このPropertyForループで回してAddItemメソッドと組み合わせたら、ユーザーフォームのコンボボックスなんかでユーザーにプリンタを選ばせることができる。