オブジェクトのループ

Origin プロジェクトに存在している特定のオブジェクトに、ある操作を次々と実行することができます。 例えば、プロジェクトのすべてのグラフレイヤを再スケールしたり、プロジェクト内のすべてのワークシートに新しい列を追加することができます。 LabTalkのdocumentコマンド(またはdoc)は、このような操作を行うものです。 docコマンドのいくつかの例がここに示されています。

目次

プロジェクト内のオブジェクトをループ

-e または -ef スイッチ付きの document コマンド(または doc -e コマンド)は、Originプロジェクト内のさまざまなオブジェクトのコレクションをループするための一般的な方法です。このコマンドにより、コレクション内で見つかったOriginオブジェクトの各インスタンスで複数行のLabTalkスクリプトを実行します。

ワークブックとワークシートをループ

doc-e LBコマンドを使用すると、プロジェクト内のすべてのワークシートをループできます。 次のスクリプトは、行列レイヤを読み飛ばして、すべてのワークシートをループします。

//プロジェクト内のすべてのワークシートをループし
//その名前および各シートの列数を出力
doc -e LB {
	if(exist(%H,2)==0) //ワークブックではなく、行列でなければならい
		continue;
	int nn = wks.nCols;
	string str=wks.Name$;
	type "[%H]%(str$) has $(nn) columns";
}

次のサンプルは、プロジェクトの異なるワークブックに存在するデータ列をループして操作する方法を示しています。

Origin 8.1 SR2以降で利用可能なサンプルプロジェクトファイルを開きます。
\\Samples\LabTalk Script Examples\Loop_wks.opj

プロジェクトには、Sample1、Sample2フォルダとバックグラウンド信号に Bgsignal というフォルダがあります。Sample1、Sample2フォルダには Freq1 および Freq2という2つのフォルダがあり、これは特定のサンプルに対する1セットの周波数でのデータに対応しています。

Freq1、Freq2 フォルダ内のワークブックは DataX, DataY および定数の周波数を含む3列があります。Bgsignal フォルダのワークブックの名前は Bgsigです。 Bgsig ワークブックでは、DataX と2つのY列を含む3列があり、そのロングネームは、各 Freq フォルダのワークブックの周波数に対応しています。

各ワークブックに列を追加し、同じ周波数のサンプルデータから特定の周波数のバックグラウンド信号を減算するのが目的です。 以下のLabTalkスクリプトでこの操作を実行します。

doc -e LB
{ //各ワークシートをループ
   if(%H != "Bgsig") //バックグラウンド信号のワークブックをスキップ
   {
      Freq=col(3)[1]; //周波数を取得
      wks.ncols=wks.ncols+1; //サンプルシートに列を追加
      //ロングネームを使ってFreqに対するbg 信号列を取得
      range aa=[Bgsig]1!col("$(Freq)");
      wcol(wks.ncols)=col(2)-aa; //bg 信号を減算
      wcol(wks.ncols)[L]$="Remove bg signal"; //ロングネームを設定
   }
}

上記コードよりもやや遅いですが、コード内でブックをループしてからシートをループすることもできます。

次の例では、現在アクティブなプロジェクトエクスプローラのフォルダ内のすべてのワークブックをループし、見つかった各ブック内の各シートをループする方法を示しています。

int nbooks = 0;
// このフォルダの名前を取得
string strPath;
pe_path path:=strPath;
// すべてのワークブックをループ 
// 現在のプロジェクトエクスプローラフォルダビュー
doc -ef W {
   int nsheets = 0;
   // 各ワークブックのすべてのワークシートをループ
   doc -e LW {
      type Sheet name: %(layer.name$);
      nsheets++;
   }
   type Found $(nsheets) sheet(s) in %H;
   type %(CRLF);
   nbooks++;   
}
type Found $(nbooks) book(s) in folder %(strPath$) of project %G;

また、ワークブックのプロパティを使用して内部ループを置き換えることができます。

int nbooks = 0;
// このフォルダの名前を取得
string strPath;
pe_path path:=strPath;
// すべてのワークブックをループ 
//現在のプロジェクトエクスプローラフォルダビュー
doc -ef W {
   // 各ブックループ内のすべてのワークシートをループ
   loop(ii,1,page.nlayers) {
      range rW = [Book1]$(ii)!;
      type Sheet name: %(rw.name$);
   }
   type Found $(page.nlayers) sheet(s) in %H;
   type %(CRLF);
   nbooks++;   
}
// 最終的なレポート- %G はプロジェクト名を含む
type Found $(nbooks) book(s) in folder %(strPath$) of project %G;

グラフウィンドウをループ

