当然Win環境の技術なのでプラットフォームはWin32に限定されます。PerlからOLE使用する事でによってExcelの表計算機能を使用する事や,Wordの文章機能を使用する,Outlookからメールを送信する、などといったマイクロソフト製品の機能を非常に簡単にPerlから使用する事が出来ます。
PerlからOLEを使用するには
Win32::OLEモジュール を使用します、これはモジュールはデフォルトで Perlのインストール時にインストールされるモジュールなので別途インストールなどは不要だと思います。
※たくさん出てくる用語についてExcel97のヘルプにあった説明を記述しておきます。
| オブジェクト |
ワークシート、セル、グラフ、フォーム、レポートなど、アプリケーションの要素を表します。 |
| コレクション |
中に複数オブジェクトを含むオブジェクトです。たとえば、Microsoft Excel では、Workbooks コレクションは開いているすべての Workbook オブジェクトを含みます。 |
| プロパティ |
サイズ、色、画面の位置などオブジェクトの特徴や、使用可能または表示/非表示などの動作を定義する属性です。オブジェクトの特徴を変更するには、そのプロパティ値を変更します。 |
| メソッド |
特定のオブジェクトに属するプロシージャ |
|
モジュールの使用は以下のような手順になります。
1. モジュールの輸入
2. アプリケーションオブジェクトの取得
3. 取得したオブジェクトに対する操作
モジュールの輸入
use strict;
use Win32::OLE qw(in with);
use Win32::OLE::Const 'Microsoft Excel';
モジュールを使用するには perlの
use関数を使用します。 この例では Excelを使用していますが、[ Microsoft Excel ] の記述を [ Microsoft Word ] とする事によって Wordを使用する事も可能です。
アプリケーションオブジェクトの取得
my $Excel = Win32::OLE->GetActiveObject('Excel.Application')
|| Win32::OLE->new('Excel.Application', 'Quit');
[ GetActiveObject ]
GetActiveObjectは引数で指定したオブジェクトが現在起動されていればそのインスタンスを返します。起動されていなければ偽となる値を返します。
[ new ]
newは引数で指定したオブジェクトを新たに起動してそのインスタンスを返します。起動に失敗すれば偽となる値を返します。
取得したオブジェクトに対する操作
VBAではオブジェクトに対してメソッドを実行する、オブジェクトの持っている属性(プロパティ)を変更する、という記述方法になります。VBAの記述をPerlで使用する時は次のように変換します。
[ メソッドを呼び出す場合 ]
先ずVBAでプロパティを変更する際の記述を見て下さい。
Application.ActiveWorkbook.ActiveSheet.Range("B1").Select
このVBAの記述をPerlで使用するには次のように変換して記述します。ここで使用している変数 $Excelにはアプリケーションオブジェクトの取得で戻り値として取得した値を格納します。
$Excel->ActiveWorkbook->ActiveSheet->Range("B1")->Select;
$Excel->ActiveWorkbook->ActiveSheet->Range("B1") ここでまでの記述がオブジェクトを指定する部分です。そのオブジェクトに対して
で記述してある
Selectメソッドを実行しているという記述になります。
[ 属性 ( プロパティ ) を変更する場合 ]
このサンプルは現在アクティブなシートのセル [ B1 ] の値を [ OLE Sample ] に変更します。
Application.ActiveWorkbook.ActiveSheet.Range("B1").Value = "OLE Sample"
Perlでは次のような記述になります。
$Excel->ActiveWorkbook->ActiveSheet->Range("B1")->{Value} = "OLE Sample" ;
オブジェクトの記述は前回と同じです。ここで指定したオブジェクトの属性(プロパティ)である Valueを変更するという記述です。このプロパティはオブジェクトの内容になります、このオブジェクトはセルを表わしていますのでセルの内容を示します。
PerlからExcelを操作してみます。 多少 Excel VBAの知識もいるかも知れませんが先ずは次のコードを眺めて見て下さい。
ブックを作成する
新規でファイルを作成するにはワークブックをコレクションに追加しそのワークブックを SaveAsメソッドで保存する事で行います。このメソッドで指定されたファイル名で保存されます、指定は絶対パスで行いますが省略するとカレントディレクトリに保存されます。
use strict;
use Win32::OLE qw(in with);
use Win32::OLE::Const 'Microsoft Excel';
my $Excel = Win32::OLE->GetActiveObject('Excel.Application')
|| Win32::OLE->new('Excel.Application', 'Quit');
my $Book = $Excel->Workbooks->add() ;
$Book->SaveAs("C:\\Sample.xls");
$Book->Close() ;
$Excel->quit() ;
1. 先ずExcelのオブジェクトを取得します。ここではExcelが既に起動されていればそのオブジェクトを取得し、起動されていなければnewによって新規でExcelオブジェクトを作成して取得します。
my $Excel = Win32::OLE->GetActiveObject('Excel.Application')
|| Win32::OLE->new('Excel.Application', 'Quit');
2. Workbooksコレクションにaddメソッドで新規のワークブックを追加します。又このメソッドは成功時に追加したワークブックオブジェクトを戻り値として返しますので変数$Bookでワークブックオブジェクトを取得しています。
my $Book = $Excel->Workbooks->add() ;
3. Aで取得したワークブックオブジェクトのメソッドSaveAsでファイルを保存します。引数で保存するファイル名を指定しています。
$Book->SaveAs("C:\\Sample.xls");
4. ワークブックを閉じます。
$Book->Close() ;
5. Excelアプリケーションを終了します。
$Excel->quit() ;
このサンプルではファイルの存在確認、エラーとラップなどは行っていませんので既に対象ファイルが存在する、既にExcelが開いていて他のファイルに変更を加えてあるなどと言った時にはメッセージボックスが表示されると思います。このメッセージボックスの
回答によっては例外が発生します。
具体的に、すでにファイル"C:\Sample.xls"が存在している状態でこのスクリプトを起動しメッセージボックスで上書きを行わなかった時に、私の環境では次のようなメッセージが表示されました。
Win32::OLE(0.1101) error 0x80020009: "例外が発生しました。
in METHOD/PROPERTYGET "SaveAs" at excel.pl line 14
ブックを全て閉じる
前回使用した Closeメソッドで指定したブックを閉じることが出来ますが、コレクションに含まれる全てのブックを閉じる時は Workbooks コレクションで Closeメソッドを呼び出しても同じ結果が得られます。
use strict;
use Win32::OLE qw(in with);
use Win32::OLE::Const 'Microsoft Excel';
my $Excel = Win32::OLE->GetActiveObject('Excel.Application')
|| die "Excelが起動していません";
$Excel->{DisplayAlerts} = 'False';
$Excel->Workbooks->close() ;
1. Excelオブジェクトのプロパティ[
DisplayAlerts ] の値を[
False ] にする事によって Excelの警告メッセージが表示されなくなります。このサンプルでは更新されているファイルも無関係に全て警告メッセージを表示させずに終了します。
$Excel->{DisplayAlerts} = 'False';
2. Workbooksコレクションで closeメソッドを実行すると全てのブックを終了します。
$Excel->Workbooks->close() ;
セルの内容を取り出す
セルのデータを取得するなど、セルに対して操作する時はセルを表わすRangeオブジェクトを使用します。Rangeオブジェクトは1 つのセルまたはセル範囲を表します。 Range("A1")とすると"A1"のセルに対して処理を行いRange("A1:C1")とすると"A1:C1"の範囲に対して処理を行います。
use strict;
use Win32::OLE qw(in with);
use Win32::OLE::Const 'Microsoft Excel';
my $Excel = Win32::OLE->GetActiveObject('Excel.Application')
|| Win32::OLE->new('Excel.Application', 'Quit');
my $Book = $Excel->Workbooks->Open("C:\\Sample.xls");
my $Sheet = $Book->Worksheets("Sheet1") ;
my $Range = $Sheet->Range("A1");
my $Area = $Range->{'Address'} . ":" . $Range->End(xlDown)->{'Address'};
my $array = $Sheet->Range("$Area")->{'Value'};
$Book->Close();
open( OUT,">C:\\Sample.txt") ;
foreach my $ref_array (@$array) {
foreach my $item (@$ref_array) {
print OUT "$item\n";
}
}
close(OUT);
1. ブックを開きます。前回の "Add" と同様にこのメソッドもワークブックオブジェクトを返します。
my $Book = $Excel->Workbooks->Open("C:\\Sample.xls");
2. A列のデータが存在する範囲の文字列を作成します。一つもデータが無ければ A列の先頭から最後までが対象となります。
my $Area = $Range->{'Address'} . ":" . $Range->End(xlDown)->{'Address'};
3. Aで作成した範囲から配列のリファレンスへデータを取得します。
my $array = $Sheet->Range("$Area")->{'Value'};
4. リファレンスのデータ全てを出力します。
foreach my $ref_array (@$array)〜foreach my $item (@$ref_array)
このサンプルも前回同様、ファイルの存在確認、エラーとラップなどは行っていません。
マクロを起動する
マクロを起動する時は
Excelクラスの runメソッドを呼び出します。 呼ばれるマクロはファイル名を指定していなければ選択されているブックに含まれるマクロになります。下で紹介している 3つ目の記述をすれば第二引数以降でマクロに引数を与える事が出来ます。
1. macro1という名前のマクロを実行します。
$Excel->Run("macro1");
2. [ MYCUSTOM.xls ] というブックに含まれる [ My_Func_Sum ] という名称のマクロを実行します。
$Excel->Run("MYCUSTOM.xls!My_Func_Sum") ;
3. 2 のマクロを二つの引数を渡して起動します。
$Excel->Run("MYCUSTOM.xls!My_Func_Sum", 1, 5) ;