24.02.2009, 10:53 | #1 |
Участник
|
Аксапта лезет в Excel
Здравствуйте уважаемые.
Давненько я не был на форуме. Как то все управлялся, а вот теперь не знаю чего делать. Вопрос не совсем аксаптовский, ногами прошу не бить, задача поставлена головной конторой управы на которую попросту нет, приходится делать. При создании документов сделали автоматическую печать документов. Соль в том, что ночами пакетно создается много документов и все они соответственно уходят на принтер. Документы формируются в экселе и выводятся соответственно на печать оттуда же. Обычный принтер такое безобразие естественно не выдерживает. Поэтому для этих целей поставили "хороший". Ему силенок хватает и все вроде хорошо. Да вот не удобно менеджера каждый вечер перенастраивать принтер по умолчанию. Попросили сделать настройку чтобы задавать принтер на который печатать, и при печати из пакетного режима чтобы настройки брало именно эти, а вручную что печатается чтобы на принтер по умолчанию. Через PrintJobSettings сделал и выбор принтера и настройку но это все для аксапты, а вот как это дело прикрутить к экселю не могу докумекать. Есть у экселя такое свойство ActivePrinter(для ApplicationObject и Worksheet), но как оно задается в хелпе не слова, а в примерах пишут что определяется оно непонятным образом. И даже список принтеров которые сам эксель предоставляет возвращает якобы не те строки которые нужны для передачи в ActivePrinter. Может кто делал что подобное? Буду крайне признателен за любую помощь
__________________
Хочу IQ как ICQ, ну или хотя бы ICQ как IQ. |
|
24.02.2009, 11:29 | #2 |
Участник
|
Вот записал макрос а екселе
X++: Application.ActivePrinter = "\\itdev1\HPLaserJet (Ne00:)" Application.ActivePrinter = "\\oko5\HP LaserJet 1018 (Ne01:)"
__________________
aLL woRk aNd nO JoY MAKes jAck a dULL Boy |
|
24.02.2009, 11:37 | #3 |
Участник
|
На сколько я понимаю 00 и 01 это указание порта к которому подключен принтер. Как мне получить его в аксапте? Везде Ne надо будет прописывать?
Вот что мне выдал эксель когда я попытался все принтеры поустанавливать какие у меня были в системе X++: Application.ActivePrinter = "\\AX_DEV\Canon[/url] LBP-810 (Ne01:)" Application.ActivePrinter = "\\wks-ukg-017\Canon[/url] LBP-810 (Ne02:)" Application.ActivePrinter = "Zebra ZM400 200 dpi (ZPL) (LPT1:)" Application.ActivePrinter = "SnagIt 9 (Ne00:)"
__________________
Хочу IQ как ICQ, ну или хотя бы ICQ как IQ. Последний раз редактировалось KingPeas; 24.02.2009 в 11:40. |
|
24.02.2009, 11:42 | #4 |
Участник
|
погуглил... пишут что эт действительно порт, информация храниться гдето в реестре)
__________________
aLL woRk aNd nO JoY MAKes jAck a dULL Boy |
|
24.02.2009, 11:43 | #5 |
Участник
|
Список установленных принтеров смотрите так
X++: foreach (string printer in System.Drawing.Printing.PrinterSettings.InstalledPrinters) { Console.WriteLine(printer); } |
|
24.02.2009, 11:50 | #6 |
Участник
|
На сколько я понимаю это .NET?
Опять на троих соображать? Здесь русский дух, здесь Русью пахнет P.S.: и это говорит пока еще казах
__________________
Хочу IQ как ICQ, ну или хотя бы ICQ как IQ. |
|
24.02.2009, 15:32 | #7 |
MCTS
|
winapi вариант. Возвращает контейнер с адресами принтеров:
X++: static client server container EnumPrinters() { container con; #define.PRINTER_ENUM_LOCAL(0x00000002) #define.PRINTER_ENUM_FAVORITE(0x00000004) DLL _winApiDLL = new DLL("winspool.drv"); DLLFunction _enumPrinters = new DLLFunction(_winApiDLL, 'EnumPrintersA'); Binary bytes_needed = new Binary(4); Binary returned = new Binary(4); Binary printers; Binary bStr = new Binary(255); Binary bByte = new Binary(1); Binary PRINTER_INFO_4; int ret, i, offs; ; _enumPrinters.returns(ExtTypes::DWord); _enumPrinters.arg( ExtTypes::DWord, ExtTypes::Pointer, ExtTypes::DWord, ExtTypes::Pointer, ExtTypes::DWord, ExtTypes::Pointer, ExtTypes::Pointer ); bStr.string(0, ""); bByte.byte(0, 0); ret = _enumPrinters.call( #PRINTER_ENUM_LOCAL | #PRINTER_ENUM_FAVORITE, bStr, 4, bByte, 0, bytes_needed, returned ); printers = new Binary(bytes_needed.dWord(0)); ret = _enumPrinters.call( #PRINTER_ENUM_LOCAL | #PRINTER_ENUM_FAVORITE, bStr, 4, printers, bytes_needed.dWord(0), bytes_needed, returned ); for (i = 0; i < returned.dWord(0); i++) { bStr.attach(printers.dWord(offs), 255); con += bStr.string(0); offs += 12; } return con; } Последний раз редактировалось Eldar9x; 24.02.2009 в 15:35. |
|
|
За это сообщение автора поблагодарили: aidsua (1). |
25.02.2009, 05:55 | #8 |
Участник
|
Вот только чистые названия принтеров эксель не кушает, ему нужно свое с указанием всех (Ne01, (LPT1 и т.д.
А получить список принтеров можно и через PrintJobSettings; Видел пост на форуме, правда где не помню, но через поиск легко найдете. Да и через SysFormPrint я уже диалог сделал для извлечения нужного имени. Проблема не в этом, а как скормить сие экселю
__________________
Хочу IQ как ICQ, ну или хотя бы ICQ как IQ. |
|
25.02.2009, 07:18 | #9 |
Участник
|
Цитата:
Цитата:
HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\PrinterPorts
HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Devices Цитата:
X++: static void jbPrinterListByPrintJobSettings(Args _args) { PrintJobSettings printJobSettings ; Name printerName ; Counter printerNum ; Counter printerCount; TempStr getPrinterPort( Name _printerName ) { int regKeyHandle ; TempStr printerPorts ; #WinAPI // #define.RegistryKey( 'Software\\Microsoft\\Windows NT\\CurrentVersion\\Devices' ) #define.RegistryKey( 'Software\\Microsoft\\Windows NT\\CurrentVersion\\PrinterPorts' ) ; regKeyHandle = WinAPI::regOpenKey( #HKEY_CURRENT_USER, #RegistryKey, #KEY_READ ) ; [ printerPorts ] = WinAPI::regGetValue( regKeyHandle, _printerName ) ; WinAPI::regCloseKey( regKeyHandle ); return strline( strreplace( printerPorts, ',', '\n' ), 1 ) ; } ; printJobSettings = new printJobSettings() ; printerCount = printJobSettings.getNumberOfPrinters() ; setPrefix( strfmt( "Number of printers: %1, default device: %2", printerCount, printJobSettings.deviceName() ) ) ; for( printerNum =1; printerNum <=printerCount; printerNum++ ) { printerName = printJobSettings.getPrinter( printerNum ) ; info( strfmt( "%1 (%2)", printerName, getPrinterPort( printerName ) ) ) ; } } |
|
|
За это сообщение автора поблагодарили: aidsua (1), KingPeas (1). |
25.02.2009, 07:46 | #10 |
MCTS
|
Цитата:
Проблема не в этом, а как скормить сие экселю
X++: COM doc, app;
;
doc = excel.getComDocument();
app = doc.Application();
app.ActivePrinter("\\\\ipp://192.168.20.1\\Printers_VO (Ne01:)"); X++: app.ActivePrinter("Printers_VO (Ne01:)"); Последний раз редактировалось Eldar9x; 25.02.2009 в 07:48. |
|
25.02.2009, 08:10 | #11 |
Участник
|
Я с реестром мало работал. Эти ветки неизменны будут для разных операционных? Получается если я поставлю на сервер то как это будет отрабатывать на клиентах?
Цитата:
__________________
Хочу IQ как ICQ, ну или хотя бы ICQ как IQ. |
|
25.02.2009, 09:08 | #12 |
MCTS
|
Дополнительно к функции WinAPI::EnumPrinters создайте еще одну:
X++: static client server str GetPrinterPort(str _printerName) { DLL _winApiDLL = new DLL("kernel32.dll"); DLLFunction _getProfileString = new DLLFunction(_winApiDLL, 'GetProfileStringA'); Binary _bStrApp = new Binary(10); Binary _bStrKey = new Binary(255); Binary _bStrDef = new Binary(1); Binary _bStrRet = new Binary(255); ; _getProfileString.returns(ExtTypes::DWord); _getProfileString.arg( ExtTypes::Pointer, ExtTypes::Pointer, ExtTypes::Pointer, ExtTypes::Pointer, ExtTypes::DWord); _bStrApp.string(0, "Devices"); _bStrKey.string(0, _printerName); _bStrDef.string(0, ""); _getProfileString.call( _bStrApp, _bStrKey, _bStrDef, _bStrRet, 255); return strReplace(_bStrRet.string(0), "winspool,", ''); } X++: static void listPrinters(Args _args) { container con; int i; ; con = WinAPI::EnumPrinters(); for (i = 1; i <= conlen(con); i++) info(strfmt("%1 (%2)", conpeek(con, i), winAPI::GetPrinterPort(conpeek(con, i)))); } |
|
|
За это сообщение автора поблагодарили: KingPeas (1), samolalex (2). |
25.02.2009, 09:41 | #13 |
Участник
|
Цитата:
Цитата:
GetProfileString Function
Retrieves the string associated with a key in the specified section of the Win.ini file. Note This function is provided only for compatibility with 16-bit Windows-based applications, therefore this function should not be called from server code. Applications should store initialization information in the registry. Цитата:
Windows Server 2003 and Windows XP/2000: Calls to profile functions may be mapped to the registry instead of to the initialization files. This mapping occurs when the initialization file and section are specified in the registry under the following keys:
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\ CurrentVersion\IniFileMapping В случае маппинга секции HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\IniFileMapping чтение ключа "Devices" приведет к обращению к ветке реестра USR:Software\Microsoft\Windows NT\CurrentVersion\Devices Последний раз редактировалось petergunn; 25.02.2009 в 10:06. |
|
25.02.2009, 10:09 | #14 |
MCTS
|
Цитата:
В итоге чтение ключа "Devices" все равно приведет к обращению к ветке реестра USR:Software\Microsoft\Windows NT\CurrentVersion\Devices
зы: вообще то разница есть. С использованием getprofilestring, мы получаем большую универсальность. Не надо задумываться о том, в какую ветку реестра надо лезть. Последний раз редактировалось Eldar9x; 25.02.2009 в 10:21. |
|
25.02.2009, 10:10 | #15 |
Участник
|
Цитата:
Только я обрадовался что мне уже все подсказали)))
__________________
Хочу IQ как ICQ, ну или хотя бы ICQ как IQ. |
|