هانس در تلاش است تا چاپگر فعال را در یک ماکرو VBA تغییر دهد، اما هر کاری که او امتحان می کند در هنگام اجرای کد منجر به پیام خطا می شود. این باعث می شود او به این فکر کند که آیا نوعی راز برای تغییر چاپگر فعال وجود دارد یا خیر.
در گذشته، اکسل به شما اجازه می داد چاپگر فعال را با استفاده از یک خط کد ماکرو تغییر دهید، مانند این:
Application.ActivePrinter = "HP LaserJet"
با این حال، این رویکرد ساده دیگر در نسخه های جدیدتر اکسل کار نخواهد کرد. در عوض، باید چیزی شبیه به این باشد:
Application.ActivePrinter = "HP LaserJet on Ne00:"
تفاوت این است که در حال حاضر شما باید نه تنها نام چاپگر، بلکه پورتی را که باید برای ارتباط با آن چاپگر استفاده کنید را نیز درج کنید. مشخص نیست چه زمانی این تغییر نحو انجام شده است، اما زمانی قبل از ورود مایکروسافت 365 بود.
برای نشان دادن سردرگمی ایجاد شده در اکسل، Ctrl+P را فشار دهید تا تنظیمات چاپ نمایش داده شود. خواهید دید که نزدیک بالای تنظیمات یک چاپگر انتخاب شده است. نام چاپگر دقیقاً همین است - نام چاپگری که اکسل روی آن چاپ خواهد کرد. از لحاظ تاریخی، می توانید نام این چاپگر را بگیرید و از آن در یک ماکرو برای تنظیم چاپگر فعال استفاده کنید. با این حال، نامی که در ماکرو استفاده می کنید، اکنون باید شامل نام پورت باشد. و همانطور که می بینید وقتی Ctrl+P را فشار می دهید ، نام چاپگر نشان داده شده نام پورت را نشان نمی دهد.
با استفاده از یک ماکرو تک خطی مانند زیر می توانید نام چاپگر و پورت را خیلی ساده تعیین کنید:
Sub WhatPrinter()
MsgBox Application.ActivePrinter
End Sub
ماکرو را اجرا کنید و مشخصات کامل چاپگر فعال خود را خواهید دید. (شکل 1 را ببینید.)
شکل 1. خروجی از اجرای ماکرو WhatPrinter.
می توانید به صورت دستی چاپگرها را در اکسل تغییر دهید، این ماکرو را مجدداً اجرا کنید و سپس نام کامل (از جمله تعیین پورت) را برای هر چاپگر یادداشت کنید. سپس می توانید در ماکرو خود از هر نام کاملی که برای برآوردن نیازهای خروجی خود لازم است استفاده کنید.
اگر ماکرو را فقط روی سیستم خود اجرا می کنید، این یک رویکرد قابل اجرا است. اگر ماکرو شما برای دیگران در دفتر شما در نظر گرفته شده باشد چه؟ برای مثال، فرض کنید پنج نفر در بخش شما هستند و همه شما سه چاپگر مشترک دارید. حتی اگر همه شما از نام های پایه چاپگر استفاده کنید (که البته بر اساس نام درایور چاپگر در هر سیستم است)، هر سیستم شخصی می تواند چاپگر را با پورت متفاوتی مرتبط کند. بنابراین، در سیستم شما، چاپگر می تواند "HP LaserJet در Ne00:" باشد، اما در سیستم افراد مختلف می تواند "HP LaserJet در Ne03:" باشد. اگر از نام های چاپگر/پورت سخت کد شده بر اساس آنچه در سیستم شما است استفاده می کنید، ماکرو شما به دلیل تفاوت های پورت روی سیستم های مختلف کار نمی کند.
همه چیز بسیار پیچیده تر شده است، زیرا باید با ویندوز کار کنید - در سطح سیستم عامل است که جفت های چاپگر و پورت تنظیم می شوند. در صورت تمایل می توانید از یک ماکرو مانند زیر برای گرفتن لیستی از چاپگرها و پورت ها از رجیستری ویندوز استفاده کنید:
Sub GetPrinterList()
Dim Arr As Variant
Dim Device As Variant
Dim Devices As Variant
Dim RegObj As Object
Dim RegValue As String
Dim PList As String
Const HKEY_CURRENT_USER = &H80000001
Const REG_KEY As String = "SoftwareMicrosoftWindows NTCurrentVersionDevices"
Set RegObj = GetObject("winmgmts:{impersonationLevel=impersonate}!\.
ootdefault:StdRegProv")
RegObj.enumvalues HKEY_CURRENT_USER, REG_KEY, Devices, Arr
PList = ""
For Each Device In Devices
RegObj.getstringvalue HKEY_CURRENT_USER, REG_KEY, Device, RegValue
PList = PList & Device & " on " & Split(RegValue, ",")(1) & vbCrLf
Next
MsgBox PList
End Sub
ماکرو مجموعه ای از دستگاه ها را از کلید رجیستری مشخص شده در ثابت REG_KEY می گیرد. این مجموعه قدم گذاشته و پیامی بر اساس آن دستگاه ها ساخته شده است. در نهایت پیام نمایش داده می شود.
یک تغییر در این رویکرد به شما امکان می دهد فقط ترکیب چاپگر/پورت مورد نظر را بر اساس نام جزئی چاپگر بگیرید:
Function FindPrinter(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
Const REG_KEY As String = "SoftwareMicrosoftWindows NTCurrentVersionDevices"
Set RegObj = GetObject("winmgmts:{impersonationLevel=impersonate}!\.
ootdefault:StdRegProv")
RegObj.enumvalues HKEY_CURRENT_USER, REG_KEY, Devices, Arr
For Each Device In Devices
RegObj.getstringvalue HKEY_CURRENT_USER, REG_KEY, 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
برای آزمایش ماکرو، تنها کاری که باید انجام دهید این است که نام چاپگر پایه جزئی را به آن منتقل کنید، همانطور که در اینجا انجام می شود:
Sub TestFindP()
Dim sP As String
sP = "MX-5070N"
MsgBox FindPrinter(sP)
End Sub
تابع FindPrinter، در این مورد، اولین چاپگری را که متن "MX-5070N" را در خود دارد، برمی گرداند. می توانید از آنچه FindPrinter برمی گرداند استفاده کنید تا چاپگر فعال را برای استفاده توسط اکسل تنظیم کنید.
در نهایت، اگر نام کامل چاپگر پایه را می دانید اما پورت آن را نمی دانید، می توانید از پوسته اسکریپت نویسی ویندوز بسیار کوتاه تر برای بیرون کشیدن اطلاعات پورت از رجیستری ویندوز استفاده کنید، به این ترتیب:
Function GetFullPrinter(sPtrName As String) As String
Dim vPort As Variant
Dim sSetting As String
Const REG_KEY As String = "HKEY_CURRENT_USERSoftwareMicrosoftWindows NTCurrentVersionDevices"
sSetting = CreateObject("WScript.Shell").RegRead(REG_KEY & sPtrName)
vPort = Split(sSetting, ",")
GetFullPrinter = sPtrName & " on " & vPort(1)
End Function
این تابع، هنگامی که یک نام چاپگر پایه ارسال می شود، نام چاپگر کاملاً شکل گرفته، از جمله پورت را که می توانید برای تنظیم چاپگر فعال استفاده کنید، برمی گرداند. برای آزمایش آن، چیزی شبیه به این ماکرو را امتحان کنید:
Sub TestGFP()
Dim sP As String
sP = "MX-5070N (Color)"
MsgBox GetFullPrinter(sP)
End Sub
به شرطی که متغیر sP را روی یک نام چاپگر پایه معتبر برای سیستمی که ماکرو در آن اجرا می شود تنظیم کرده باشید، یک نام چاپگر کاملاً شکل گرفته، از جمله پورت مناسب برای آن سیستم را نمایش می دهد.