通常、データファイルをインポートした後、ワークブックのロングネームはデータファイル名になる。データがインポートされプロットされている場合、以下のスクリプトで全てのグラフウィンドウをループし、グラフウィンドウのロングネームをブックのロングネーム(データファイル名)に変更します。

doc -e P
{
    page.label$=%(1, @WL); // 以前のバージョンではpage.longname$=%(1, @WL) を使用
}

次のスクリプトは、すべてのグラフウィンドウをデフォルトのプリンタドライバに印刷します。

doc -e P print; // ''document -each Plot Print''の略

次のスクリプトは、埋め込みグラフを除くすべてのグラフウィンドウのすべてのレイヤをループし、グラフのウィンドウ名とレイヤ名をスクリプトウィンドウに印字します。グラフのロングネームがない場合、ショートネームが印字されます。

doc -e LP
{
    //埋め込みグラフとレイアウトウィンドウのグラフはスキップ
    if(page.IsEmbedded==0&&exist(%H)!=11)
    {
        //グラフロングネームを文字列変数名に割り当て
        string name$ = %(page.label$); 
        //ロングネームがない場合、ショートネームを文字列変数名に割り当て
        if(name.Getlength()==0 ) name$ = %H; 
        
        type [%(name$)]%(layer.name$);
    }
}

ワークブックウィンドウをループ

document -eコマンドは、このサンプルのようにネストして、すべてのワークシート内のすべてのYデータセットをループできます。

doc -e W
{
    int iCount = 0;
    doc -e DY
    {
        iCount++;
    }
    if( iCount < 2 )
      { type Worksheet %H has $(wks.ncols) columns,; 
        type $(iCount) of which are Y columns; }
    else
      { type Worksheet %H has $(wks.ncols) columns,; 
        type $(iCount) of which are Y columns; }
}

列と行をループ

この例では、すべての列をループし、n番目の列ごとに削除します。

int ndel = 3; // 必要に応じてこの数字を変更
int ncols = wks.ncols;
int nlast = ncols - mod(ncols, ndel);
// 右から左に削除する必要がある
for(int ii = nlast; ii > 0; ii -= ndel)
{
   delete wcol($(ii));
}

この例では、ワークシートの行ごとに削除する方法を示しています。

int ndel = 3;           // 必要に応じてこの数字を変更
range rr = col(1);      // 列1の範囲を取得
nrows = rr.GetSize();   // 数値行の数を取得
int nlast = nrows - mod(nrows, ndel);
// 下から上に削除する必要がある
for(int ii = nlast; ii > 0; ii -= ndel)
{
   range rr = wcol(1)[$(ii):$(ii)];
   mark -d rr;
}

このスクリプトは、Sheet1の4つの列の対数を計算し、結果をSheet2の対応する列に配置します。

for(ii=1; ii<=4; ii++)
{
	range ss = [book1]sheet1!col($(ii));
	range dd = [book1]sheet2!col($(ii));
	dd = log(ss);
}

グラフィックオブジェクトをループ

アクティブレイヤ内のすべてのグラフィックオブジェクトをループできます。これを他の2つのオプションで包むことで、プロジェクト全体をカバーできます。

// 各プロットに対して
doc -e P
{
    // 各プロットの各レイヤに対して
    doc -e LW
    {
        // 各プロットの各レイヤの各図形オブジェクトに対して
        doc -e G
        {   // 凡例の背景に陰を付ける設定
            if("%B"=="Legend") %B.background = 2;
            // 日時スタンプの色を青にセット
            if("%B"=="timestamp") %B.color = color(blue);
            // すべての矩形オブジェクトを削除
            if("%B"=="rect*") label -r %B; 
        }
    }
}

グラフ内のすべてのレイヤでピーク分析を実行

この例では、事前に保存されたピークアナライザのテーマファイルを使用して、グラフ内のすべてのレイヤをループし、各レイヤのデータセットのピーク分析を実行します。 アクティブウィンドウが複数レイヤグラフであり、各レイヤに1つのデータ曲線があるものとします。 また、事前に保存されたピークアナライザテーマが存在していることを前提としています。

//ループに入る前にリマインダメッセージを表示しないようにする
// これはOriginがレポートシートに切り替わることについての
// リマインダーメッセージをポップアップしないようにする
type -mb 0;
// グラフウィンドウのすべてのレイヤをループ
doc -e LW
{
   // 事前セットしたテーマでピーク分析を実行
   sec; 
   pa theme:="My Peak Fit"; 
   watch;
   /* sec と watch は任意
      これらは各レイヤでデータフィットにかかる時間を出力 */
}
// リマインダーメッセージを戻す
type -me;