Win32::OLE を使用して、Excel VBA の COM オブジェクトを使用するルーチンを Perl に移植しようとしています。主な理由は、VBA は配列反復で遅いため、多少速度が向上するためです。
次のコードは、VBA で正常に動作します。
Function LoadServerSignal(name As String, timeRange As FooCOMLib.timeRange) As FooCOMLib.SerieValues
Dim server as object
Dim signal As FooCOMLib.signal
Dim fooData As New FooCOMLib.SerieValues
Set server = New FooCOMLib.Recorder
fooData.initialize (0)
If server.SignalContents.FindSignalByName(name, signal) Then
Set fooData = server.LoadSignal(signal, timeRange)
End If
Set LoadServerSignal = fooData
End Function
要求されたシグナル名は、name文字列を介して渡されます。サーバーは名前を見つけ、FindSignalByNameオブジェクト メソッドを介して信号オブジェクトのデータを返します。
Win32::OLE ライブラリを使って同じことを Perl に移植してみました。単純なスカラー オブジェクトを取得または返す項目のほとんどは正常に動作します。しかし、$signalオブジェクトを返す同じコードは常に空を返します。
#!perl -w
use strict;
use Win32::OLE;
use Win32::OLE::Variant;
my $server = Win32::OLE->new('FooCOMLib.Recorder');
my $signal = Win32::OLE->new('FooCOMLib.signal');
my $timeRange = Win32::OLE->new('FooCOMLib.timeRange');
my $fooData = Win32::OLE->new('FooCOMLib.SerieValues');
my $name = "FooTran76";
$fooData->initialize(0);
$timerange->{StartTime} = 40909; # Jan 1, 2012
$timerange->{EndTime} = 40910; # Jan 2, 2012
$server->{SignalContents}->FindSignalByName($name,$signal) or die "Could not find $name\n";
$fooData= $server->LoadSignal($signal,$timeRange);
コードが実行され、最後から 2 行目で終了しません。しかし、 $signalオブジェクトを見るたびに、それは空です。正しく解釈されていることを確認したので、時間範囲と名前は正しいです。
さらに、次のように、Win32::OLE::Variant ライブラリを使用して、戻り値の型をより適切に強制しようとしました。
$server->{SignalContents}->FindSignalByName($name,Variant(VT_DISPATCH|VT_BYREF,$signal)) or die "Could not find $name\n";
しかし、これは役に立ちませんでした...どのように試しても、まだ空の$signalオブジェクトです。何か案は?