home *** CD-ROM | disk | FTP | other *** search
- <?xml version="1.0"?>
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/transitional.dtd">
- <html xmlns="http://www.w3.org/TR/xhtml1">
- <head>
- <title>perlwin32faq12 - Using OLE with Perl</title>
- <link rev="made" href="mailto:hmn@datagraf.dk" />
- <meta name="GENERATOR" charset="iso-8859-1" />
- <link rel="STYLESHEET" href="../win32prk.css" type="text/css"
- media="screen" />
- </head>
-
- <body bgcolor="#ffffff">
- <!-- beginning of leaf header-->
-
- <table width="100%">
- <tr>
- <td bgcolor="000000" width="70" height="31"><a href=
- "http://www.activestate.com/"><img src="ASbutton.gif" alt=
- "ActiveState Home Page" border="0" width="68" height=
- "30" /></a></td>
-
- <td width="10" bgcolor="#ffffff"> </td>
-
- <td valign="middle" bgcolor="#cc0066"><font face=
- "sans-serif" size="+1" color="#ff99cc">
- Win32 FAQ</font></td>
- </tr>
- </table>
- <!-- end of leaf content--><!-- INDEX BEGIN -->
-
- <ul>
- <li><a href="#NAME">NAME</a></li>
-
- <li>
- <a href="#DESCRIPTION">DESCRIPTION</a>
-
- <ul>
- <li><a href="#use_ole">Can I use OLE with Perl?</a></li>
-
- <li><a href="#changed_by_4xx">What has changed with OLE
- since build 3xx</a></li>
-
- <li><a href="#print_word">How do I print a Microsoft Word
- document?</a></li>
-
- <li><a href="#extract_cells">How do I extract a series of
- cells from Microsoft Excel?</a></li>
-
- <li><a href="#make_chart">How do I make a chart in
- Microsoft Excel?</a></li>
-
- <li><a href="#save_chart">How do I save a chart from
- Microsoft Excel as GIF/JPEG/PNG?</a></li>
-
- <li><a href="#run_macro">How do I run a macro in
- Microsoft Excel?</a></li>
-
- <li><a href="#set_name_cell">How do I set the name of a
- cell in Microsoft Excel?</a></li>
-
- <li><a href="#create_new_folder">How do I create a new
- folder in Outlook?</a></li>
-
- <li><a href="#use_ado">How do I use ADO?</a></li>
-
- <li><a href="#use_notes">How do I use Lotus
- Notes?</a></li>
-
- <li><a href="#set_printer">How do I set the
- printer?</a></li>
-
- <li><a href="#convert_vba">How do I convert a VBA macro
- to Perl?</a></li>
-
- <li><a href="#find_docs">Where do I find documentation
- for the object models?</a></li>
-
- <li><a href="#find_constants">OK, but can I at least find
- the constants that are exported from
- Win32::OLE::Const?</a></li>
-
- <li><a href="#errors">Why doesn't $! get set with the
- error message I am generating?</a></li>
-
- <li><a href="#odbc_ole">Why do I get an error when using
- ODBC and OLE?</a></li>
-
- <li><a href="#strict">Why doesn't it work - even after
- all this?</a></li>
- </ul>
- </li>
-
- <li><a href="#AUTHOR_AND_COPYRIGHT">AUTHOR AND
- COPYRIGHT</a></li>
- </ul>
- <!-- INDEX END --><br />
- <hr />
- <br />
- <br />
-
-
- <h1><a name="NAME">NAME</a></h1>
-
- <p>perlwin32faq12 - Using OLE with Perl</p>
- <br />
- <hr />
- <br />
- <br />
-
-
- <h1><a name="DESCRIPTION">DESCRIPTION</a></h1>
-
- <p>How to use OLE automation with Perl - through the Win32::OLE
- module</p>
- <a name="use_ole"></a>
- <hr />
-
- <h1>Can I use OLE with Perl?</h1>
-
- <p>Yes - otherwise this FAQ wouldn't have been a separate FAQ,
- but just part of perlwin32faq4 ;-)</p>
-
- <p>If you want to use OLE with Perl you need the Win32::OLE
- module. And you need to read the documentation that comes with
- it.</p>
-
- <p><code>use Win32::OLE</code> doesn't export any variables and
- functions to the main namespace, so if you want easy access to
- the <code>in</code> and <code>with</code> functions you should
- load the module with</p>
-
- <blockquote>
- <p><code>use Win32::OLE qw(in with);</code></p>
- </blockquote>
- <a name="changed_by_4xx"></a>
- <hr />
-
- <h1>What has changed with OLE since build 3xx</h1>
-
- <p>A lot - Gurusamy Sarathy and then Jan Dubois redesigned the
- code and added a bundle of enhancements. Old scripts should run
- with little or no modifications. When writing new scripts there
- is no excuse for not using the new Win32::OLE module
- options.</p>
-
- <p>Look at the Win::OLE module documentation (under
- Incompatibilities) and in particular the <a href=
- "release.htm#Whats_Changed">'What's changed from 300 series
- builds'</a> in the release notes.</p>
- <a name="print_word"></a>
- <hr />
-
- <h1>How do I print a Microsoft Word document?</h1>
-
- <p>Use the method PrintOut on a document object, for
- example:</p>
-
- <blockquote>
- <p><code>use strict;<br />
- use Win32::OLE;<br />
- use Win32::OLE::Const 'Microsoft Word';<br />
- <br />
- my $Word = Win32::OLE->new('Word.Application',
- 'Quit');<br />
- # $Word->{'Visible'} =
- 1; # if
- you want to see what's going on<br />
- $Word->Documents->Open("C:\\DOCUMENTS\\test.doc")<br />
- || die("Unable to open document ",
- Win32::OLE->LastError());<br />
- $Word->ActiveDocument->PrintOut({<br />
- Background => 0,<br />
- Append =>
- 0,<br />
- Range =>
- wdPrintAllDocument,<br />
- Item =>
- wdPrintDocumentContent,<br />
- Copies =>
- 1,<br />
- PageType =>
- wdPrintAllPages,<br />
- });</code></p>
- </blockquote>
-
- <p>or simply</p>
-
- <blockquote>
- <p><code>$Word->ActiveDocument->PrintOut;</code></p>
- </blockquote>
- <a name="extract_cells"></a>
- <hr />
-
- <h1>How do I extract a series of cells from Microsoft
- Excel?</h1>
-
- <p>If you have a sheet object you can extract the values of a
- series of cells through $Sheet->Range->{'Value'}, for
- example:</p>
-
- <blockquote>
- <p><code>my $array =
- $Sheet->Range("A8:B9")->{'Value'};</code></p>
- </blockquote>
-
- <p>Now $array[0][0] contains the value of cell A8, $array[0][1]
- the value of cell B8, $array[1][0] the value of cell A9 and
- $array[1][1] the value of cell B9.</p>
-
- <p>What is returned is an two-dimensional array (OK, an array
- with references to arrays) that contains the values of the
- requested cells.</p>
-
- <p>A complete example is here:</p>
- <br />
-
- <blockquote>
- <code>use strict;<br />
- use Win32::OLE qw(in with);<br />
- use Win32::OLE::Const 'Microsoft Excel';<br />
- $Win32::OLE::Warn =
- 3; #
- die on errors...<br />
- my $Excel =
- Win32::OLE->GetActiveObject('Excel.Application')<br />
- ||
- Win32::OLE->new('Excel.Application', 'Quit'); #
- get already active Excel<br />
- #
- application or open new<br />
- my $Book =
- $Excel->Workbooks->Open("C:\\DOCUMENTS\\test.xls"); #
- open Excel file<br />
- my $Sheet =
- $Book->Worksheets(1); #
- select worksheet number 1<br />
- my $array =
- $Sheet->Range("A8:B9")->{'Value'}; #
- get the contents<br />
- $Book->Close;<br />
- foreach my $ref_array (@$array)
- { #
- loop through the array<br />
- #
- referenced by $array<br />
- foreach my $scalar (@$ref_array)
- {<br />
- print
- "$scalar\t";<br />
- }<br />
- print "\n";<br />
- }</code>
- </blockquote>
- <br />
- <br />
-
-
- <p>To retrieve the formatted value of a cell you should use the
- <code>{'Text'}</code> property instead of the <code>
- {'Value'}</code> property. This returns exactly what is being
- displayed on the screen though! If the column is not wide
- enough, you get a value of '######':</p>
-
- <blockquote>
- <p><code>my $array =
- $Sheet->Range("A8:B9")->{'Text'};</code></p>
- </blockquote>
- <a name="make_chart"></a>
- <hr />
-
- <h1>How do I make a chart in Microsoft Excel?</h1>
-
- <p>A good idea would be to record a macro in Microsoft Excel
- and then <a href="#convert_vba">convert it to Perl</a>. But
- here is a complete example:</p>
-
- <blockquote>
- <p><code>use strict;<br />
- use Win32::OLE;<br />
- use Win32::OLE::Const 'Microsoft Excel';<br />
- <br />
- my $Excel = Win32::OLE->new("Excel.Application");<br />
- $Excel->{Visible} = 1;<br />
- <br />
- my $Book = $Excel->Workbooks->Add;<br />
- my $Sheet = $Book->Worksheets(1);<br />
- my $Range = $Sheet->Range("A2:C7");<br />
- $Range->{Value} =<br />
- [['Delivered', 'En route', 'To be
- shipped'],<br />
- [504, 102, 86],<br />
- [670, 150, 174],<br />
- [891, 261, 201],<br />
- [1274, 471, 321],<br />
- [1563, 536, 241]];<br />
- <br />
- my $Chart = $Excel->Charts->Add;<br />
- $Chart->{ChartType} = xlAreaStacked;<br />
- $Chart->SetSourceData({Source => $Range, PlotBy =>
- xlColumns});<br />
- $Chart->{HasTitle} = 1;<br />
- $Chart->ChartTitle->{Text} = "Items delivered, en route
- and to be shipped";</code></p>
- </blockquote>
- <a name="save_chart"></a>
- <hr />
-
- <h1>How do I save a chart from Microsoft Excel as
- GIF/JPEG/PNG?</h1>
-
- <p>You can use the Export method of a chart. If you have a
- chartobject the code looks like this</p>
-
- <blockquote>
- <p><code>$ChartObj->Chart->Export({<br />
- FileName =>
- "$graphics_filename",<br />
- FilterName =>
- 'GIF',<br />
- Interactive =>
- 0});</code></p>
- </blockquote>
-
- <p>A complete example that opens an Excel workbook, loops
- through all the charts and saves them as GIFs and then closes
- the Excel workbook is here:</p>
-
- <blockquote>
- <p><code>use strict;<br />
- use Win32::OLE qw(in with);<br />
- use Win32::OLE::Const;<br />
- use Win32::OLE::Const 'Microsoft Excel';<br />
- $Win32::OLE::Warn =
- 3; # die on
- errors...<br />
- <br />
- my $filename = 'c:\\documents\\test.xls';<br />
- my $filter =
- 'GIF'; #
- can be GIF, JPG, JPEG or PNG<br />
- my $count = 0;<br />
- <br />
- my $Excel =
- Win32::OLE->GetActiveObject('Excel.Application')<br />
- ||
- Win32::OLE->new('Excel.Application', 'Quit'); #
- use the Excel application if it's open, otherwise open
- new<br />
- my $Book = $Excel->Workbooks->Open( $filename
- ); # open the file<br />
- foreach my $Sheet (in $Book->Sheets)
- { #
- loop through all sheets<br />
- foreach my $ChartObj (in
- $Sheet->ChartObjects) { # loop through all
- chartobjects in the sheet<br />
- my $savename
- = "$filename." . $count++ . ".$filter";<br />
- $ChartObj->Chart->Export({<br />
-
- FileName =>
- $savename,<br />
- FilterName =>
- $filter,<br />
- Interactive =>
- 0});<br />
- }<br />
- }<br />
- $Book->Close;</code></p>
- </blockquote>
- <a name="run_macro"></a>
- <hr />
-
- <h1>How do I run a macro in Microsoft Excel?</h1>
-
- <p>Macros in Microsoft Excel can be run by using the
- $Excel->Run method, for example:</p>
-
- <blockquote>
- <p><code>$Excel->Run("PrintPDFFile");</code></p>
- </blockquote>
-
- <p>In order to do this, you of course need to have a macro in
- Excel that's called 'PrintPDFFile'...</p>
- <a name="set_name_cell"></a>
- <hr />
-
- <h1>How do I set the name of a cell in Microsoft Excel?</h1>
-
- <p>Use the Names->Add method on a sheet, giving it a name
- and a range object to apply the name to, for example:</p>
-
- <blockquote>
- <p><code>$Sheet->Names->Add({Name => 'NetCost',
- RefersTo => $Sheet->Range('$B$10')});</code></p>
- </blockquote>
- <a name="create_new_folder"></a>
- <hr />
-
- <h1>How do I create a new folder in Outlook?</h1>
-
- <p>Again, an example :-)</p>
-
- <blockquote>
- <p><code>use strict;<br />
- use Win32::OLE;<br />
- use Win32::OLE::Const 'Microsoft Outlook';<br />
- <br />
- my $Outlook = Win32::OLE->new('Outlook.Application',
- 'Quit');<br />
- my $ol = Win32::OLE::Const->Load($Outlook);<br />
- <br />
- my $namespace = $Outlook->GetNamespace("MAPI");<br />
- my $Folder =
- $namespace->GetDefaultFolder(olFolderInbox);<br />
- my $NewFolder =
- $Folder->Folders->Add("Test1");</code></p>
- </blockquote>
- <a name="use_ado"></a>
- <hr />
-
- <h1>How do I use ADO?</h1>
-
- <p>In order to use ActiveX Data Objects (ADO) you can just</p>
-
- <blockquote>
- <p><code>use strict;<br />
- use Win32::OLE;<br />
- use Win32::OLE::Const 'Microsoft ActiveX Data Objects';<br />
- my $Conn = Win32::OLE->new('ADODB.Connection'); #
- creates a connection object<br />
- my $RS =
- Win32::OLE->new('ADODB.Recordset'); #
- creates a recordset object<br />
- $Conn->Open('DBname'); #
- opens the database connection<br />
- <br />
- my $Fields = ['Id', 'Name', 'Phone'];<br />
- my $Values = [1, 'Joe Doe', '555-1234'];<br />
- $RS->AddNew($Fields,
- $Values); #
- adds a record<br />
- <br />
- print "This didn't go well: ", Win32::OLE->LastError(),
- "\n";<br />
- if
- (Win32::OLE->LastError());<br />
- <br />
- $RS->Close;<br />
- $Conn->Close;</code></p>
- </blockquote>
-
- <p>To get further than this you should have a look at the ADO
- FAQ at <a href=
- "http://www.fastnetltd.ndirect.co.uk/Perl/perl-win32-database.html">
- http://www.fastnetltd.ndirect.co.uk/Perl/perl-win32-database.html</a>
- or Jan Dubois article in TPJ#10 (visit The Perl Journal at <a
- href="http://tpj.com/">http://tpj.com/</a>).</p>
- <a name="use_notes"></a>
- <hr />
-
- <h1>How do I use Lotus Notes?</h1>
-
- <p>Lotus Notes can be accessed through OLE, for example like
- this:</p>
-
- <blockquote>
- <p><code>use strict;<br />
- use Win32::OLE;<br />
- my $Notes = Win32::OLE->new('Notes.NotesSession')<br />
- or die "Cannot start Lotus Notes
- Session object.\n";<br />
- my ($Version) = ($Notes->{NotesVersion} =~
- /\s*(.*\S)\s*$/);<br />
- print "The current user is $Notes->{UserName}.\n";<br />
- print "Running Notes \"$Version\" on
- \"$Notes->{Platform}\".\n";<br />
- my $Database = $Notes->GetDatabase('', 'help4.nsf');<br />
- my $AllDocuments = $Database->AllDocuments;<br />
- my $Count = $AllDocuments->Count;<br />
- print "There are $Count documents in the database.\n";<br />
- for (my $Index = 1 ; $Index <= $Count ; ++$Index) {<br />
- my $Document =
- $AllDocuments->GetNthDocument($Index);<br />
- printf "$Index. %s\n",
- $Document->GetFirstItem('Subject')->{Text};<br />
- my $Values =
- $Document->GetItemValue('Index_Entries');<br />
- foreach my $Value (@$Values) {<br />
- print "
- Index: $Value\n";<br />
- }<br />
- last unless $Index < 5;<br />
- }</code></p>
- </blockquote>
-
- <p>You can access all objects that are accessible to
- LotusScript, and the LotusScript classes can be seen at <a
- href="http://www.lotus.com/products/lotusscript.nsf">
- http://www.lotus.com/products/lotusscript.nsf</a>. A good idea
- would also be to read Jan Dubois article in TPJ#10 (visit The
- Perl Journal at <a href="http://tpj.com/">
- http://tpj.com/</a>)</p>
- <a name="set_printer"></a>
- <hr />
-
- <h1>How do I set the printer in Word?</h1>
-
- <p>The active printer can be set and retrieved through the word
- application object with <code>$Word->{ActivePrinter} =
- $printername</code>.</p>
- <a name="convert_vba"></a>
- <hr />
-
- <h1>How do I convert a VBA macro to Perl?</h1>
-
- <p>If you record a macro in Microsoft Office, this can often be
- translated directly into Perl. In Visual Basic for Applications
- (VBA) the syntax is like this:</p>
-
- <blockquote>
- <p><code>object.method(argument).property = value</code></p>
- </blockquote>
-
- <p>In Perl this becomes</p>
-
- <blockquote>
- <p><code>object->method(argument)->{property} =
- value;</code></p>
- </blockquote>
-
- <p>So for example this code from VBA:</p>
-
- <blockquote>
- <p><code>ActiveChart.Axes(xlCategory, xlPrimary).CategoryType
- = xlCategoryScale</code></p>
- </blockquote>
-
- <p>becomes this in Perl:</p>
-
- <blockquote>
- <p><code>$Chart->Axes(xlCategory,
- xlPrimary)->{CategoryType} = xlCategoryScale;</code></p>
- </blockquote>
- <a name="find_docs"></a>
- <hr />
-
- <h1>Where do I find documentation for the object models?</h1>
-
- <p>The best way to learn about methods/properties would be
- through an OLE type browser if the documentation is
- unavailable.</p>
-
- <p>If you have Microsoft Excel or Microsoft Word available, go
- into the Visual Basic Editor (Alt+F11). Now you can open the
- object browser window (F2) and see what you find.</p>
-
- <p>There is also an OleView program (various names and
- versions) included in Microsoft Visual C++ / Microsoft Visual
- Studio if you don't have Office. Or you can download it from
- the Microsoft COM website ( <a href=
- "http://www.microsoft.com/com/">
- http://www.microsoft.com/com/</a>).</p>
-
- <p>But it is still possible that Notes doesn't reveal anything;
- objects are not required to provide type info support. For
- example Lotus Notes doesn't reveal nothing about it's internal
- constants, methods and properties; you have to look them up in
- the documentation.</p>
-
- <p>For Lotus Notes look at <a href=
- "http://www.lotus.com/products/lotusscript.nsf">
- http://www.lotus.com/products/lotusscript.nsf</a>.</p>
- <a name="find_constants"></a>
- <hr />
-
- <h1>OK, but can I at least find the constants that are exported
- from Win32::OLE::Const?</h1>
-
- <p>Yes, you can use the following code example to view all the
- constants - you really shouldn't need this, but if you want to
- know what's going on, it might help:</p>
-
- <blockquote>
- <p><code>use strict;<br />
- use Win32::OLE;<br />
- use Win32::OLE::Const;<br />
- <br />
- my $xl = Win32::OLE::Const->Load("Microsoft Excel");<br />
- printf "Excel type library contains %d constants:\n", scalar
- keys %$xl;<br />
- foreach my $Key (sort keys %$xl) {<br />
- print "$Key =
- $xl->{$Key}\n";<br />
- }</code></p>
- </blockquote>
-
- <p>Generally you should look at the documentation for
- Win32::OLE::Const.</p>
- <a name="errors"></a>
- <hr />
-
- <h1>Why doesn't $! get set with the error message I am
- generating?</h1>
-
- <p>Error messages from Win32::OLE doesn't go to the $!
- variable, but can be accessed as <code>
- Win32::OLE->LastError()</code></p>
- <a name="odbc_ole"></a>
- <hr />
-
- <h1>Why do I get an error when using ODBC and OLE?</h1>
-
- <p>For some reason you get an 'OleInitialize' error if you open
- an OLE application first and then open an ODBC connection to
- the Access ODBC driver. If you do it the other way around,
- there is no problem with this.</p>
-
- <p>It looks like the Access ODBC driver calls OleInitialize().
- This fails when Win32::OLE already initialized the COM
- subsystem as "apartment threaded".</p>
-
- <p>In order to remove the error either start the ODBC driver
- before the OLE application or, better yet, initialize the OLE
- system with <code>
- Win32::OLE->Initialize(Win32::OLE::COINIT_OLEINITIALIZE);</code></p>
- <a name="strict"></a>
- <hr />
-
- <h1>Why doesn't it work - even after all this?</h1>
-
- <p>Execute your scripts with <code>perl -w</code> and <code>use
- strict</code> - this catches most of your errors. Apart from
- this, read the documentation for Win32::OLE (a good start) and
- possibly the documentation for the object you are trying to
- use.</p>
-
- <p>In the case of Microsoft Office 97, make sure that you have
- at least updated to Service Release 1 - much of the OLE in
- Microsoft Office 97 is broken without this update.</p>
- <br />
- <hr />
-
- <h1><a name="AUTHOR_AND_COPYRIGHT">AUTHOR AND
- COPYRIGHT</a></h1>
-
- <p>This <font size="-1">FAQ</font> was compiled by Henning
- Michael Møller-Nielsen of RTO based on examples by many
- people, especially Jan Dubois. It is maintained by Henning
- Michael Møller-Nielsen, Philip Martin, Kevin Meltzer and
- Eric Smith at <a href="mailto:perlwin32faq@rto.dk">
- perlwin32faq@rto.dk</a>.</p>
-
- <p>This <font size="-1">FAQ</font> is in the public domain. If
- you use it, however, please ensure that you give credit to the
- original authors.</p>
-
- <p><!-- beginning of leaf footer--></p>
-
- <table width="100%">
- <tr>
- <td bgcolor="000000" width="70" height="31"><a href=
- "http://www.activestate.com/"><img src="ASbutton.gif" alt=
- "ActiveState Home Page" border="0" width="68" height=
- "30" /></a></td>
-
- <td width="10"> </td>
-
- <td valign="middle" bgcolor="#cc0066"><font face=
- "sans-serif" size="+1" color="#ff99cc">
- Win32 FAQ</font></td>
- </tr>
- </table>
- <!-- end of leaf footer-->
- </body>
- </html>
-
-