kevind0718 has asked for the wisdom of the Perl Monks concerning the following question:

Hello:
I am attempting to access Bloomberg, an ActiveX control (a fincial data source) via Perl. I can not figure out how to pass a variant array of strings to the above ActiveX control. Here is my PERL code.
use Win32::OLE;
use Win32::OLE::Variant;
$blpData = Win32::OLE->new('Bloomberg.Data.1') or
die "can NOT load the blpData" ; #print $blpData->Timeout . "\n";
$aSec = Variant(VT_BSTR, "IBM Equity");
@tmpArray = ("PX_Last");
$aFields = Variant(VT_ARRAY|VT_UI1, "PX_Last" );
$sDate = Variant(VT_DATE, "2007/07/01");
$eDate = Variant(VT_DATE, "2007/07/10");
@bbData = Variant(VT_EMPTY, undef);
@bbData = $blpData->BLPGetHistoricalData($aSec, $aFields, $sDate, $eDate);
print "Array Size: " , $#bbData . "\n";
foreach $bbData (@bbData) {
print $bbData
}
print "end" ;
Here the documentation on the BLPGetHistoricalData call
VARIANT BLPGetHistoricalData (VARIANT Security, VARIANT Fields,
VARIANT StartDate, VARIANT EndDate,
VARIANT BarSize, VARIANT BarFields);
Security: in Specifies either a single security, or array of securities as the basis of the request. See Security Syntax
Fields: in An array of Bloomberg field references, or mnemonics. All applicable fields can be found in the bbfields.tbl data dictionary. For a list of the three fields which can be used for an Intraday Time-Bars request, see the Time-Bar Fields page.
StartDate: in Either an absolute date indicating the first date about which data will be returned, or a numerical value relating to the number of days back in history to report from. The latter type indicates an intraday activity request. For more details, click the StartDate link in the above method signature.
EndDate: in, optional Indicates the final date about which data will be reported. Omitting this parameter causes all data to be reported up until the current time of request.
Please note that the Fields parameter expects a variant.
Question: How do I create a variant array of strings? I am getting an error on the Fields parameter. Need help to make some VBA macros go away. Thanks in Advance KD

Replies are listed 'Best First'.
Re: Win32::OLE::Variant Array
by almut (Canon) on Aug 16, 2007 at 17:37 UTC

    Have you tried an array of BSTR? Something like

    $aFields = Variant(VT_ARRAY|VT_BSTR, 1); $aFields->Put(0, "PX_Last");

    or, more generally:

    my @vals = qw(First Second Third ... Last); $arrStr = Variant(VT_ARRAY|VT_BSTR, scalar @vals); my $i = 0; for my $val (@vals) { $arrStr->Put($i++, $val); }

    (I currently can't test it, so this might be nonsense...!)

    As I understand it, VT_ARRAY|VT_UI1 would correspond to a C char[], i.e. a single string, or an array of characters...

    ___

    BTW, please put <code>...</code> tags (or short <c>...</c>) around your code sections — that makes it much easier to read...

Re: Win32::OLE::Variant Array
by Anonymous Monk on Aug 17, 2007 at 18:46 UTC
    Thanks for your quick reply.
    Your suggestion helped me make progress.

    When I run the code below I get the following error:
    Can't call method "Get" on unblessed reference at tstblpDataII.pl line 27.

    I must admit, being new to the world of PERL, that I have no idea what this means. Something about classes.

    If it helps. The code to do the same processing in VB looks like this.

    VBA Code
    Dim vtSec As Variant <br> Dim vtFields As Variant<br> Dim vtData As Variant<br> strSecId = Cells(currRow, colSecurityID).Value <br> vtSec = Array(Cells(currRow, colBBCode).Value & " " & Cells(cur +rRow, colSecType).Value)<br> vtData = bbObject.BlpGetHistoricalData(vtSec, vtFields, CDate(st +rBdate), CDate(strEDate)) <br>
    PERL code
    use Win32::OLE;<br> use Win32::OLE::Variant;<br> $blpData = Win32::OLE->new('Bloomberg.Data.1') or die "can NOT load t +he blpData" ;<br> #print $blpData->Timeout . "\n";<br> $aSec = Variant(VT_BSTR, "IBM Equity");<br> #@tmpArray = ("PX_Last"); <br> $aFields = Variant(VT_ARRAY|VT_BSTR, 1 );<br> $aFields->Put(0, "PX_Last");<br> $sDate = Variant(VT_DATE, "2007/07/01");<br> $eDate = Variant(VT_DATE, "2007/07/10");<br> $bbData = Variant(VT_EMPTY, 1);<br> $bbData = $blpData->BLPGetHistoricalData($aSec, $aFields, $sDate, $e +Date);<br> print "Error: " . Win32::OLE->LastError . "\n";<br> #print "Array Size: " , $bbData->Dim . "\n";<br> print "Returned: " . $bbData->Get(0) . "\n";<br> #@aDim = @bbData->Dim ;<br> #foreach $tmp (@aDim) {<br> # print $tmp<br> # <br> #}<br> print "end" ;<br>
      Can't call method "Get" on unblessed reference ...

      It seems the return value of BLPGetHistoricalData() is not a Perl object (i.e. a blessed reference), but rather just a regular reference. What it exactly is largely depends on the method being called, but unfortunately, the API description you posted isn't all that detailed in that respect, and I don't have the Bloomberg ActiveX control installed, so I can't test myself either...

      Best approach is probably to dump the returned data structure, e.g. using Data::Dumper, to figure out what it actually is (maybe an arrayref holding a list of variant objects — but that's merely a guess):

      use Data::Dumper; # ... print Dumper $bbData;

      ___

      (<meta> not wanting to sound patronizing, but please use the [reply] link at the right margin of the node you're replying to. In that case I would have gotten a message that there's a reply... (when people don't report back within a day or so, I don't always check for responses any longer). </meta>)

        Hello: I was finally able to get a run on the live Bloomberg station. And got this out put.
        Error: 0 $VAR1 = [ [ [ bless( do{\(my $o = 27137740)}, 'Win32::OLE::Variant' ), '112.04' ] ], [ [ bless( do{\(my $o = 27137852)}, 'Win32::OLE::Variant' ), '113.23' ] ], [ [ bless( do{\(my $o = 27137964)}, 'Win32::OLE::Variant' ), '111.89' ] ], [ [ bless( do{\(my $o = 27138116)}, 'Win32::OLE::Variant' ), '113.89' ] ], [ [ bless( do{\(my $o = 27138268)}, 'Win32::OLE::Variant' ), '113.53' ] ], [ [ bless( do{\(my $o = 27138492)}, 'Win32::OLE::Variant' ), '112.98' ] ], [ [ bless( do{\(my $o = 27138604)}, 'Win32::OLE::Variant' ), '110.73' ] ], [ [ bless( do{\(my $o = 27138756)}, 'Win32::OLE::Variant' ), '112.64' ] ] ]; end
        which is great progress! I see prices.
        what does the (my $o = 27138604) represent?
        Is there a way this could be interputed as a date?
        many thanks
        kd
      please note in the prior vtData is returned as an multidimensional array. Therefore I would expect that whatever is returned within PERL would have a Mutlidimemsional array inside somewhere.

      kd