偶爾會逛逛PTT的Visual_Basic 版
最近看到一篇"[VBA] 如何用VBA開啟PDF並列印?"
結果沒有人回應
我用其中的關鍵字"用VBA開啟PDF並列印"搜尋
在搜尋的第2頁,有一篇reddit的文章"Printing external PDF-files using VBA"
其中有人回應跟我的想法很類似,這應該要用windows命令列程式
才能夠在Excel用VBA Shell或者 WScript.Shell執行相關程序
貼文提供了一個能透過命令列執行的程式-PDFtoPrinter
我把這個網站的內容貼到gemini
請AI幫忙整理操作方式
因為這個程式是包裝PDF-XChange Viewer,而PDF-XChange Viewer可以設定自訂列印選項
在說明內容也提到相關的設定可以參考PDF-XChange Viewer手冊
所以我再把手冊貼給 gemini
請AI幫我找出來設定的方式
接著,再問gemini如果想要動態設定自訂檔應該如何處理
AI真的很厲害,能夠提出變通的方式來處理
也提供了power shell的程式碼
所以我再請AI改成VBA程式碼,並且用 WScript.Shell來執行命令串
最後我參考了AI的程式碼,用我習慣的方式來串這些流程
首先,以工作表作為資料庫
介面如下
設定了2個按鈕,分別執行選取PDF、列印等功能
因為我不想在測試的時候印出一堆東西
所以印表機設定成"Microsoft Print to PDF"
以下分別呈現程式碼
1.選取PDF的程式碼
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Sub selePDF4()
r = Sheets(1).Range("B1").End(xlDown).Row
If r = 1048576 Then
r = 2
Else
r = r + 1
End If
Dim fd As FileDialog
Set fd = Application.FileDialog(msoFileDialogFilePicker)
Dim filePath As Variant
With fd
.AllowMultiSelect = False
.Filters.Clear
.Filters.Add "pdf", "*.pdf"
.Title = "選取pdf檔"
End With
If fd.Show = -1 Then
filePath = fd.SelectedItems(1)
Debug.Print filePath
Sheets(1).Range("B" & r).Value = filePath
End If
Set fd = Nothing
End Sub
2.列印功能
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
Sub printByComandLine4()
r = Sheets(1).Range("B1").End(xlDown).Row
If r = 1048576 Then
Exit Sub
End If
For i = 2 To r
If Range("A" & i) <> "◎" Then
Dim wsh As Object
Set wsh = VBA.CreateObject("WScript.Shell")
Dim waitOnReturn As Boolean: waitOnReturn = True
Dim windowStyle As Integer: windowStyle = 0
' 如果用環境參數在WScript.Shell會無法執行
' PDFtoPrinter.exe
Dim PrinterExe As String
PrinterExe = Chr(34) & ThisWorkbook.Path & "\pdftoprinter-main\PDFtoPrinter.exe" & Chr(34)
' 列印的PDF檔案
Dim PrintFile As String
' PrintFile = ThisWorkbook.Path & "\PDFVManual.pdf"
PrintFile = Range("B" & i).Value
' 印表機名稱
Dim PrinterName As String
' PrinterName = "Microsoft Print to PDF"
PrinterName = Range("D" & i).Value
If PrinterName = "" Then
PrinterName = "Microsoft Print to PDF"
End If
' 複製設定檔
Dim SETTINGS_DIR As String
Dim SourceSettingFile As String
Dim DestinationSettingFile As String
Dim SettingFile As String
SETTINGS_DIR = ThisWorkbook.Path & "\pdftoprinter-main\setting\"
Dim cc As String
c = Range("C" & i).Value
Select Case c
Case "單面"
SettingFile = "Settings_1.dat"
Case "四合一"
SettingFile = "Settings_4up.dat"
Case Else:
SettingFile = "Settings_ori.dat"
End Select
SourceSettingFile = Chr(34) & SETTINGS_DIR & SettingFile & Chr(34)
DestinationSettingFile = Chr(34) & ThisWorkbook.Path & "\pdftoprinter-main\PDF-XChange Viewer Settings.dat" & Chr(34)
Dim CmdString As String
CmdString = "cmd.exe /c copy /Y " & SourceSettingFile & " " & DestinationSettingFile
Debug.Print CmdString
Dim ExitCode As Long
ExitCode = wsh.Run(CmdString, windowStyle, waitOnReturn)
If ExitCode <> 0 Then
MsgBox "錯誤: 複製設定檔失敗,退出碼: " & ExitCode, vbCritical
Set wsh = Nothing
Exit Sub
End If
' 等待3秒鐘
Application.Wait (Now + TimeValue("0:00:03"))
' 列印範圍
Dim ce As String
ce = Range("E" & i).Value
Dim pageString As String
' 列印命令串
Dim s As String
Select Case ce
Case Is <> ""
pageString = "pages=" & ce
s = PrinterExe & " " & Chr(34) & PrintFile & Chr(34) & Chr(32) & Chr(34) & PrinterName & Chr(34) & Chr(32) & pageString
Debug.Print s
Case Else:
s = PrinterExe & " " & Chr(34) & PrintFile & Chr(34) & Chr(32) & Chr(34) & PrinterName & Chr(34)
Debug.Print s
End Select
' WScript.Shell
Dim errorCode As Long
errorCode = wsh.Run(s, windowStyle, waitOnReturn)
If errorCode = 0 Then
' MsgBox "Done! No error to report."
Debug.Print "列印完成"
Else
MsgBox "Program exited with error code " & errorCode
End If
' 寫回預設的設定檔
Dim OriSettingFile As String
OriSettingFile = Chr(34) & SETTINGS_DIR & "Settings_ori.dat" & Chr(34)
Dim CmdString2 As String
CmdString2 = "cmd.exe /c copy /Y " & OriSettingFile & Chr(32) & DestinationSettingFile
Debug.Print CmdString2
Dim ExitCode2 As Long
ExitCode2 = wsh.Run(CmdString2, windowStyle, waitOnReturn)
If ExitCode2 <> 0 Then
MsgBox "錯誤: 複製設定檔失敗,退出碼: " & ExitCode2, vbCritical
Set wsh = Nothing
Exit Sub
End If
' 等待1秒鐘
Application.Wait (Now + TimeValue("0:00:01"))
Set wsh = Nothing
Range("A" & i).Value = "◎"
End If
Next
End Sub
主要流程就是依據需求串接命令
命令列的架構如下
如果要指定範圍就加上 pages參數
這個程式碼最大的關隘就是找到能夠在命令列執行的PDF程式
接著就是處理動態設定列印選項的方法
之後就簡單多了,都是VBA的語法問題而已
把相關的參數串接起來在WScript.Shell執行PDFtoPrinter.exe
0 comments:
張貼留言