PDF管理ユーザーフォームを作ってみた。エクセルで、PDF検索から印刷まで可能。

PDF管理エクセルの作成

クラウドワークスで、「PDFをエクセルから印刷したい」という需要があったので作ってみた。

設計

メインのDirectoryを決める。存在するファイルをもとにComboboxに追加し、その場所のPDFを検索し印刷できるようにした。

ファイルの構造
MainDirectory-人事部
       ⎣人事1課
        ⎣人事1班 
        ⎣人事2班
       ⎣人事2課
        ⎣人事3班 
        ⎣人事4班

このようなファイル構造のものを「人事」「総務」「製造」「営業」で作成(架空のもの)。
部、課、班単位でComboboxを選択しPDF一覧をListboxに取得する。



MainDirectory画面
f:id:bimori466:20200411073954p:plain

各部ごとに格納されたPDFを取得し、検索、印刷します。

処理イメージ

1 検索 (人事部人事課人事1班フォルダの”調査”を含むPDF)
f:id:bimori466:20200410161044g:plain


2 印刷 (リストを選択して印刷実行)
f:id:bimori466:20200410162409g:plain
リストの中で選択しているPDFを印刷します(選択印刷)。
一括印刷は、リストにあるPDFをすべて印刷します。
PDFが開いて印刷され、閉じる。これをPDFの数だけ繰り返す。
★注意
 ファイル名に「空白」を含むと、PDFファイルが開けずエラーとなる。
 部分印刷ができません。全ページを印刷します。
 部分印刷したい場合は、PowerShellでGUI操作を自動化する方法が解決策の1つかと。

作成のポイント2点

1 存在するフォルダをComboboxに追加する。

「人事」「総務」「製造」「営業」のフォルダを準備しました。
おそらく、使っていくと問題になりそうなのがComboboxには選択があるが、実際のフォルダがないということが発生しそうです。
そうならないために、Initialize処理でMainDirectoryをDir関数でフォルダだけ取得します。取得できたフォルダ名を「部」のComboboxに追加。その後は「営業部」を選択した場合、「MainDirectory + 営業部¥」のファイルパスをDir関数で取得し、「課」のComboboxに追加する。「課」が入力されたら「班」も同様に処理する。
これなら、フォルダの追加変更があっても対応できます。


Combobox追加処理イメージ
f:id:bimori466:20200410213516g:plain

2 印刷処理(Shellコマンドを使用)

参照設定の追加

コマンドを実行するために「Windows Script Host Object Model」を追加する。

コマンド作成

コマンド = "AcroRd32.exe /t +  ファイルパス  + プリンタ名"
Shellオブジェクトを作成し、RUNメソッドで実行する。

コマンド実行のモジュール

'Shellコマンドを設定
strShellCommand = "AcroRd32.exe /t " & PrintPDF & " " & printerName
            
'Shellコマンドを実行
wshShellObj.Run (strShellCommand)

この2点を使って作成しました。
これで、モジュールをコピーして、MainDirectoryを設定して使用できます。
MainDirectoryを設定は、ユーザーフォームコードの先頭に、定数strFolderPathに設定しています。
先頭に記述しておけば、フォームコードの他のモジュールからも引数をして参照できます。


モジュール

モジュールの中身を貼っとくので、興味のあるかたはどうぞ。

標準モジュール

Sub PDF管理画面呼出()

PDF管理画面.Show

End Sub


フォームモジュール

Const strFolderPath = "MainDirectory"

Private Sub cmb_部_Change()

strFolderPath_Level2 = strFolderPath & cmb_部.Value & "\"


'課、班を初期化
cmb_課.Clear: cmb_班.Clear

Dim strFileName As String

strFileName = Dir(strFolderPath_Level2, vbDirectory)

Do While strFileName <> ""
    If GetAttr(strFolderPath_Level2 & strFileName) And vbDirectory Then
            If strFileName <> "." And strFileName <> ".." Then: cmb_課.AddItem strFileName
    End If
    
    '次のPDFファイル名を取得
    strFileName = Dir()
Loop



End Sub

Private Sub cmb_課_Change()

strFolderPath_Level3 = strFolderPath & cmb_部.Value & "\" & cmb_課.Value & "\"

Dim strFileName As String

strFileName = Dir(strFolderPath_Level3, vbDirectory)

Do While strFileName <> ""
    If GetAttr(strFolderPath_Level3 & strFileName) And vbDirectory Then
            If strFileName <> "." And strFileName <> ".." Then: cmb_班.AddItem strFileName
    End If
    
    '次のPDFファイル名を取得
    strFileName = Dir()
Loop


End Sub

Private Sub cmd_All_Print_Click()

