19.18 OLE AutomationThe Win32::OLE modules give Perl support for OLE automation. OLE automation is a Microsoft technology based on COM that allows objects created by another application to be used and manipulated by a program through a common interface. The application (or DLL) that implements the automation interface is called the automation server . The application that creates and uses the interface is called the automation controller or automation client . Many popular applications expose their objects through automation. Microsoft Word, Excel, and other Office applications can be used as automation servers. Automation is widely used by Active Server Pages (ASP) and CGI scripts to access data repositories, perhaps via ActiveX Data Objects (ADO). You can even use automation to control many development environments and editors. In order to create an automation object, the server needs to be registered on the system. This is typically done by the server's installation program, but can be done manually using a utility like regsvr32.exe . This involves adding entries to the system registry to tell COM how to find the component, what types of interfaces it provides, what type of server it is, etc. You should be able to find the object model, available methods and properties of the interface in the documentation provided by the application. This object model can be used via Perl's object syntax to create and control objects in your programs. Four modules provide automation functionality to Perl:
There are a few limitations to Win32::OLE to note. There is currently no
support for OCXs or OLE events (notifications generated by the
automation server). Win32::OLE implements the 19.18.1 Creating ObjectsAutomation objects are represented in Perl as instances of Win32::OLE objects. The module provides three constructors for creating objects from a registered automation server. 19.18.2 Automation Methods and PropertiesOnce you have created an automation object, you can use its methods or adjust its properties as you require. Automation methods are implemented as you'd expect with the Perl object syntax: Automation methods can often take a number of optional parameters. You can pass$obj->some_method(args);
undef
for any unwanted parameters in the arguments
list. For example, you can save a WorkBook in Excel with
SaveAs
.
Additional settings allow you to add the WorkBook to the MRU list and
create a backup copy:
For simplification, you can also use just the named parameters you want to set by passing a reference to a hash containing them. You can do this right in the argument list by creating an anonymous hash reference with$xl->WorkBooks(1)->SaveAs($f, undef, undef, undef, undef, 1, undef, undef, 1);
{}
. The previous example can therefore be
written like this:
Properties of automation objects are accessed via hash reference notation on the object. For example:$xl->WorkBooks(1)->SaveAs($f, {AddtoMru => 1, CreateBackup => 1}); Be aware that properties may not be writable (or even readable). Many automation objects have read-only properties and will generate an exception if you try to write to them. You'll need to consult the documentation for the object to find out which properties you can safely set.$val = $obj->{"property"}; # get a property value $obj->{"property"} = $val; # set a property value
You can enumerate the properties of an automation object using the normal
methods for enumerating hashes, which are $xl = Win32::OLE->new('Excel.Application', 'Quit'); while( ($key,$value) = each %$xl ) { print "$key=$value\n"; } 19.18.2.1 Win32::OLE methodsWin32::OLE defines a couple of its own methods for dealing with the automation interface. These are not automation-defined methods, although they look the same. If a given method is not defined in Win32::OLE, the method call is dispatched to the automation object. If the method doesn't exist there, you will get an OLE error. The following methods are defined by Win32::OLE: 19.18.2.2 Win32::OLE functionsThe following functions are defined by Win32::OLE. They are not exported by default. 19.18.2.3 Win32::OLE class variablesThe Win32::OLE module defines certain class variables that set default behavior for automation usage.
19.18.3 Win32::OLE::EnumThe Win32::OLE::Enum module provides special support for collections. Collections are special automation data types that contain an array of objects or data. A collection supports enumeration - you can iterate through each item through a standard interface.
Collection objects should always provide a
Collection objects also support a standard COM interface (IEnumVARIANT)
that allows you to enumerate each
item in a collection. It defines methods that let you advance the iteration to the next item,
skip a given item, restart the enumeration, and create a new copy of the iterator.
While all servers are supposed to provide this interface, some servers don't
implement all of the methods (often
Win32::OLE::Enum defines these methods for enumerating collections.
The collection object should provide the $cnt = $coll->Count(); if( $cnt) { $obj = $coll->Item(0); $obj->do_something(); }
Count
will tell you how many items are in the collection,
and
Item
will return the desired item as a Win32::OLE object.
For the enumeration methods, you need to create an enumeration object for the collection object: Now you can use the enumeration methods on the object.$coll = $obj->some_coll(); $enum = Win32::OLE::Enum->new($coll); 19.18.4 Win32::OLE::VariantAll automation data has to be coerced into a special type called a Variant. Most of the time, you don't need to worry about explicit type coercion. You just provide your scalar data and the magic of automation takes care of the rest of it. How- ever, there are cases when you want to control the exact type of data you're send- ing to the automation server. The Win32::OLE::Variant module provides access to the Variant data type and lets you control exactly how the data is represented. A Variant is an OLE data structure that contains a type field and a data field. The flags are implemented in Perl (as are many constants) as subroutines that return an integer value. The table below lists the Variant type flags, along with a brief description of each.
To convert data to a specific variant type, you create a variant
object with either the For example, to force a string to be interpreted as a date, create a variant object and set it to the$vnt = Win32::OLE::Variant->new(type, data); $vnt = Variant(type, data);
VT_DATE
type:
$dt = Variant(VT_DATE, "August 24, 1970"); # create an explicit data type $sheet->Cells(1,1)->{Value} = $dt; # set it to a spreadsheet cell 19.18.4.1 Win32::OLE::Variant methodsThe following methods are defined by Win32::OLE::Variant for working with Variant data types: 19.18.5 Win32::OLE::Const
While browsing through the documentation for an automation object, you may
have come across references to constant values. For example, if you're trying to
save an Excel workbook to a different file format, you need to provide a file for-
mat constant. Since the server documentation typically provides symbolic con-
stants (e.g., You can either import the constants directly into your namespace as subs that return the constant value, or you can have them returned as a hash reference with the constant name as the key and its value as the value. Here's an example of the former: which produces something like:use Win32::OLE::Const ("Microsoft Excel"); print "xlExcel5 = ", xlExcel5, "\n"; Here's an example using thexlExcel5 = 39
Load
method to return a hash reference populated
with the constants and their values (this produces the same output as the previ-
ous example, of course):
Notice that, in both cases, we're supplying a regular expression for the name of the type library from which we want to import.use Win32::OLE::Const; my $constants = Win32::OLE::Const->Load("Microsoft Excel"); print "xlExcel5 = $constants->{xlExcel5}\n";
Win32::OLE::Const
searches the
registry for matching type libraries and loads the one with the highest version
number (you can override this by supplying the version you want). You can also
specify the language you'd like. The parameters (for either
Load
or
Win32::OLE::Const
) are the typelib regular expression, the major version number, the minor version number, and the locale (LCID).
You can also provide the Usinguse Win32::OLE; use Win32::OLE::Const; # create an Excel application object my $xl = Win32::OLE->new('Excel.Application', 'Quit') || die "Can't create Excel: ", Win32::OLE->LastError; # import the constants from it my $constants = Win32::OLE::Const->Load($xl);
Load
(to get a hash reference for the constants) may be preferable to
importing all of the constants into your namespace. Some automation servers pro-
vide a large number of constants (the current version of Excel has some 900+), so
importing them into your namespace can clutter things considerably.
| ||||||||||||||||||||||||||||||||||||
|