use strict; use sigtrap qw(die INT); use Win32::OLE qw(in EVENTS); use Win32::OLE::Variant; $| = 1; # Without this, you end up registering the same event multiple times... # However, check the docs, as there is a performance penalty... Win32::OLE->Option(_Unique => 1); # Excel 10 "Dispatch" interfaces for Win32::OLE->WithEvents # Application: AppEvents # Sheets: DocEvents # Charts: ChartEvents # Workbooks: WorkbookEvents # OLE: OLEObjectEvents sub kill_excel { my $self = shift; $self->Quit; } END { my $Count = Win32::OLE->EnumAllObjects(sub { my $Object = shift; my $Class = Win32::OLE->QueryObjectType($Object); printf "# Object=%s Class=%s\n", $Object, $Class; }); print $Count,$/; } my $xl_app = Win32::OLE->new('Excel.Application', \&kill_excel); $xl_app->{Visible} = 1; my %wkb; my %sheets; sub get_ole_type { return Win32::OLE->QueryObjectType(shift); } sub app_event_handler { my ($obj, $event, @args) = @_; #print "app_event_handler: ", get_ole_type($obj), " ($obj->{Name}) : Event: $event",$/; my $new_item = $args[0]; if ($event eq'NewWorkbook'|| $event eq 'WorkbookActivate' ){ print "app_event_handler: ", get_ole_type($obj), " ($obj->{Name}) : Event: <$event>",$/; print $new_item->{BuiltinDocumentProperties}->{"Creation Date"}; print $new_item, ":",join("<->", keys %wkb), $/; unless ($wkb{$new_item}){ my $w = $new_item; print "Registering event handler for Workbook: $w->{Name}",$/; Win32::OLE->WithEvents($w, \&wb_event_handler, 'WorkbookEvents'); $wkb{$w} = $new_item; for my $s (in $w->Worksheets()) { $sheets{$s} = $s unless $sheets{$s}; print "Registering event handler for sheet $s->{Name} in book $s->{Parent}->{Name}",$/; Win32::OLE->WithEvents($s, \&sheet_event_handler, 'DocEvents'); } } } } Win32::OLE->WithEvents($xl_app, \&app_event_handler, 'AppEvents'); sub sheet_event_handler { my ($obj, $event, @args) = @_; print "sheet_event_handler: ",get_ole_type($obj), " ($obj->{Name}) : Event: <$event>",$/; if ($event eq 'SelectionChange' || $event eq 'Change') { my $range = $args[0]; print "$event received with " . get_ole_type($range) . " as argument",$/; print <{Columns}->{Count} column(s) and $range->{Rows}->{Count} row(s) It spans cell(s) $range->{Address} EOF } if ($event eq 'Change') { for my $cell ( in $args[0]->{Cells}) { print "Cell $cell->{Address} contains: $cell->{Value}",$/; } } } sub wb_event_handler { my ($obj, $event, @args) = @_; print "wb_event_handler: ",get_ole_type($obj), " ($obj->{Name}) : Event: <$event>",$/; } while (1) { $xl_app->SpinMessageLoop(); }