【问题标题】:VBA Replace Sendkeys to select option in print settingsVBA 替换 Sendkeys 以在打印设置中选择选项
【发布时间】:2019-05-10 14:58:58
【问题描述】:

在 Excel 中打印时,我的工作场所有一个额外的弹出窗口,用于选择打印选项。它不是 Excel 的一部分(我相信它是佳能打印机对话窗口)。这些选项允许您指定以彩色、装订和分页等方式打印。它们不是 excel 打印选项。

过去,我使用过一个宏,它使用SendKeys 复制用于选择(在 Excel 中)页面布局 (alt P)、页面设置 (alt I) 和“选项”的键盘快捷键页面设置屏幕 (alt O)。选择“选项”后,打印机对话屏幕打开,宏继续使用SendKeys 在此窗口中选择配置文件(每个配置文件都包含彩色打印、装订和分页等选项)。这段代码如下:

Sub Test()

    Application.SendKeys ("%p"), True 'Selects Page Layout
    Application.SendKeys ("%i"), True 'Selects Print Titles
    Application.SendKeys ("%o"), True 'Selects Options
    Application.SendKeys ("p"), True  'Selects 'Portrait' default (this needs to be set up initially)
    Application.SendKeys "{TAB 19}", True 'Tabs to OK
    Application.Wait (Now() + TimeValue("00:00:01"))
    Application.SendKeys "~", True 'Hits enter to close screen
    Application.Wait (Now() + TimeValue("00:00:01"))
    Application.SendKeys "~", True 'Hits enter to close screen

End Sub

自从迁移到 Windows 10/Office 2016 - SendKeys 在单独的打印机窗口打开时失败(特别是在以 Application.SendKeys ("p"), True 开头的行及以后)。基本上,宏会打开打印机设置窗口,但之后什么都不做。

我曾尝试寻找 SendKeys 的替代品,但我很难理解如何通过 VBA 自动执行点击 p 的过程(在打印对话窗口中选择纵向配置文件),点击标签 19 次(到进入退出屏幕按钮),然后按两次 Enter(关闭后续对话窗口 - 这是 excel 窗口)。需要明确的是 - 提到的“纵向”配置文件是一个特定的打印机配置文件,它指定了许多选项,包括方向、2 面打印、装订位置、颜色模式和装订/分页/组首选项。

如果可能的话,我很乐意替换所有 SendKeys 命令,因为我知道它们不可靠/不受支持。

[更新 14.05.2019]:

所以我考虑尝试用“Keybd_Event”替换发送键,但这遇到了完全相同的障碍(在打印机对话窗口打开之前一直有效)。

[2019 年 5 月 20 日更新]

@Selkie 的解决方案有效,我已将其标记为答案。

这是我最后使用的代码,尽管仍然需要对其进行调整,以便循环遍历选定的工作表:

Sub PrinterSetUp()
Dim filepath As String
Dim Msg As Integer

'Filepath can't have a space in it
filepath =         "Directory\PrinterScriptPortrait.vbs"

If Dir(filepath) <> "" Then
'Hurray it exists
Else
'It doesn't exist yet, create the file
WriteVBSScript (filepath)
End If

Shell "wscript " & filepath, vbNormalFocus
'no code after here, otherwise everything breaks.
End Sub


Sub WriteVBSScript(filepath As String)
Dim VBScriptString As String
Dim fso As Object
Dim oFile As Object

'Needs to be done as a VBS script because VBA and sendkeys don't play well with dialog boxes.
Set fso = CreateObject("Scripting.FileSystemObject")
Set oFile = fso.CreateTextFile(filepath)


VBScriptString = VBScriptString & "Set WSHShell = WScript.CreateObject( " & Chr(34) & "WScript.Shell" & Chr(34) & " )" & vbNewLine
VBScriptString = VBScriptString & "WSHshell.AppActivate " & Chr(34) & " Excel.exe " & Chr(34) & " " & vbNewLine
VBScriptString = VBScriptString & "wsh.sleep 1000" & vbNewLine
VBScriptString = VBScriptString & "WSHshell.SendKeys " & Chr(34) & "%p" & Chr(34) & " " & vbNewLine
VBScriptString = VBScriptString & "wsh.sleep 1000" & vbNewLine
VBScriptString = VBScriptString & "WSHshell.SendKeys " & Chr(34) & "%i" & Chr(34) & " " & vbNewLine
VBScriptString = VBScriptString & "wsh.sleep 1000" & vbNewLine
VBScriptString = VBScriptString & "WSHshell.SendKeys " & Chr(34) & "%o" & Chr(34) & " " & vbNewLine
VBScriptString = VBScriptString & "wsh.sleep 1000" & vbNewLine
VBScriptString = VBScriptString & "WSHshell.SendKeys " & Chr(34) & "p" & Chr(34) & " " & vbNewLine
VBScriptString = VBScriptString & "wsh.sleep 1000" & vbNewLine
VBScriptString = VBScriptString & "WSHshell.SendKeys " & Chr(34) & "{TAB 19}" & Chr(34) & " " & vbNewLine
VBScriptString = VBScriptString & "wsh.sleep 1000" & vbNewLine
VBScriptString = VBScriptString & "WSHshell.SendKeys " & Chr(34) & "~" & Chr(34) & " " & vbNewLine
VBScriptString = VBScriptString & "wsh.sleep 1000" & vbNewLine
VBScriptString = VBScriptString & "WSHshell.SendKeys " & Chr(34) & "~" & Chr(34) & " " & vbNewLine
VBScriptString = VBScriptString & "wsh.sleep 1000" & vbNewLine

