Базы данныхИнтернетКомпьютерыОперационные системыПрограммированиеСетиСвязьРазное
Поиск по сайту:
Подпишись на рассылку:

Назад в раздел

Работа с OLE Automation из PERL'а

Работа с OLE Automation из PERL'а Чак Богорад Работа с OLE Automation из PERL'а

Эта статья предназначена для тех, кто уже умеет сносно программировать на PERL, и хочет получить навыки работы с OLE Automation. В приводимых примерах использовался так называемый PERL-GS, который можно взять уже собранным, или собрать из исходных текстов на http://www.perl.com/CPAN/ (не путать с ActiveState PERL, доступным на http://www.activestate.com). Для работы с OLE Automation используется модуль Win32::OLE, который входит в библиотеку libwin32, также доступную с CPAN.

Модуль Win32::OLE (как и большинство других модулей) использует объектную модель. В PERL она организована очень просто: объект - всего лишь ссылка на HASH, в котором могут быть данные, ссылки на данные или ссылки на процедуры. Вызов "метода" - всего лишь разименование ссылки на HASH, еще одно разименование ссылки на процедуру и вызов этой процедуры. Подробнее об этом и массе других интересных вещей можно прочитать в книжке "Advanced PERL programming", которую написал Sriram Srinivasan. Купить ее можно здесь: http://www.amazon.com/exec/obidos/ASIN/1565922204/002-9864635-4316215 или в некоторых московских книжных магазинах (там, правда, она стоит чуть дороже).

Кратко опишу идеи OLE Automation, как я его понимаю. Сразу хочу предупредить - это может не иметь почти ничего общего с идеей его создателей. Итак, OLE Automation - это единый интуитивно понятный интерфейс, построенный по образу и подобию интерфейса всех windows-программ. Интерфейс объектный, то есть существуют объекты, их атрибуты и методы. Работая с ним, мы фактически имитируем работу с программой через её меню. Это гораздо удобнее, чем изучать для каждой программы ее собственный API. Так, показ WEB-страницы в MS IE и удаление старого письма из папки MS Outlook - одинаково примитивные и похожие операции.

Теперь к первому примеру. Это пример из жизни, задача состояла в том, чтобы преобразовать очень много (несколько сотен) документов из MS RTF в обычные текстовые файлы. Сразу замечу, что использовать самодельные преобразователи было нельзя, так как RTF - формат плохо документированный и непостоянный, поэтому едиственный надежный способ - использовать MS Word. Сначала рассмотрим, как эта задача решается при помощи MS Word. Мы загружаем файл ( File -> Open), затем сохраняем его как текстовый (File -> SaveAs -> DOS Text). Точно такие же действия производятся при помощи OLE Automation.

 

#!perl -w # Всегда используем 'use strict' и параметр '-w' , чтобы избежать ошибок и # облегчить оптимизацию. use strict; # Модуль 'Win32::OLE' объявляет нужные объекты. use Win32::OLE; # Модуль 'Win32::OLE:Const' объявляет нужные константы. use Win32::OLE::Const 'Microsoft Word'; { # Локальные переменные для имен входного и выходного файлов. my ($file_in, $file_out); # Используем 't.rtf' в качестве имени файла, если не задано другое имя. $file_out = $file_in = $ARGV[0] ? $ARGV[0] : 't.rtf'; # Формируем имя выходного файла. $file_out =~ s/(.*.).*/$1txt/; # Создаем объект - 'программа Word'. # Если Word не был активен, он будет запущен. my $word = Win32::OLE->new('Word.Application', 'Quit'); # Создаем объект 'документ Word'. Обратите внимание - единственным # параметром 'методу' Open является ссылка на HASH. При открытии файла # можно указать разнообразные параметры. my $doc = $word->Documents->Open({ FileName => $file_in, ConfirmConversions => 0, ReadOnly => 1, AddToRecentFiles => 0, Format => wdOpenFormatAuto}); # Теперь сохраняем файл так DOS Text.Обратите внимание - единственным # параметром 'методу' SaveAs является ссылка на HASH. my $rc = $doc->SaveAs({ FileName => $file_out, FileFormat => wdFormatDOSTextLineBreaks, AddToRecentFiles => 0}); # Закрываем документ. $rc = $doc->Close; # Завершаем работу MS Word. $rc = $word->Quit; };

 

