excel - 仅在打印机处于事件状态时使用注册表设置默认打印机 VBA

标签 excel vba function printing

我使用 Leith Ross 的 VBA 代码循环浏览我的机器/网络上的打印机,并选择与我传递的参数匹配的打印机作为默认打印机。见下文:

Function FindPrinter(ByVal PrinterName As String) As String

  Dim Arr As Variant
  Dim Device As Variant
  Dim Devices As Variant
  Dim Printer As String
  Dim RegObj As Object
  Dim RegValue As String
  Const HKEY_CURRENT_USER = &H80000001

  Set RegObj = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
  RegObj.enumvalues HKEY_CURRENT_USER, "Software\Microsoft\Windows NT\CurrentVersion\Devices", Devices, Arr

  For Each Device In Devices
    RegObj.getstringvalue HKEY_CURRENT_USER, "Software\Microsoft\Windows NT\CurrentVersion\Devices", Device, RegValue
    Printer = Device & " on " & Split(RegValue, ",")(1)
    If InStr(1, Printer, PrinterName, vbTextCompare) > 0 Then
       FindPrinter = Printer
       Exit Function
     End If
  Next


End Function

这会稍微复杂一些,因为 IT 有时会为打印机命名略有不同的名称。尽管如此,我使用的功能还是找到了我正在寻找的打印机并将其设置为默认打印机。

当使用此代码的某些计算机上具有重复的打印机驱动程序/软件时,真正的问题就出现了,并且其中只有一个在线,而其余的则离线。我通常必须让 IT 人员卸载离线驱动程序,否则此功能有时会抓取离线驱动程序并且代码不起作用。我不必依赖它们来执行此操作,而是有兴趣修改此功能,以便仅将事件打印机设置为我将其传递给的任何标准,仅当打印机与 Instr 匹配时功能中的条件处于事件状态。

VBA 中是否有任何内容,和/或我可以添加到此代码中以检查打印机是否与 Instr 匹配条件实际上是在线的,如果是 THEN FindPrinter = Printer Exit Function ?我的在线搜索结果并没有真正的帮助;几乎所有东西都提供此功能或其他一些功能来显示/设置默认打印机。

编辑:请注意,并不是真的在寻找讲义答案,尽管如果您提供确切的操作方法,那么我将不胜感激。如果您更倾向于将我链接到有关在哪里可以找到答案/解决方案的文档,我将非常乐意进行研究。

最佳答案

由于这将是一个链接,否则只能回答,我在下面发布相关文本......

无耻地从 http://www.merrioncomputing.com/Programming/PrintStatus.htm 盗取

从 Visual Basic 获取选定打印机的状态
打印机对象遗漏了什么

长期以来,在 Visual Basic 中开发完整和专业的应用程序时,打印一直是一个非常有问题的部分。这在很大程度上通过 Visual Basic 4 中引入的新打印机对象得到了纠正。

然而,这个对象也有缺点。最大的缺点是您无法从您的应用程序中了解打印机是否准备就绪、忙碌、缺纸等。

幸运的是,有一个 API 调用 GetPrinter,它返回有关打印机的更多信息。

Private Declare Function GetPrinterApi Lib "winspool.drv" Alias _
       "GetPrinterA" (ByVal hPrinter As Long, _
         ByVal Level As Long, _
         buffer As Long, _
         ByVal pbSize As Long, _
         pbSizeNeeded As Long) As Long

这将处理 hPrinter 中的打印机,并使用来自打印机驱动程序的信息填充提供给它的缓冲区。要从 Printer 对象获取句柄,您需要使用 OpenPrinter API 调用。
完成后,必须使用 ClosePrinter API 调用释放此句柄。
Private Type PRINTER_DEFAULTS
  pDatatype As String
  pDevMode As DEVMODE
  DesiredAccess As Long
End Type

Private Declare Function OpenPrinter Lib "winspool.drv" _
    Alias "OpenPrinterA" (ByVal pPrinterName As String, _
    phPrinter As Long, pDefault As PRINTER_DEFAULTS) As Long

Private Declare Function ClosePrinter Lib "winspool.drv" _
    (ByVal hPrinter As Long) As Long

您将 Printer.DeviceName 传递给此以获取句柄。
Dim lret As Long
Dim pDef As PRINTER_DEFAULTS

lret = OpenPrinter(Printer.DeviceName, mhPrinter, pDef)

不同的状态

打印机驱动程序可以返回多种标准状态。
Public Enum Printer_Status
   PRINTER_STATUS_READY = &H0
   PRINTER_STATUS_PAUSED = &H1
   PRINTER_STATUS_ERROR = &H2
   PRINTER_STATUS_PENDING_DELETION = &H4
   PRINTER_STATUS_PAPER_JAM = &H8
   PRINTER_STATUS_PAPER_OUT = &H10
   PRINTER_STATUS_MANUAL_FEED = &H20
   PRINTER_STATUS_PAPER_PROBLEM = &H40
   PRINTER_STATUS_OFFLINE = &H80
   PRINTER_STATUS_IO_ACTIVE = &H100
   PRINTER_STATUS_BUSY = &H200
   PRINTER_STATUS_PRINTING = &H400
   PRINTER_STATUS_OUTPUT_BIN_FULL = &H800
   PRINTER_STATUS_NOT_AVAILABLE = &H1000
   PRINTER_STATUS_WAITING = &H2000
   PRINTER_STATUS_PROCESSING = &H4000
   PRINTER_STATUS_INITIALIZING = &H8000
   PRINTER_STATUS_WARMING_UP = &H10000
   PRINTER_STATUS_TONER_LOW = &H20000
   PRINTER_STATUS_NO_TONER = &H40000
   PRINTER_STATUS_PAGE_PUNT = &H80000
   PRINTER_STATUS_USER_INTERVENTION = &H100000
   PRINTER_STATUS_OUT_OF_MEMORY = &H200000
   PRINTER_STATUS_DOOR_OPEN = &H400000
   PRINTER_STATUS_SERVER_UNKNOWN = &H800000
   PRINTER_STATUS_POWER_SAVE = &H1000000
End Enum 

关于excel - 仅在打印机处于事件状态时使用注册表设置默认打印机 VBA,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31458654/

相关文章:

javascript - 检查 JavaScript 中的对象内部是否存在私有(private)函数

excel - 带动态数字的命令按钮

java - Grails Date 构造函数和解析日期

Excel 单元格格式 - 水平对齐

arrays - 如何将字符串类型数组转换为变体类型数组 - Excel VBA

c - 我是否需要将 ascii 转换为 uint8_t 以通过 uart(腻子)写入和显示

java - 如何在Android Studio中管理文件

arrays - VBA转置类型不匹配错误

excel - 复制一系列单元格,仅选择包含数据的单元格,仅选择值而不是公式

vba - 如何将 8 个文本框中的值求和到单个文本框中?