AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: База знаний и проекты
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 24.02.2009, 10:53   #1  
KingPeas is offline
KingPeas
Участник
Аватар для KingPeas
 
163 / 35 (2) +++
Регистрация: 09.01.2007
Адрес: Россия, Новосибирск
? Аксапта лезет в Excel
Здравствуйте уважаемые.
Давненько я не был на форуме. Как то все управлялся, а вот теперь не знаю чего делать.
Вопрос не совсем аксаптовский, ногами прошу не бить, задача поставлена головной конторой управы на которую попросту нет, приходится делать.
При создании документов сделали автоматическую печать документов. Соль в том, что ночами пакетно создается много документов и все они соответственно уходят на принтер. Документы формируются в экселе и выводятся соответственно на печать оттуда же. Обычный принтер такое безобразие естественно не выдерживает. Поэтому для этих целей поставили "хороший". Ему силенок хватает и все вроде хорошо. Да вот не удобно менеджера каждый вечер перенастраивать принтер по умолчанию.
Попросили сделать настройку чтобы задавать принтер на который печатать, и при печати из пакетного режима чтобы настройки брало именно эти, а вручную что печатается чтобы на принтер по умолчанию. Через PrintJobSettings сделал и выбор принтера и настройку но это все для аксапты, а вот как это дело прикрутить к экселю не могу докумекать.
Есть у экселя такое свойство ActivePrinter(для ApplicationObject и Worksheet), но как оно задается в хелпе не слова, а в примерах пишут что определяется оно непонятным образом. И даже список принтеров которые сам эксель предоставляет возвращает якобы не те строки которые нужны для передачи в ActivePrinter.
Может кто делал что подобное? Буду крайне признателен за любую помощь
__________________
Хочу IQ как ICQ, ну или хотя бы ICQ как IQ.
Старый 24.02.2009, 11:29   #2  
ivas is offline
ivas
Участник
Аватар для ivas
 
252 / 68 (3) ++++
Регистрация: 22.12.2005
Вот записал макрос а екселе
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  
KingPeas is offline
KingPeas
Участник
Аватар для KingPeas
 
163 / 35 (2) +++
Регистрация: 09.01.2007
Адрес: Россия, Новосибирск
Цитата:
Сообщение от ivas Посмотреть сообщение
выбор идет по имени принтера
На сколько я понимаю 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  
ivas is offline
ivas
Участник
Аватар для ivas
 
252 / 68 (3) ++++
Регистрация: 22.12.2005
погуглил... пишут что эт действительно порт, информация храниться гдето в реестре)
__________________
aLL woRk aNd nO JoY MAKes jAck a dULL Boy
Старый 24.02.2009, 11:43   #5  
_scorp_ is offline
_scorp_
Участник
Аватар для _scorp_
MCBMSS
 
488 / 369 (13) ++++++
Регистрация: 25.07.2007
Адрес: Москва
Список установленных принтеров смотрите так

X++:
foreach (string printer in System.Drawing.Printing.PrinterSettings.InstalledPrinters)
{
    Console.WriteLine(printer);
}
В цикле ищите свой принтер и потом подсовывайте его в ActivePrinter
Старый 24.02.2009, 11:50   #6  
KingPeas is offline
KingPeas
Участник
Аватар для KingPeas
 
163 / 35 (2) +++
Регистрация: 09.01.2007
Адрес: Россия, Новосибирск
Цитата:
Сообщение от _scorp_ Посмотреть сообщение
В цикле ищите свой принтер и потом подсовывайте его в ActivePrinter
На сколько я понимаю это .NET?
Опять на троих соображать? Здесь русский дух, здесь Русью пахнет
P.S.: и это говорит пока еще казах
__________________
Хочу IQ как ICQ, ну или хотя бы ICQ как IQ.
Старый 24.02.2009, 15:32   #7  
Eldar9x is offline
Eldar9x
MCTS
Аватар для Eldar9x
Oracle
MCBMSS
 
1,064 / 166 (8) ++++++
Регистрация: 29.09.2006
Адрес: Казань
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  
KingPeas is offline
KingPeas
Участник
Аватар для KingPeas
 