oFile.WriteLine VBScriptString

oFile.Close

Set fso = Nothing
Set oFile = Nothing

End Sub

【问题讨论】:

  • 不清楚如何触发打印:使用 VBA 代码还是手动按下标准 excel 按钮?如果 VBA 显示代码。
  • 打印由 VBA 触发 - 上面的 sendkeys 语句,即“选择选项”是打开打印机对话窗口的方式 - sendkeys 从字面上复制您将使用的键盘快捷键命令。我会修改我的问题。
  • 如果您使用 ActiveSheet.PrintOut 之类的东西触发打印会发生什么?你看到佳能对话框了吗?
  • 您愿意使用其他语言吗?可能会有些不同,但您可以使用称为 Autohotkey 的语言更轻松地自动填写表单。

标签: excel vba sendkeys


【解决方案1】:

所以这真的很棘手,我最近才弄明白。

基本上,当您打开这样的窗口时,sendkeys 会停止工作 - 从 Excel 中。

解决方案?在外部调用 sendkeys。

这是我编写的示例代码,用于将打印机类型更改为在按钮所在的工作表之后的 15 个工作表上进行双面打印:

Sub PrinterSetUp()
Dim filepath As String
Dim Msg As Integer

'This code is super janky, I apologize.

'Filepath can't have a space in it
filepath = "Filepath\PrinterScript.vbs"
 'Select the printer we want to print to
Application.Dialogs(xlDialogPrinterSetup).Show


If Dir(filepath) <> "" Then
    'Hurray it exists
Else
    'It doesn't exist yet, create the file
    WriteVBSScript (filepath)
End If

Shell "wscript " & filepath, vbNormalFocus
'no code after here, otherwise everything breaks.
End Sub





Sub WriteVBSScript(filepath As String)
Dim VBScriptString As String
Dim fso As Object
Dim oFile As Object

'Needs to be done as a VBS script because VBA and sendkeys don't play well with dialog boxes.
Set fso = CreateObject("Scripting.FileSystemObject")
Set oFile = fso.CreateTextFile(filepath)


VBScriptString = VBScriptString & "Set WSHShell = WScript.CreateObject( " & Chr(34) & "WScript.Shell" & Chr(34) & " )" & vbNewLine
VBScriptString = VBScriptString & "WSHshell.AppActivate " & Chr(34) & " Excel.exe " & Chr(34) & " " & vbNewLine
VBScriptString = VBScriptString & "wsh.sleep 1000" & vbNewLine
VBScriptString = VBScriptString & "For i = 1 To 14" & vbNewLine
VBScriptString = VBScriptString & "WSHshell.SendKeys  " & Chr(34) & "^" & Chr(34) & "&" & Chr(34) & "{PGDN}" & Chr(34) & " " & vbNewLine
VBScriptString = VBScriptString & "wsh.sleep 500" & vbNewLine
VBScriptString = VBScriptString & "WSHshell.SendKeys " & Chr(34) & "%psp" & Chr(34) & " " & vbNewLine
VBScriptString = VBScriptString & "wsh.sleep 2500" & vbNewLine
VBScriptString = VBScriptString & "WSHshell.SendKeys " & Chr(34) & "{TAB 1}" & Chr(34) & " " & vbNewLine
VBScriptString = VBScriptString & "wsh.sleep 500" & vbNewLine
VBScriptString = VBScriptString & "WSHshell.SendKeys " & Chr(34) & "o" & Chr(34) & " " & vbNewLine
VBScriptString = VBScriptString & "wsh.sleep 3500" & vbNewLine
VBScriptString = VBScriptString & "WSHshell.SendKeys " & Chr(34) & "{TAB 4}" & Chr(34) & " " & vbNewLine
VBScriptString = VBScriptString & "wsh.sleep 500" & vbNewLine
VBScriptString = VBScriptString & "WSHshell.SendKeys " & Chr(34) & "n" & Chr(34) & " " & vbNewLine
VBScriptString = VBScriptString & "WSHshell.SendKeys " & Chr(34) & "y" & Chr(34) & " " & vbNewLine
VBScriptString = VBScriptString & "wsh.sleep 500" & vbNewLine
VBScriptString = VBScriptString & "WSHshell.SendKeys " & Chr(34) & "{TAB 2}" & Chr(34) & " " & vbNewLine
VBScriptString = VBScriptString & "WSHshell.SendKeys " & Chr(34) & "l" & Chr(34) & " " & vbNewLine
VBScriptString = VBScriptString & "wsh.sleep 500" & vbNewLine
VBScriptString = VBScriptString & "WSHshell.SendKeys " & Chr(34) & "{Enter}" & Chr(34) & " " & vbNewLine
VBScriptString = VBScriptString & "wsh.sleep 500" & vbNewLine
VBScriptString = VBScriptString & "WSHshell.SendKeys " & Chr(34) & "{Enter}" & Chr(34) & " " & vbNewLine
VBScriptString = VBScriptString & "wsh.sleep 500" & vbNewLine
VBScriptString = VBScriptString & "Next"