Dim wshShellObj As IWshRuntimeLibrary.WshShell                          'Shellオブジェクト
Set wshShellObj = New IWshRuntimeLibrary.WshShell
Dim strShellCommand As String

'デフォルトのプリンタ名
printerName = "プリンタ名"

Dim Result As Integer

Result = MsgBox("すべてのリストPDF印刷を実行しますか?", vbYesNo + vbQuestion, "印刷確認")

If Result = vbYes Then
    MsgBox "処理を行います。"
    
    printFilePath = strFolderPath & cmb_部.Value & "\" & cmb_課.Value & "\" & cmb_班.Value & "\"
    
    For i = 0 To lst_file.ListCount - 1
        printFileName = lst_file.List(i)
        
        PrintPDF = printFilePath & printFileName
        
        'Shellコマンドを設定
        strShellCommand = "AcroRd32.exe /t " & PrintPDF & " " & printerName
        
        'Shellコマンドを実行
        wshShellObj.Run (strShellCommand)
        
         
        '印刷終了後、印刷済へPDFを移動とか
          
    Next i
        
Else
    MsgBox "印刷処理を中断します。"
End If


'オブジェクトを強制開放
Set wshShellObj = Nothing


End Sub

Private Sub cmd_PDF検索_Click()

'初期化
lst_file.Clear

searchFolderPath = strFolderPath & cmb_部.Value & "\" & cmb_課.Value & "\" & cmb_班.Value & "\"
txt_Select_cd.Value = searchFolderPath


strPDFName = Dir(searchFolderPath & "*.pdf")
        
'拡張子が「.pdf」のファイルがある限り、処理をループ
Do While strPDFName <> ""
    lst_file.AddItem strPDFName
    
    '次のPDFファイル名を取得
    strPDFName = Dir()
Loop

End Sub

Private Sub cmd_Select_Print_Click()

Dim wshShellObj As IWshRuntimeLibrary.WshShell                          'Shellオブジェクト
Set wshShellObj = New IWshRuntimeLibrary.WshShell
Dim strShellCommand As String

'デフォルトのプリンタ名
printerName = "プリンタ名"

Dim Result As Integer

Result = MsgBox("選択されたリストのPDF印刷を実行しますか?", vbYesNo + vbQuestion, "印刷確認")

If Result = vbYes Then
    MsgBox "処理を行います。"
    
    printFilePath = strFolderPath & cmb_部.Value & "\" & cmb_課.Value & "\" & cmb_班.Value & "\"
    
    For i = 0 To lst_file.ListCount - 1
        If lst_file.Selected(i) = True Then
            printFileName = lst_file.List(i)
            
            PrintPDF = printFilePath & printFileName
            
            'Shellコマンドを設定
            strShellCommand = "AcroRd32.exe /t " & PrintPDF & " " & printerName
            
            'Shellコマンドを実行
            wshShellObj.Run (strShellCommand)
            
             
            '印刷終了後、印刷済へPDFを移動とか
            
        
        End If
    
    Next i
        
Else
    MsgBox "印刷処理を中断します。"
End If


'オブジェクトを強制開放
Set wshShellObj = Nothing

End Sub

Private Sub cmd_SearchWord_Click()

'初期化
lst_file.Clear

Dim SearchWord As String
Dim SearchPDF As String

SearchWord = txt_SearchWord.Value


'選択中のディレクトリを、キーワード調査
SearchPDF = Dir(txt_Select_cd.Value & "*" & SearchWord & "*.pdf")

Do While SearchPDF <> ""
    If InStr(strFileName, ".") = 0 Then
       lst_file.AddItem SearchPDF
    End If
    
    '次のPDFファイル名を取得
    SearchPDF = Dir()
Loop

End Sub




Private Sub UserForm_Initialize()

strPDFName = Dir(strFolderPath & "*.pdf")
        
'拡張子が「.pdf」のファイルがある限り、処理をループ
Do While strPDFName <> ""
    lst_file.AddItem strPDFName
    
    '次のPDFファイル名を取得
    strPDFName = Dir()
Loop


Dim strFileName As String

strFileName = Dir(strFolderPath, vbDirectory)
        
'ファイル属性が"ファイルで、"."、".."以外ならComboboxに追加。
Do While strFileName <> ""
    If GetAttr(strFolderPath & strFileName) And vbDirectory Then
            If strFileName <> "." And strFileName <> ".." Then: cmb_部.AddItem strFileName
    End If
            
    '次のPDFファイル名を取得
    strFileName = Dir()
Loop


End Sub

ユーザーフォーム

f:id:bimori466:20200411085736p:plain
Mainディレクトリのテキストボックスは、動画gifでは非表示にしていました。
テキストボックスのValueに、Mainディレクトリを入れているだけです。