如何用VBA 7.1控制Word打印对话框的黑白/双面属性?
Word VBA控制佳能TR7600打印黑白/双面的解决方案
问题总结
- 需求:通过宏或打印预设,控制佳能TR7600打印机的「黑白打印」开关,同时实现双面打印的开关控制。
- 现有问题:
- Word打印预设无法保存「黑白」属性,仅能保存双面等Word层面的设置;
- 录制宏生成的代码不包含黑白打印参数,手动添加
Black & White:=False会报错。
核心原因
- 打印预设限制:Word的打印预设仅存储Word应用程序层面的设置(如双面、页码范围),而佳能TR7600的「黑白打印」属于打印机驱动级自定义设置,无法被Word预设保存。
- 宏录制局限:Word宏录制器仅记录
PrintOut方法的标准参数,驱动级的打印设置不会被捕获,因此录制的代码缺失黑白控制逻辑。
解决方案
方法1:通过Word Printer对象直接控制(推荐)
利用Word的Application.Printer对象,直接读取/修改打印机的黑白、双面属性,打印完成后恢复原始设置避免影响后续打印:
' 彩色双面打印宏 Sub PrintColorDoubleSided() Dim originalPrinter As Printer Dim originalBW As Boolean Dim originalDuplex As WdPrintDuplex ' 保存当前打印机的原始设置 Set originalPrinter = Application.Printer originalBW = originalPrinter.BlackAndWhite originalDuplex = originalPrinter.Duplex ' 出错时自动恢复设置 On Error GoTo RestoreSettings ' 设置为彩色+双面打印(长边翻转,适合纵向文档) originalPrinter.BlackAndWhite = False originalPrinter.Duplex = wdPrintDuplexFlipLongEdge ' 执行打印(可根据需求调整参数) ActiveDocument.PrintOut _ Range:=wdPrintAllDocument, _ Item:=wdPrintDocumentContent, _ Copies:=1, _ Collate:=True RestoreSettings: ' 恢复打印机原始设置 originalPrinter.BlackAndWhite = originalBW originalPrinter.Duplex = originalDuplex Set originalPrinter = Nothing End Sub ' 黑白单面打印宏 Sub PrintBlackWhiteSingleSided() Dim originalPrinter As Printer Dim originalBW As Boolean Dim originalDuplex As WdPrintDuplex Set originalPrinter = Application.Printer originalBW = originalPrinter.BlackAndWhite originalDuplex = originalPrinter.Duplex On Error GoTo RestoreSettings ' 设置为黑白+单面打印 originalPrinter.BlackAndWhite = True originalPrinter.Duplex = wdPrintDuplexNone ActiveDocument.PrintOut _ Range:=wdPrintAllDocument, _ Item:=wdPrintDocumentContent, _ Copies:=1, _ Collate:=True RestoreSettings: originalPrinter.BlackAndWhite = originalBW originalPrinter.Duplex = originalDuplex Set originalPrinter = Nothing End Sub
说明:
- 若你的打印机驱动不支持
BlackAndWhite属性(执行报错),则需要使用方法2。 - 双面打印的常量:
wdPrintDuplexNone:单面打印wdPrintDuplexFlipLongEdge:长边翻转双面(纵向文档)wdPrintDuplexFlipShortEdge:短边翻转双面(横向文档)
方法2:通过Windows API修改打印机DEVMODE(驱动级控制)
如果Printer对象的BlackAndWhite属性无效,需要直接修改打印机的DEVMODE结构(适合驱动级自定义设置),以下是简化版代码:
Option Explicit Private Declare PtrSafe Function OpenPrinter Lib "winspool.drv" Alias "OpenPrinterA" (ByVal pPrinterName As String, phPrinter As LongPtr, pDefault As Any) As Long Private Declare PtrSafe Function ClosePrinter Lib "winspool.drv" (ByVal hPrinter As LongPtr) As Long Private Declare PtrSafe Function GetPrinter Lib "winspool.drv" Alias "GetPrinterA" (ByVal hPrinter As LongPtr, ByVal Level As Long, pPrinter As Any, ByVal cbBuf As Long, pcbNeeded As Long) As Long Private Declare PtrSafe Function SetPrinter Lib "winspool.drv" Alias "SetPrinterA" (ByVal hPrinter As LongPtr, ByVal Level As Long, pPrinter As Any, ByVal Command As Long) As Long Private Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long) Private Type DEVMODE dmDeviceName As String * 32 dmSpecVersion As Integer dmDriverVersion As Integer dmSize As Integer dmDriverExtra As Integer dmFields As Long dmOrientation As Integer dmPaperSize As Integer dmPaperLength As Integer dmPaperWidth As Integer dmScale As Integer dmCopies As Integer dmDefaultSource As Integer dmPrintQuality As Integer dmColor As Integer ' 关键:0=彩色,1=黑白 dmDuplex As Integer dmYResolution As Integer dmTTOption As Integer dmCollate As Integer dmFormName As String * 32 dmUnusedPadding As Integer dmBitsPerPel As Integer dmPelsWidth As Long dmPelsHeight As Long dmDisplayFlags As Long dmDisplayFrequency As Long End Type Private Type PRINTER_INFO_2 pServerName As LongPtr pPrinterName As LongPtr pShareName As LongPtr pPortName As LongPtr pDriverName As LongPtr pComment As LongPtr pLocation As LongPtr pDevMode As LongPtr pSepFile As LongPtr pPrintProcessor As LongPtr pDatatype As LongPtr pParameters As LongPtr pSecurityDescriptor As LongPtr Attributes As Long Priority As Long DefaultPriority As Long StartTime As Long UntilTime As Long Status As Long cJobs As Long AveragePPM As Long End Type Sub SetBlackAndWhitePrint(enableBW As Boolean) Dim hPrinter As LongPtr Dim pi2 As PRINTER_INFO_2 Dim dm As DEVMODE Dim cbNeeded As Long Dim printerName As String Dim ret As Long ' 获取当前打印机名称 printerName = Application.Printer.Name ' 打开打印机 If OpenPrinter(printerName, hPrinter, ByVal 0&) = 0 Then Exit Sub ' 获取PRINTER_INFO_2所需缓冲区大小 GetPrinter hPrinter, 2, ByVal 0&, 0, cbNeeded ret = GetPrinter(hPrinter, 2, pi2, cbNeeded, cbNeeded) ' 读取DEVMODE结构 CopyMemory dm, ByVal pi2.pDevMode, Len(dm) ' 设置黑白/彩色 dm.dmFields = dm.dmFields Or &H80 ' 启用dmColor字段 dm.dmColor = IIf(enableBW, 1, 0) ' 1=黑白,0=彩色 ' 写入修改后的DEVMODE CopyMemory ByVal pi2.pDevMode, dm, Len(dm) ' 应用设置 SetPrinter hPrinter, 2, pi2, 0 ' 关闭打印机 ClosePrinter hPrinter End Sub ' 使用示例:黑白双面打印 Sub PrintBlackWhiteDoubleSided() Dim originalDuplex As WdPrintDuplex Dim originalBW As Boolean ' 保存原始设置 originalDuplex = Application.Printer.Duplex originalBW = Application.Printer.BlackAndWhite ' 设置黑白打印 SetBlackAndWhitePrint True ' 设置双面打印 Application.Printer.Duplex = wdPrintDuplexFlipLongEdge ' 执行打印 ActiveDocument.PrintOut Range:=wdPrintAllDocument, Copies:=1 ' 恢复原始设置 Application.Printer.Duplex = originalDuplex SetBlackAndWhitePrint originalBW End Sub
说明:
- 代码中
dmColor字段控制黑白/彩色,需根据你的佳能TR7600驱动确认取值(部分驱动可能用其他字段,可通过打印机属性工具查看DEVMODE结构); - 上述代码适配64位Word,32位Word需移除
PtrSafe关键字。
注意事项
- 运行宏前需确保Word启用了宏功能(文件->选项->信任中心->信任中心设置->宏设置);
- API方法需谨慎使用,错误修改DEVMODE可能导致打印机设置异常。
内容的提问来源于stack exchange,提问作者Tim Perrin
相关产品推荐
相关产品推荐

