VBA 从自定义程序打印为 PDF

VBA Print to PDF from a custom program

在工作中,我们有一个自定义程序可以从我们的数据库生成报告。 我们不允许安装新的语言包或参考,但我设法使用 excel 的基础 UIAutomation 自动生成了一份报告,但这份报告需要以 pdf 格式保存在一个目录中,就像他们会做的那样按 CTRL+P 并选择打印机名称 "Microsoft Print to PDF"。有什么方法可以仅使用 VBA 来自动执行此步骤吗?

如果有帮助,我的代码如下:

Sub open_evol()
Dim oUIAutomation As New CUIAutomation8
Dim oUIADesktop As IUIAutomationElement
Dim allChilds As IUIAutomationElementArray
Dim allChildsAxys As IUIAutomationElementArray
Dim axys As IUIAutomationElement
Dim axys2 As IUIAutomationElement
Dim intermed As IUIAutomationElement
Dim boxes As IUIAutomationElementArray
Dim boxes2 As IUIAutomationElementArray
Dim a As IUIAutomationElement


Set oUIADesktop = oUIAutomation.GetRootElement

Debug.Print oUIADesktop.CurrentName

Set allChilds = oUIADesktop.FindAll(TreeScope_Children, oUIAutomation.CreateTrueCondition)

For i = 0 To allChilds.Length - 1
    Debug.Print i & ":=" & allChilds.GetElement(i).CurrentName & vbTab & allChilds.GetElement(i).CurrentClassName
    If Left(allChilds.GetElement(i).CurrentName, 12) = "Axys Reports" Then
    Set axys = allChilds.GetElement(i)
    End If
Next

On Error GoTo escape:
axys.SetFocus
On Error GoTo 0

SendKeys "%cee~", True

time1 = Now
time2 = Now + TimeValue("0:00:01")
    Do Until time1 >= time2
        DoEvents
        time1 = Now()
    Loop

Set allChildsAxys = axys.FindAll(TreeScope_Children, oUIAutomation.CreateTrueCondition)

Set axys2 = allChildsAxys.GetElement(0)
Set boxes = axys2.FindAll(TreeScope_Element, oUIAutomation.CreateTrueCondition)

For i = 0 To boxes.Length - 1
    If Left(boxes.GetElement(i).CurrentName, 8) = "Evol e R" Then
    Set intermed = boxes.GetElement(i)
    Debug.Print "intermet: "; boxes.GetElement(i).CurrentName
    End If
Next i

Set boxes2 = intermed.FindAll(TreeScope_Subtree, oUIAutomation.CreateTrueCondition)

boxes2.GetElement(4).SetFocus

SendKeys "+^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT} +^{LEFT}", True
SendKeys "{DELETE}", True
SendKeys "@5ABE2", True

boxes2.GetElement(9).SetFocus

SendKeys "^{RIGHT} +^{LEFT}", True
SendKeys "{DELETE}", True
SendKeys "033118", True

boxes2.GetElement(13).SetFocus

SendKeys "^{RIGHT} +^{LEFT}", True
SendKeys "{DELETE}", True
SendKeys "043018", True

boxes2.GetElement(26).SetFocus

SendKeys "{ENTER}"

End


escape:
MsgBox ("Open Axys Reports")

End Sub

假设 CTRL+p 是自定义应用程序中用于打开打印对话框的适当热键,您也许可以用 SendKeys.

破解它
Dim filename as String
filename = "c:/path/to/my filename" ' do not need to include the .PDF extension

' Open the print dialog
SendKeys "^p", True
' Select your printer (this may not be necessary, but since we don't know
' anything about your application or what it's print dialog looks like, 
' you'll have to probably make some changes 
SendKeys "{ENTER}", True
' Once the printer has been selected, send the filename to the dialog
SendKeys filename, True
' Sending ENTER again should execute the Print to PDF
SendKeys "{ENTER}"

注意 这假定 "Microsoft Print to PDF" 是默认打印机。如果不是这种情况,并且您的应用程序没有提供 API,可能仍然有一种方法可以使用 FindWindow/etc 和其他更复杂的 WinAPI 调用来实现。