Здравствуйте, или я так сильно туплю... или одно из двух... Документ ЭКСЕЛЬ сохраняется в "облаке" и из разных мест к нему происходит обращение, естественно и периодическая печать, но т.к. на разных машинах стоят разные по умолчанию принтеры, то и печать происходит "везде где только можно", как вставить в существующий макрос печати что-бы печать проводилась только на сетевом принтере (или через порт standart TCP/IP port IP_192.168.0.104 или по айпишнику 192.168.0.104) Подобное на сайте не нашел... хотя в списке установленных принтер существует и мышкой выбирается.при записи макроса макрорекордером в теле самого макроса выбора принтера нет, и после переоткрытия документа печать все-равно происходит через "по умолчанию".
Изменено: edkudin - 23.07.2018 09:00:03(Два вопроса в одной теме)
Два разных вопроса в одной теме. По вопросу принтера - можете назначить нужный принтер и потом в коде посмотреть как он распознается системой через s = Application.ActivePrinter. Далее надо будет просто выставлять принудительно перед печатью кодом этот принтер в качестве активного: Application.ActivePrinter = s. Пример подобного кода я приводил здесь: Как из VBA выбрать и установить принтер для Excel Не прям то, что Вам надо, но в качестве именно примера должно помочь. По вопросу просмотра кода - наверное, надо создавать отдельную тему для отдельного обсуждения, как того требуют правила форума. Т.к. причина может быть не совсем очевидной.
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
Андрей VG, Андрей, приветствую, ТС вроде пытался не выбор обеспечить, а указать конкретный.
edkudin, Думаю ссылки на MS не хватит. Прочел первый пост более внимательно, если правильно понял, то могут быть установлены разные по названию (которые мы не знаем) сетевые принтера и нужно выбрать тот, что с указанным портом (который мы знаем) Тут на помощь придет WMI select Name from Win32_Printer where PortName='IP_192.168.0.104' Но и тут будет проблемка ибо имя порта можно также изменить тогда сперва select Name from Win32_TCPIPPrinterPort where HostAddress='192.168.0.104' И полученное используем в первом запросе. Ну а это имя уже использовать для печати.
Код
const strComputer = "."
Const strHostaddress = "192.168.0.104"
Dim strPrinterName As String
Dim strPortName As String
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colInstalledPorts = objWMIService.ExecQuery("Select * from Win32_TCPIPPrinterPort Where HostAddress = '" & strHostaddress & "'")
For Each objPort In colInstalledPorts
strPortName = objPort.Name
Set colInstalledPrinters = objWMIService.ExecQuery("Select Name from Win32_Printer where PortName='" & strPortName & "'")
For Each objPrinter In colInstalledPrinters
strPrinterName = objPrinter.Name
Next
Next
If strPrinterName <> "" Then Worksheets("sheet1").PrintOut ActivePrinter:=strPrinterName
Да уважаемый БМВ, вы конечно абсолютно правы, могут быть разные принтеры но айпишник у них всегда один и тот-же, пока я еще не разобрался с вашим ответом №7 но надеюсь получится. сейчас хотя-бы принудительно выскакивает выбор принтера и отпечатать можно правильно Спасибо
ExecQuery("Select Name, HostAddress From Win32_TCPIPPrinterPort")
не возвращает все порты принтеров. Запускал сугубо под обычнопользовательской учёткой (другой нет), из двух сетевых принтеров, порт фактически найден только для одного и почему-то аж в трёх экземплярах. Из которых в списке портов свойств принтера реально существует только один.
Андрей VG, Андрей, привет. А точно принтера сетевые подключены не через принт сервер и через шару, а именно напрямую через сеть и именно по TCP/IP? WSD и прочие порты - естевенно в другой ветке.
Select Name, PortName from Win32_Printer что показывает?
Как видишь, они ссылаются на один IP Adress. А вот второго принтера нет. Хотя в свойствах он есть (тот, который F8_622 - им раз в месяц, квартал пользуюсь).
Плюс, код не совсем полный. Нужен ещё и суффикс \\path\F8_622 (Ne02:). Впрочем он вполне по имени находится в реестре.
Андрей VG, Андрей, Всеж думаю что принтер подключен через принт сервер где подключен напрямую (уже по TCP/IP или иным образом) и расшарен. Это нормальная практика. Порт при этом виден, так как передается в свойствах принтера, но его нет на локальном ПК. Проверить просто, зайдите в свойства принтера и посмотрите на акладку общий доступ (Sharing) / Скорее всего стоит галочка что расшарен, но не доступная. Более того \\path\F8_622 как раз говорит что принтер расшарен на сервере. использовать для печати \\path\F8_622 можно на ровне что просто обратится по имени принтера в системе. Посмотрите Select Name, PortName, ServerName, ShareName from Win32_Printer У подключенного напрямую два последних будут пустыми.
У нас схема сети примерно такая- три крупных подсети (одноранговых, без выделенного сервера) связаны между собой, в каждой из них используется пул адресов "серой сети" 192.168.0.101-155, айпи назначается сервером dhcp (вайфай роутером) в двух из них стоит по сетевому принтеру Xerox WorkCentre 4118 MFP/X подключенных 45 кабелем к роутеру. В одной сети стоит Xerox VersaLink C7000DN подключенный через вай-фай напрямую в дропбокс. Печать "хитрых документов" проводится на них, потому как у них автоматическая двусторонняя печать и брошуровка. Для всех этих принтеров в настройках dhcp зарезервирован адрес 192.168.0.104 и он не меняется, а у остальных клиентов "плавающие адреса...
edkudin, Дело не в топологии сети, а в методике подключения принтера. Я давно не подключаю принтера напрямую, только через принт сервер. Причин несколько 1. Простота подключения клиента даже в ручном режиме. Зашел на \\<server>\ выбрал нужный принтер из списка или просто \\<server>\<shareName>, он подключится и драйвера с сервера скопируются и установятся. 2. Управляемость - можно на уровне групп безопасности ограничить печать на определенный принтер, можно очередями управлять и их приоритетом. 3. Логи печати централизованы.
Вам ничего не мешает попробовать, выше скрипт почти готовый.
Скрытый текст
Код
Sub Печать_4118_сетевой()
' Печать_4118_сетевой Макрос
Dim v, s
Dim strTargetPrinterName
strTargetPrinterName = GetTcpIPPrinter("192.168.0.104")
If strTargetPrinterName <> "" Then
s = Application.ActivePrinter
Application.ActivePrinter = strTargetPrinterName
Application.ScreenUpdating = False
Worksheets("Расшифровка_о_расходе").PrintOut Copies:=3, Collate:=True, IgnorePrintAreas:=False
Worksheets("Донесение").PrintOut Copies:=3, Collate:=True, IgnorePrintAreas:=False
Worksheets("Акт_списания").PrintOut Copies:=3, Collate:=True, IgnorePrintAreas:=False
Worksheets("Акт_списания (2)").PrintOut Copies:=2, Collate:=True, IgnorePrintAreas:=False
Worksheets("Ведомость_замера").PrintOut Copies:=1, Collate:=True, IgnorePrintAreas:=False
Worksheets("Протокол").PrintOut Copies:=1, Collate:=True, IgnorePrintAreas:=False
Worksheets("Реестр").PrintOut Copies:=2, Collate:=True, IgnorePrintAreas:=False
Worksheets("Реестр(2)").PrintOut Copies:=2, Collate:=True, IgnorePrintAreas:=False
Worksheets("Округление").Select
Application.ActivePrinter = s
Application.ScreenUpdating = 1
Worksheets("Округление").Range("H41").Value = s
Else
MsgBox "The printer is not connected to this system!"
End If
End Sub
Function GetTcpIPPrinter(ByVal strHostAddress As String) As String
'Return name of network printer connected directly to PC via tcpip port
Const strComputer = "."
Dim strPrinterName As String
Dim strPortName As String
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colInstalledPorts = objWMIService.ExecQuery("Select * from Win32_TCPIPPrinterPort Where HostAddress = '" & strHostAddress & "'")
For Each objPort In colInstalledPorts
strPortName = objPort.Name
Set colInstalledPrinters = objWMIService.ExecQuery("Select Name from Win32_Printer where PortName='" & strPortName & "'")
For Each objPrinter In colInstalledPrinters
GetTCIPPrinter = objPrinter.Name
Next
Next
End Function
Именно методика подключения и играет у нас роковую роль,- принтер стоит в отдельной комнате для печати, сервер иметь нельзя, актив директори под запретом..., сеть строго одноранговая, драйвера стоят на каждой машине, при "инициализации" каждый клиент проверяется по MAC адресу еще при подключении по вай-фай, чужая машина в сеть не войдет, со скриптом сегодня пока не получилось, уже ночь и компы сдали в секретку, попробую завтра. Если будут у кого какие мысли очень хотелось бы услышать!
edkudin написал: каждый клиент проверяется по MAC адресу еще при подключении по вай-фай, чужая машина в сеть не войдет,
ржунимагу, тема для курилки. Привет админам и ссылку на статью могу передать как сперва отловить используемые MAC в WiFi, а после поменять его на сетевухе и подключится, 802.1x . 802.11x обезопасят но это не по теме
я выше наШкодил свои мысли. Пробуйте. У меня все работает.
БМВ, работает без волшебных (Ne0x:)? И спасибо за консультацию. Все бы админы были столь вдумчивыми. Может проще зайти со сканирования ветки реестра HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Devices? Там как раз имена установленных принтеров и суффикы (Ne0x:) или (null:), а уже этими именами опрашивать Win32_Printer на предмет Network = True и PortName не пустое?
Андрей VG, тут дело вкуса. Хоть реестр и стандартизирован, и порой сам туда лезу, но если есть штатный механизм, предпочту его, было уже пара примеров, когда были отличия в ветках на XP и свежих. Network = True - это как раз признак того, что через сервер печати (расшаренный принтер на сервере) Выше писал но подумал что лишнее и стер. В системе принтер подключенный по IP числится как локальный, так же как и что подключен по USB, LPT,COM(RS232 …) . Мы просто называем такие принтера сетевыми, по тому что подключаются в LAN или WLAN. Подключенный таким образом принтер доступен для всех пользователей этого ПК.
Для этих сделал. Оба у меня получается шарой идут через принт-сервер.
Скрытый текст
Код
Public Sub TestNetworkPrinters()
Dim p As Collection, nPrinter
Set p = ExcelNetworkPrinterCollection
For Each nPrinter In p
Debug.Print nPrinter
Next
End Sub
Public Function ExcelNetworkPrinterCollection() As Collection
Const HKCU = &H80000001
Const printDeviceBranch = "Software\Microsoft\Windows NT\CurrentVersion\Devices"
Dim myPrinters As New Collection, nextName, nextValue
Dim pReg As Object, keyNames, keyValues, parts() As String
Dim pWMI As Object, wmiPrinters As Object, nextPrinter As Object
Set pReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")
Set pWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
pReg.EnumValues HKCU, printDeviceBranch, keyNames, keyValues
For Each nextName In keyNames
pReg.GetStringValue HKCU, printDeviceBranch, nextName, nextValue
Set wmiPrinters = pWMI.ExecQuery("Select Network From Win32_Printer Where Network <> 0 And Name = '" & Replace$(nextName, "\", "\\") & "'")
For Each nextPrinter In wmiPrinters
parts = Split(nextValue, ",")
myPrinters.Add nextName & " (" & parts(UBound(parts)) & ")"
Exit For
Next
Next
Set ExcelNetworkPrinterCollection = myPrinters
End Function