163 / 35 (2) +++
Регистрация: 09.01.2007
Адрес: Россия, Новосибирск
Цитата:
Сообщение от Eldar9x Посмотреть сообщение
winapi вариант. Возвращает контейнер с адресами принтеров:
Вот только чистые названия принтеров эксель не кушает, ему нужно свое с указанием всех (Ne01, (LPT1 и т.д.
А получить список принтеров можно и через PrintJobSettings; Видел пост на форуме, правда где не помню, но через поиск легко найдете. Да и через SysFormPrint я уже диалог сделал для извлечения нужного имени. Проблема не в этом, а как скормить сие экселю
__________________
Хочу IQ как ICQ, ну или хотя бы ICQ как IQ.
Старый 25.02.2009, 07:18   #9  
petergunn is offline
petergunn
Участник
 
118 / 274 (10) ++++++
Регистрация: 30.08.2005
Адрес: Tyumen
Цитата:
Сообщение от ivas Посмотреть сообщение
погуглил... пишут что эт действительно порт, информация храниться гдето в реестре)
Похоже что информация о портах есть в этих ветках реестра:
Цитата:
HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\PrinterPorts
HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Devices
Цитата:
Сообщение от KingPeas Посмотреть сообщение
Вот только чистые названия принтеров эксель не кушает, ему нужно свое с указанием всех (Ne01, (LPT1 и т.д.
А получить список принтеров можно и через PrintJobSettings;
Набросал небольшой job получения списка принтеров (и портов из реестра) :
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  
Eldar9x is offline
Eldar9x
MCTS
Аватар для Eldar9x
Oracle
MCBMSS
 
1,064 / 166 (8) ++++++
Регистрация: 29.09.2006
Адрес: Казань
Цитата:
Проблема не в этом, а как скормить сие экселю
дык, так и скормить:
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  
KingPeas is offline
KingPeas
Участник
Аватар для KingPeas
 
163 / 35 (2) +++
Регистрация: 09.01.2007
Адрес: Россия, Новосибирск
Цитата:
Сообщение от petergunn Посмотреть сообщение
Похоже что информация о портах есть в этих ветках реестра:
Я с реестром мало работал. Эти ветки неизменны будут для разных операционных? Получается если я поставлю на сервер то как это будет отрабатывать на клиентах?

Цитата:
Сообщение от Eldar9x Посмотреть сообщение
дык, так и скормить:
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:)");
не пройдет.
Получить имя принтера не проблема) И установить в экселе легко, вопрос как получить (Ne01 по имени принтера безболезненно и стабильно для любой системы
__________________
Хочу IQ как ICQ, ну или хотя бы ICQ как IQ.
Старый 25.02.2009, 09:08   #12  
Eldar9x is offline
Eldar9x
MCTS
Аватар для Eldar9x
Oracle
MCBMSS
 
1,064 / 166 (8) ++++++
Регистрация: 29.09.2006
Адрес: Казань
Дополнительно к функции 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  
petergunn is offline
petergunn
Участник
 
118 / 274 (10) ++++++
Регистрация: 30.08.2005
Адрес: Tyumen
Цитата:
Сообщение от Eldar9x Посмотреть сообщение
Дополнительно к функции WinAPI::EnumPrinters создайте еще одну:
X++:
static client server str GetPrinterPort(str _printerName)
{
    DLL         _winApiDLL = new DLL("kernel32.dll");
    DLLFunction _getProfileString = new DLLFunction(_winApiDLL, 'GetProfileStringA');
    ...
}
imho, использование GetProfileString не лучшее решение, т.к. эта функция в API присутсвует только для обратной совместимости с 16-bit приложениями.

Цитата:
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
Более подробно тут (msdn).
В случае маппинга секции 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  
Eldar9x is offline
Eldar9x
MCTS
Аватар для Eldar9x
Oracle
MCBMSS
 
1,064 / 166 (8) ++++++
Регистрация: 29.09.2006
Адрес: Казань
Цитата:
В итоге чтение ключа "Devices" все равно приведет к обращению к ветке реестра USR:Software\Microsoft\Windows NT\CurrentVersion\Devices
"А если нет разницы, ..."

зы: вообще то разница есть. С использованием getprofilestring, мы получаем большую универсальность. Не надо задумываться о том, в какую ветку реестра надо лезть.

Последний раз редактировалось Eldar9x; 25.02.2009 в 10:21.
Старый 25.02.2009, 10:10   #15  
KingPeas is offline
KingPeas
Участник
Аватар для KingPeas
 
163 / 35 (2) +++
Регистрация: 09.01.2007
Адрес: Россия, Новосибирск
Цитата:
Сообщение от petergunn Посмотреть сообщение
imho, использование GetProfileString не лучшее решение, т.к. эта функция в API присутсвует только для обратной совместимости с 16-bit приложениями.
И какова же тогда альтернатива?
Только я обрадовался что мне уже все подсказали)))
__________________
Хочу IQ как ICQ, ну или хотя бы ICQ как IQ.
Теги
excel, принтер

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Исследование скорости экспорта данных из Axapta в Excel (коллективный эксперимент) Gustav DAX: База знаний и проекты 79 13.02.2014 13:18
gl00mie: Read Excel table via ADO Blog bot DAX Blogs 2 09.04.2010 08:32
[Excel] - Несколько версий Excel на машине клиента Андре DAX: Программирование 11 07.08.2007 13:45
Вызов Item() для коллекций Excel Владимир Максимов DAX: Программирование 15 17.08.2006 19:47
Аксапта и Excel Swetik DAX: Программирование 3 01.03.2004 10:12

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 15:44.