Win32::OLE::Variantモジュール(日本語チョウ訳) Ver. 0.14対応

by Hippo2000(2001/2/20)

Jan Duboisさんにはメールで了解をいただきました。

内容等が間違っていたら修正します。ご連絡ください。



名前

Win32::OLE::Variant - OLE バリアント変数の作成と変更


概要

   use Win32::OLE::Variant;
    my $var = Variant(VT_DATE, 'Jan 1,1970');
    $OleObject->{value} = $var;
    $OleObject->Method($var);


説明

Perl OLEモジュールによって使われるIDispatch インターフェースはバリアント(VARIANT)と呼ばれる汎用的な引数型を使います。これは基本的にデータ型と実際のデータ値をもったオブジェクトです。データ型はVT_xxx定数により指定されます。

関数

nothing()
nothing() 関数は空のVT_DISPATCH変数を返します。プロパティに格納されたオブジェクト参照をクリアするために使うことができます。
    use Win32::OLE::Variant qw(:DEFAULT nothing);
    # ...
    $object->{Property} = nothing;

これは以下のVisual Basic ステートメントと同じ効果を持ちます。

   Set object.Property = Nothing

nothing() はデフォルトではエクスポートされません

Variant(TYPE, DATA)
これはWin32::OLE::Variant->new() メソッドの単なる別名関数です。(下記をご覧ください)この関数はデフォルトでエクスポートされます。

メソッド

new(TYPE, DATA)
このメソッドは指定されたTYPEの与えられたDATAをもったWin32::OLE::Variantオブジェクトを返します。 Win32::OLE::Variant オブジェクトは IV, NV または PV(これらは透過的にサポートされています)以外のデータ型を指定するために使うことができます。詳細については下記のVariantsをご覧ください。

VT_EMPTY と VT_NULL variantsについては、 DATA引数を省略することができます。すべてのVT_ARRAYではない variant については、DATAを初期値を指定します。

SAFEARRAY variantを作るためには、配列要素の基本型に加えてVT_ARRAYフラグを指定しなければなりません。この場合、DATAは配列を次元を指定するリストでなければなりません。各要素は要素数(0から指定数-1を示します)またはこの次元での上限下限を示す配列リファレンスのどちらかにすることができます:

   my $Array = Win32::OLE::Variant->new(VT_ARRAY|VT_R8, [1,2], 2);