Следующий пример тоже жизненный - удаление дублированных писем из папок MS Outlook. Дело в том, что у меня дома отвратительная телефонная линия, связь все время рвется, и Outlook не успевает забрать все письма из POP3-ящика. И каждый раз начинает сначала. Таким образом, накапливается огромное количество одинаковых писем, и их удаление - задача неприятная.

Используем Perl + OLE Automation. Перебираем все письма в папке, используем дату/время получения письма как ключ в HASH. В качестве элемента HASH заносим строку, полученную путем склеивания полей from/to/date/size. Если такая запись уже есть, удаляем текущее письмо. Аналогично для всех остальных папок. У меня все mail-list'ы складываются в подпапки папки 'Листы разные'.

 

#!perl -w # Всегда используем 'use strict' и параметр '-w' , чтобы избежать ошибок и # облегчить оптимизацию. use strict; # Используем модуль национальной поддержки. use locale; # Модуль 'Win32::OLE' объявляет нужные объекты. use Win32::OLE; # Модуль 'Win32::OLE:Const' объявляет нужные константы. use Win32::OLE::Const 'Microsoft Outlook'; { #main # Сохраняем текущую кодовую старницу. my $cp = `chcp`; # Выделяем число из 'Active code page: 866' chomp($cp); $cp =~ s/.*?(d+).*/$1/; # Временно устанавливаем Windows CP. `chcp 1251`; # Создаем объект 'программа Outlook'. my $olApp = Win32::OLE->new('Outlook.Application'); # Получаем handle(MAPI). my $nameSpace = $olApp->GetNameSpace('MAPI'); # Получаем handle папки 'Personal Folders'. ВНИМАНИЕ: в русском Outlook'е # она называется 'Личные папки'. my $persFolder = $nameSpace->Folders('Personal Folders'); # Получаем handle папки 'Листы разные'. my $listsFolder = $persFolder->Folders('Листы разные'); # Получаем handles всех ее подпапок. # Обратите внимание, что 'метод' 'Folders' # возвращает scalar, а не list! my $listFolders = $listsFolder->Folders(); # Перебираем сообщения в каждой подпапке. my $curFolder; # Чтобы получить список всех handles # всех подпапок используется функция 'in'. foreach $curFolder (in $listFolders) { # Выводим имя обрабатываемой папки print $curFolder->Name(), qq(n); # Заводим HASH, где будут храниться ключи. my %dupes; # Перебираем все письма в подпапке. 'Items' возвращает scalar. my $curItems = $curFolder->Items(); my $curItem; # Снова используем функцию 'in' для получения list'а. foreach $curItem (in $curItems) { # Берем время прихода письма. my $msgTime = $curItem->ReceivedTime(); # Склеиваем остальные поля. my $msgID = $curItem->SentOnBehalfOfName() . $curItem->To() . $curItem->SentOn() . $curItem->Size(); # Проверяем, встречалось ли уже такое письмо. if (defined($dupes{$msgTime}) and ($dupes{$msgTime} eq $msgID)) { # Если встречалось - стираем текущее письмо. $curItem->Delete(); print qq(Deleted $msgIDn); } else { # В противном случае заполняем HASH. $dupes{$msgTime} = $msgID; }; }; }; # foreach print qq(Quitting!n); # Здесь можно выйти из MS Outlook. # $olApp->Quit(); # Восстанавливаем исходную CODEPAGE. system("chcp $cp"); exit(0); } #main

 

Еще одной чрезвычайно интересной задачей является написание скрипта, который бы посылал напоминания о грядущих событиях на пейджер. Со временем и такой несомненно появится.

В заключение хочу обратить внимание на источники информации о структуре объектов OLE Automation в MS Office. В принципе, все необходимое есть в HELP for Visual basic. Кое-что есть в help-файлах, лежащих в папке MOREHELP на CD с MS Office. В Internet тоже есть места с информацией об объектах OLE Automation:



  • Главная
  • Новости
  • Новинки
  • Скрипты
  • Форум
  • Ссылки
  • О сайте




  • Emanual.ru – это сайт, посвящённый всем значимым событиям в IT-индустрии: новейшие разработки, уникальные методы и горячие новости! Тонны информации, полезной как для обычных пользователей, так и для самых продвинутых программистов! Интересные обсуждения на актуальные темы и огромная аудитория, которая может быть интересна широкому кругу рекламодателей. У нас вы узнаете всё о компьютерах, базах данных, операционных системах, сетях, инфраструктурах, связях и программированию на популярных языках!
     Copyright © 2001-2024
    Реклама на сайте