Excel/Word/Outlook-Automatisierung mit Perl und win32ole

Sehr mächtig, für einen produktiven Büroalltag eigentlich unverzichtbar, jedoch wenig dokumentiert: Batch-Verarbeitung von MS-Office mit Perl, hier am Beispiel einiger Code-Snippets als Anregung. Ist die grundlegende Syntax (auch des komplexen Ersetzungsbeispieles mit "anonymous hash" in Word unten) einmal verstanden, eröffnet die den MS-Office-Produkten integrierte Hilfe die gesamte API.

Voraussetzung: Perl-Umgebung unter Windows, z.B. Active-State-Perl


Excel

Typischer Header
use Win32::OLE qw (in with);
use Win32::OLE::Const ('Microsoft Excel');
use Win32::OLE::Variant;
use IO::Handle;
use File::Next;
use Cwd;
use Date::Calc qw(:all);
Initialisierung
$application = Win32::OLE->new('Excel.Application','Quit');
unless ($application){
  &abort("Excel-Objekt konnte nicht erstellt werden");
}
$book=$application->Workbooks->Add;
unless ($book){
  &abort("Konnte Ergebnisobjekt nicht anlegen");
}
Neues Tabellenblatt
$lastSheet=$book->Worksheets("Tabelle3");
$sheet=$book->Worksheets->Add;
$sheet->{'Name'}=$monthText;
$sheet->Move({'After' => $lastSheet});
$lastSheet=$sheet;
Werte eintragen und Formatieren
$sheet->Cells(4,5)->{'Value'}="Schulferien";
$sheet->Cells(4,5)->Font->{'Bold'}=1;
$sheet->Cells(4,5)->Font->{'StrikeThrough'}=1;
$sheet->Cells(4,5)->Interior->{'Pattern'}=xlPatternGray16;
Kommentar einfügen und automatische Spaltenanpassung
$commentHandle=$sheet->Cells(8,4)->AddComment("mein Senf dazu");

$shape=$commentHandle->{Shape};
$shape->{Width}=20;
$shape->{Height}=10;

$sheet->Columns("A:AZ")->AutoFit();
Pfeil zeichnen
$msoArrowheadTriangle = 2;
$shape=$sheet->Shapes->Addline(0,4,0,4);
$shape->Line->{'EndArrowheadStyle'}=$msoArrowheadTriangle;
Zellen mergen, ausrichten, färben
$sheet->Range("A1:A6")->{'MergeCells'}=1;
$sheet->Cells(7,2)->{'HorizontalAlignment'}=xlCenter;
$sheet->Range("B5:B13")->Interior->{'ColorIndex' }=$contrastColor;
Formeln
$sheet->Cells(4,4)->{'Formula'}="=ZÄHLENWENN("Januar!B3";\"Urlaub\")";
Gitter zeichnen
$sheet->Range("A1:A7")->Borders(xlEdgeLeft)->{'LineStyle'}=xlContinuous;
$sheet->Range("A1:A7")->Borders(xlEdgeLeft)->{'Weight'}=xlThin;
Blätter löschen
for($i=1;i<=3;$i++){
  $sheet=$book->Worksheets("Tabelle".$i);
  ($sheet) && $sheet->Delete;
}
Speichern und Beenden
$book->SaveAs("Heinz.xls");
$book->Close;
$application->Quit;
Beispiel-Fehlerroutine (OLE-Error)
sub abortOnOleError{
  my ($message)=shift;
  my $oleError=Win32::OLE->LastError();
  if($oleError){
    &abort("-------------------------------------\n".$message."\n".$oleError."\n-----------------------------");
  }
}

Outlook

Initialisierung
use Win32::OLE;
use Win32::OLE::Const 'Microsoft Outlook';
use Win32::OLE::Variant;
use IO::Handle;

$application = Win32::OLE->GetActiveObject('Outlook.Application');
unless ($application){
  $application = Win32::OLE->new('Outlook.Application', sub {$_[0]->Quit;});
  &printLog("Alloziere neues Outlook-Objekt");
  unless ($application){
    &abort("Outlook-Objekt konnte nicht gefunden und auch nicht angelegt werden");
  }
}
$nameSpace=$application->GetNameSpace('MAPI');
$mailboxName = 'Postfach - Breinlinger, Dr. Heinz';
Ordnersuche
$inbox=$nameSpace->GetDefaultFolder(olFolderInbox);

$outbox=&seekFolder($nameSpace,"Postausgang");
sub seekFolder{
  my $obj = shift;
  my $pattern = shift;
  my $i=0;
  for ($i = 1; $i <= $obj->Folders->Count; $i++) {
    if ( $obj->Folders->Item($i)->Name eq $pattern ) {
      return $obj->Folders->Item($i);
    }
  }
}
Mailsuche
$items=$inbox->Items;
$mail=$items->Find("[SenderName] <> 'Dr. Breinlinger'"); 
while($mail &&){
  $subject=$mail->Subject;
  if($subject =~ /SMTP:/i){
    ...
  }
  ...
  $mail=$items->FindNext; 
}
Weiterleitung
$forwardMail=$mail->Forward;
$oleError=Win32::OLE->LastError();
if($oleError){
 ...
}
$forwardMail->Body="Was ich schon immer mal sagen wollte ...";
$forwardMail->To="michelle.obama@whitehouse.com";
$forwardMail->Subject="Wo haben Sie das Kleid gekauft ?";
$forwardMail->Send;
Neue Mail
$mail=$application->CreateItem(olMailItem);
$mail->Recipients->Add("barack.obama@whitehouse.com");
$mail->{Subject}="Ich bin dann mal weg";
$mail->{Body}="Langer Sermon ...";
$mail->Send;
Verschieben
$outbox=&seekFolder($nameSpace,"Postausgang");
$mail->Move(&seekFolder($nameSpace,"Archiv"));
Beenden
$application->Quit;

Word

Initialisierung
use Win32::OLE qw (in with);
use Win32::OLE::Const ('Microsoft Word');
use Win32::OLE::Variant;
use IO::Handle;
use File::Next;
use Cwd;
use Date::Calc qw(:all);

$word=Win32::OLE->new('Word.Application','Quit');
$word->{'Visible'}=0;
$word->{'DisplayAlerts'}=0;
$document=$word->Documents->Open("Heinz.doc");
Suchen und Ersetzen
$content=$document->{'Content'};
$content->Find->Execute({
                          MatchCase => 0,
                          Replace => wdReplaceAll,
                          FindText => "Suchtext",
                          ReplaceWith => "Ersetzungstext" 
                       });
Beenden
$document->SaveAs("Heinz_neu.doc"); 
$document->Close();
$word->Quit;

Impressum und Datenschutzerklärung