oFile.WriteLine VBScriptString

oFile.Close


Set fso = Nothing
Set oFile = Nothing




End Sub

工作原理:它检查是否存在外部 VBS 脚本。如果它没有找到它,它会编写它,然后它会使用 powershell 来调用脚本。然后,该脚本将使用 Excel“外部”的 sendkeys 来使一切正常运行 - 覆盖 Excel 固有的“不能将 sendkeys 用于对话框”

在能够做到这一点之前,我不得不将我的标准降低很多,我不推荐这样做。我相信除了双面打印之外的大多数东西,还有其他选择。但是,这确实使 sendkeys 可以与 Excel 对话框一起使用,这就是您要问的问题。

您当然需要编辑代码以用于您尝试使用 sendkeys 执行的操作 - 一种更简单的方法是直接编写 VBS 脚本 - 我需要我的脚本在任何计算机上运行我碰巧在的文件路径目录,因此具有写入后使用的功能。

您的脚本翻译如下:

VBScriptString  = VBScriptString  & "    Application.SendKeys (" & Chr(34)& "%p" & Chr(34)& "), True 'Selects Page Layout" & vbnewline
VBScriptString  = VBScriptString  & "    Application.SendKeys (" & Chr(34)& "%i" & Chr(34)& "), True 'Selects Print Titles" & vbnewline
VBScriptString  = VBScriptString  & "    Application.SendKeys (" & Chr(34)& "%o" & Chr(34)& "), True 'Selects Options" & vbnewline
VBScriptString  = VBScriptString  & "    Application.SendKeys (" & Chr(34)& "p" & Chr(34)& "), True  'Selects 'Portrait' default (this needs to be set up initially)" & vbnewline
VBScriptString  = VBScriptString  & "    Application.SendKeys " & Chr(34)& "{TAB 19}" & Chr(34)& ", True 'Tabs to OK" & vbnewline
VBScriptString  = VBScriptString  & "    Application.Wait (Now() + TimeValue(" & Chr(34)& "00:00:01" & Chr(34) & "))" & vbnewline
VBScriptString  = VBScriptString  & "    Application.SendKeys " & Chr34 & "~" & Chr(34)& ", True 'Hits enter to close screen" & vbnewline
VBScriptString  = VBScriptString  & "    Application.Wait (Now() + TimeValue(" & Chr(34)& "00:00:01" & Chr(34)& "))" & vbnewline
VBScriptString  = VBScriptString  & "    Application.SendKeys " & Chr(34)& "~" & Chr(34)& ", True 'Hits enter to close screen" & vbnewline

当然,您可能希望使用默认方法:

Worksheets("Sheet1").PageSetup.Orientation = xlPortrait

这是一种以纵向模式打印工作表的更简单方法

【讨论】:

  • 谢谢你,虽然我没有尝试在 Excel 中设置纵向,但纵向是打印机对话窗口中配置文件的名称,用于设置彩色打印、装订位置等。我是目前不在工作,但会试一试,尽管我已经开始研究另一种解决方案,这可能会证明更多的未来证明!
  • @bawpie:啊,明白了。我看到了代码的纵向部分,并认为您正在尝试设置该设置。我同意 sendkeys 不是很有未来的证明,但这样做的好处是它是纯 Excel/VBA :)
  • 所以我今天早上试了一下,它在指定的路径中创建了脚本,但随后我收到一条消息,指出“应用程序访问被拒绝”,我猜这发生在“Shell” wscript " & 文件路径,vbNormalFocus' 行。我也尝试对线路进行硬编码,但收到相同的错误消息 - 可能是因为我是通过远程访问进行的,所以一旦我回到办公室,我就会试一试。再次感谢!
  • 该错误与 Citrix 相关,根据您的建议,我已经调整了您现有的代码并且可以正常工作。但是有一个障碍 - 我需要它来循环浏览工作簿中的选定工作表。我认为这是在您的原始代码中完成的,因此我将进行进一步的比赛。不过,我会将其标记为解决方案,因为它完全按照我在原始问题中的要求进行 - 非常感谢您的帮助!
  • 是的,你需要循环它,我已经循环了我的原始代码 - 工作表确实需要按顺序排列
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-15
  • 2011-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多