これはdoubleで4つの要素:((1,0), (1,1), (2,0) そして(2,1) をもった2次元のSAFEARRAYを作成します。

特別なケースは、文字列DATA引数をもった1次元のVT_UI1配列の作成です。

   my $String = Variant(VT_ARRAY|VT_UI1, "String");

これは"String"で初期化された6つの文字配列を作成します。後方互換性のため、文字列初期値をもったVT_UI1は自動的にVT_ARRAYが暗黙のうちに設定されます。次の行は前の例と同じです:

   my $String = Variant(VT_UI1, "String");

本当に1文字 VT_Ul1 バリアントが必要なのであれば、数値の初期値を使って作らなければなりません:

   my $Char = Variant(VT_UI1, ord('A'));

As(TYPE)
As はVARIANT をPerlの値に変換される前に新しい型に変換します。これは現在のLCID設定も勘案します。例えばある文字列bんは小数点文字として,'が入っているかもしれません。$variant->As(VT_R8)を使うと浮動小数点値を返します。

元になるバリアントは、このメソッドによって変更されません。

ChangeType(TYPE)
このメソッドは入っているバリアントの型をその場で変更します。変換された値ではなく、オブジェクトそれ自身を返します。
Copy([DIM])
このメソッドはオブジェクトのコピーを作成します。元のバリアントのVT_BYREFビットが設定されていれば、新しいオブジェクトは同じ古いデータのリファレンスではなく参照されているデータのコピーを持ちます。新しいオブジェクトではVT_BYREFビットは設定されていません。
   my $Var = Variant(VT_I4|VT_ARRAY|VT_BYREF, [1,5], 3);
    my $Copy = $Var->Copy;

$Copyの型は今やVT_I4|VT_ARRAY であり、値は他のSAFEARRAYのコピーです。$Varの要素を変更しても$Copyには反映されませんし、その逆でも同じです。

CopyメソッドはVT_ARRAY | VT_VARIANT オブジェクトの1つの要素を取り出すために使うこともできます。この場合、配列のインデックスはリストDIMで指定されなければなりません:

   my $Int = $Var->Copy(1, 2);

$Int は今や要素(1,2)の値をもった VT_I4 バリアント・オブジェクトです。

Currency([FORMAT[, LCID]])
このメソッドはバリアントの値を書式設定された通貨文字列に変換します。FORMATは整数定数またはハッシュ・リファレンスのどちらかにすることができます。適切な定数は0とLOCALE_NOUSEROVERRIDEです。Win32::OLE::NLSモジュールからLOCALE_NOUSEROVERRIDEの値を取得することができます:
 use Win32::OLE::NLS qw(:LOCALE);

LOCALE_NOUSEROVERRIDEは、コントロール・パネル・アプリケーションを通して行われた変更をすべて無視しして、指定されたロケールのためのシステム・デフォルト通貨フォーマットを使うように指示します。

ハッシュ・リファレンスには以下のキーを入れることができます:

   NumDigits   小数の桁数
    LeadingZero 数値フィールドで前に0をつけるかどうか
    Grouping    数字区切りの各グループの桁数
    DecimalSep  小数点文字列
    ThousandSep 桁区切り文字
    NegativeOrder   Win32::OLE::NLS/LOCALE_ICURRENCYを参照
    PositiveOrder   Win32::OLE::NLS/LOCALE_INEGCURRを参照
    CurrencySymbol  通貨記号

例えば:

   use Win32::OLE::Variant;
    use Win32::OLE::NLS qw(:DEFAULT :LANG :SUBLANG :DATE :TIME);
    my $lcidGerman = MAKELCID(MAKELANGID(LANG_GERMAN, SUBLANG_NEUTRAL));
    my $v = Variant(VT_CY, "-922337203685477.5808");
    print $v->Currency({CurrencySymbol => "Tuits"}, $lcidGerman), "\n";

以下のようになります:

   -922.337.203.685.477,58 Tuits

Date([FORMAT[, LCID]])
バリアントを書式設定された日付文字列に変換する。FORMATは以下の整数定数か書式設定文字列のどちらかにすることができます:
 LOCALE_NOUSEROVERRIDE   このロケールでのシステム・デフォルト日付書式を使う
    DATE_SHORTDATE      短い日付書式を使う(デフォルト)
    DATE_LONGDATE       長い日付書式を使う
    DATE_YEARMONTH      年/月 書式を使う
    DATE_USE_ALT_CALENDAR   もしあれば代替 カレンダーを使う
    DATE_LTRREADING     左から右 読込順レイアウト
    DATE_RTLREADING     右から左 読込順レイアウト

Win32::OLE::NLSモジュールから定数を利用することができます:

   use Win32::OLE::NLS qw(:LOCALE :DATE);

以下の要素を日付書式設定文字列を構成するために使うことができます。文字は正確に以下で示される通りに指定されなければなりません(例えば"dd"は"DD"ではありません)。書式コードの間のどこにでも空白を入れることができます。その他の、逐語的なテキストはシングル・クォートに含まれなければなりません:

   d   日
    dd  日。1桁であれば前に0がつく
    ddd 曜日 : 3文字の省略名 (LOCALE_SABBREVDAYNAME)
    dddd    曜日 : フルネーム (LOCALE_SDAYNAME)
    M   月
    MM  月。1桁であれば前に0がつく
    MMM 月: 3文字の省略名 (LOCALE_SABBREVMONTHNAME)
    MMMM    月: フルネーム (LOCALE_SMONTHNAME)
    y   年 最後の2桁
    yy  年 最後の二桁。10よりも小さければ前に0がつく。
    yyyy    年 4桁により表される
    gg  時代/年号 文字列

例えば:

   my $v = Variant(VT_DATE, "April 1 99");
    print $v->Date(DATE_LONGDATE), "\n";
    print $v->Date("ddd',' MMM dd yy"), "\n";

は以下のように出力します:

   Thursday, April 01, 1999
    Thu, Apr 01 99

Dim()
VT_ARRAYバリアントのための配列範囲を返します。リストにはバリアントのSAFEARRAYの各次元の配列リファレンスが入ります。このリファレンスはこの次元のための下限と上限が入った配列を示します。例えば:
    my @Dim = $Var->Dim;

すると @Dim には以下のリストが入ります: ([1,5], [0,2]).

Get(DIM)
通常のバリアントではGetはValueメソッドとまったく同じようにバリアントの値を返します。VT_ARRAYバリアントではGetは1つの配列要素の値を取り出します。この場合、DIMは配列インデックスのリストでなければなりません。例えば:
 my $Val = $Var->Get(2,0);

1次元のVT_UI1|VT_ARRAYバリアントの特別場合、引数のないGetメソッドはPerl文字列として文字配列を返します:

   print $String->Get, "\n";

LastError()
Win32::OLE::Variant->LastError()メソッドを使うことは非難されます。代わりにWin32::OLE->LastError()クラスメソッドを使ってください。
Number([FORMAT[, LCID]])
このメソッドはバリアント値を書式化れた数字文字列に変換します。FORMATは整数定数またはハッシュ・リファレンスのどちらかにすることができます。適切な定数は0とLOCALE_NOUSEROVERRIDEです。LOCALE_NOUSEROVERRIDEの値をWin32::OLE::NLSモジュールから取得することがでいます:
   use Win32::OLE::NLS qw(:LOCALE);

LOCALE_NOUSEROVERRIDE はメソッドにコントロール・パネル・アプリケーションを通してなされたかもしれない変更をすべて無視して、指定されたロケールのためのシステム・デフォルト数値書式を使うように指示します。

ハッシュ・リファレンスには以下のキーのものを入れることができます:

   NumDigits   小数の桁数
    LeadingZero 数値フィールドで前に0をつけるかどうか
    Grouping    桁区切りの桁数
    DecimalSep  小数点の文字列
    ThousandSep 桁区切りの文字列
    NegativeOrder   Win32::OLE::NLS/LOCALE_INEGNUMBERを参照

Put(DIM, VALUE)
Putメソッドはバリアントに新しい値を代入するために使われます。値はバリアントの現在の型に強制されます。

例:

   my $Var = Variant(VT_I4, 42);
    $Var->Put(3.1415);

型がVT_I4なので、これはバリアントの値を3に変更します。

VT_ARRAY 型バリアントでは、SAFEARRAYに含まれている各次元のためのインデックスが当たらし値の前に指定されなければなりません:

   $Array->Put(1, 1, 2.7);

一度のPut()メソッド呼出しを使ってSAFEARRAYの*各*要素に値を代入することも可能です:

   $Array->Put([[1,2], [3,4]]);

この場合、Put()への引数は配列リファレンスで、Perlリストのリストの次元はSAFEARRAYの次元と厳密にあっていなければなりません。

1次元のVT_Ul1配列のためにはいくつか特別なケースがあります:VALUEは数値の代わりに文字列として指定することができます。これは選択された文字をその文字列の最初の文字に設定します。または文字列が空であれば'\0'にします:

   my $String = Variant(VT_UI1|VT_ARRAY, "ABCDE");
    $String->Put(1, "123");
    $String->Put(3, ord('Z'));
    $String->Put(4, '');

これは$Stringの値を"A1CZ\0"に設定します。もしインデックスが省略されると、文字列は完全に値へコピーされます。もしVT_Ul1配列の大きさよりも長ければ、その文字列は切り捨てられます。もし短ければ'\0'で埋められます。

   $String->Put("String");

$Stringには値"Strin"が入ります。

PutはVariantオブジェクトそのものを返します。そのためPut呼出しをつなげておこなうことができます:

   $Array->Put(0,0,$First_value)->Put(0,1,$Another_value);

Time([FORMAT[, LCID]])
バリアントを書し聞かされた時刻文字列に変換します。FORAMTは以下の整数定数か書式設定文字列のどちらかにすることができます:
   LOCALE_NOUSEROVERRIDE   このロケールでのシステム・デフォルト時刻書式
    TIME_NOMINUTESORSECONDS 分または秒を使わない
    TIME_NOSECONDS      秒を使わない
    TIME_NOTIMEMARKER   時刻マーカーを使わない
    TIME_FORCE24HOURFORMAT  つねに24時間制の時刻フォーマットを使う

定数はWin32::OLE::NLSモジュールから利用することができます:

   use Win32::OLE::NLS qw(:LOCALE :TIME);

以下の要素を日付書式設定文字列を構成するために使うことができます。文字は正確に以下で示される通りに指定されなければなりません(例えば"dd"は"DD"ではありません)。書式コードの間のどこにでも空白を入れることができます。その他の、逐語的なテキストはシングル・クォートに含まれなければなりません:

   h   時; 12時間制
    hh  時 1桁であれば前に0がつく;12時間制
    H   時; 24時間制
    HH  時 1桁であれば前に0がつく;24時間制
    m   分
    mm  分 1桁であれば前に0がつく
    s   秒
    ss  秒 1桁であれば前に0がつく
    t   A や Pのような1字時刻マーカー文字列
    tt  AMまたはPMのような複数文字時刻マーカー文字列

例えば:

   my $v = Variant(VT_DATE, "April 1 99 2:23 pm");
    print $v->Time, "\n";
    print $v->Time(TIME_FORCE24HOURFORMAT|TIME_NOTIMEMARKER), "\n";
    print $v->Time("hh.mm.ss tt"), "\n";

これは以下のように出力します:

   2:23:00 PM
    14:23:00
    02.23.00 PM

Type()
Typeメソッドは入っているバリアントのバリアント型を返します
Unicode()
UnicodeメソッドはUnicode::Stringオブジェクトを返します。これはネットワーク・バイト順でのバリアントのBSTR値が入ります。もしバリアントが現在はVT_BSTRフォーマットでなければ、VT_BSTRへのコピーが先に作成されます。
Value()
ValueメソッドはPerlの値としてバリアントの値を返します。すべてのWin32::OLEメソッドの値が変換されるのと同じ方法で変換されます。

オーバーロード

Win32::OLE::Variant パッケージは文字列と数値書式の変換がオーバーロードされています。このためVarinatオブジェクトはValueメソッドを先に適用することなしに、算術と文字列操作で使うことができます。

クラス変数

Win32::OLE::Variantクラスは独自のクラス変数の集合を$CP、$LCIDそして$Warnをもつようにしてきました。Win32::OLEモジュールのバージョン0.1003 以降では、これらの変数は削除されています。今ではWin32::OLEの設定が Win32::OLE::Variant モジュールでも使われます。Win32::OLE->Option クラス・メソッドのドキュメントをお読みください。

定数

デフォルトで以下の定数がエクスポートされます:

   VT_EMPTY
    VT_NULL
    VT_I2
    VT_I4
    VT_R4
    VT_R8
    VT_CY
    VT_DATE
    VT_BSTR
    VT_DISPATCH
    VT_ERROR
    VT_BOOL
    VT_VARIANT
    VT_UNKNOWN
    VT_DECIMAL
    VT_UI1

   VT_ARRAY
    VT_BYREF

VT_DECIMAL は許可されるOLEオートメーション・データ型の公式リストにはありません。しかしMicrosoft ADOでさえ、レコードセット・リールドの値をVT_DECIMAL形式で返しているようです。

バリアント

バリアント(Variant) はOLE接続の間でデータを渡すために使われるデータ型です。

デフォルトの動きは各Perlスカラ変数を内部のperl表現に合わせてOLEバリアントに変換します。以下の型対応が取られます:

        C type          Perl type       OLE type
        ------          ---------       --------
          int              IV            VT_I4
        double             NV            VT_R8
        char *             PV            VT_BSTR
        void *           ref to AV       VT_ARRAY
           ?              undef          VT_ERROR
           ?        Win32::OLE object    VT_DISPATCH

VT_BSTRが全角文字またはUnicode文字列であることに注意。これはパラメータとしてバイナリ・データを渡そうとすると、データのすべてのバイトの間に0x00が挿入されるという問題を起こします。Variant()メソッドはこれを解決する方法を提供します。Variantでスクリプトの作者は、そのパラメータが変換されるべきOLEバリアント型を指定することができます。現在は以下の型がサポートされています:

        VT_UI1     unsigned char
        VT_I2      signed int (2 bytes)
        VT_I4      signed int (4 bytes)
        VT_R4      float      (4 bytes)
        VT_R8      float      (8 bytes)
        VT_DATE    OLE Date
        VT_BSTR    OLE String
        VT_CY      OLE Currency
        VT_BOOL    OLE Boolean

VT_DATEとVT_CYオブジェクトが作成されると、入力パラメータはPerl文字列型として扱われます。これはVT_BSTRに変換され、最後にVariantChangeType OLE API関数を使ってVT_CYまたはVT_DATEに変換されます。これらがどのように使うことができるかについては、 Win32::OLE/EXAMPLES をご覧ください。

バリアント配列

バリアントは1つの値を持つだけでなく、値の多次元配列ももつ事ができます(SAFEARRAYと呼ばれます)。この場合、VT_ARRAYフラグが基本バリアント型に付与されなければなりません。例えばVT_I4|VT_ARRAYは整数の配列です。VT_EMPTYとVT_NULL型はSAFEARRAYには不適切です。バリアントの配列を作成することも可能です:VT_VARIANT | VT_ARRAY。この場合、配列の各要素を異なる型(VT_EMPTY、VT_NULLも含めて)にすることができます。VT_VARIANT SAFEARRAYの要素はVT_ARRAYまたはVT_BYREFのどちらのフラグも設定することはできません。

各次元の上限、下限は個別に指定することができます。(Perlの配列とは違って)すべてが同じ下限をもつ必要はありません。

リファレンスによるバリアント

いくつかのOLEサーバーは、メソッド呼出しの中で変更できるように、リファレンスによってパラメータが渡されることを期待します。これはメソッドに複数の値を戻すことを簡単にします。Win32::OLE::Variantモジュールでこれの予備的なサポートがされています:

   my $x = Variant(VT_I4|VT_BYREF, 0);
    my $y = Variant(VT_I4|VT_BYREF, 0);
    $Corel->GetSize($x, $y);
    print "Size is $x by $y\n";

GetSizeメソッド呼出しの後、$xと$yは対応する大きさに設定されます。これらはまだバリアントです。printステートメントでは、オーバーロードがそれらを自動的に文字列表現に変換します。

VT_BYREF は今やすべてのバリアント型でサポートされています(SAFEARRAYも含めて)。これはOLEオブジェクトをリファレンスで渡すためにも使われます:

   my $Results = $App->CreateResultsObject;
    $Object->Method(Variant(VT_DISPATCH|VT_BYREF, $Results));


作者(AUTHORS/COPYRIGHT)

このモジュールはWin32::OLEディストリビューションの一部です。


ホーム Perlの小技

ご意見、ご質問はこちらの掲示板で受け付けています。
またメールは河馬屋(Nifty)にお願いします。