
本記事は、「%ZLANGV00」「%ZLANGC00」ルーチンを利用して、オリジナルの特殊変数やコマンドを作成する方法をご紹介します。
はじめに
前回の記事で「%ZLANGF00」ルーチンのご紹介をしました。
本記事では、「%ZLANG」ルーチンシリーズの残り2つ、「%ZLANGV00」と「%ZLANGC00」について解説します。
「%ZLANGV00」はオリジナルの特殊変数を作成するルーチンであり、「%ZLANGC00」はオリジナルのコマンドを作成するルーチンです。
これらを活用することで、アイデア次第でコーディングを効率化できます。ただし、呼び出し速度が若干遅いというデメリットもあります。
メリットとデメリットを把握しつつ、適切に使いこなせば選択肢の一つとして活用できると思います。
では、それぞれの詳細について解説していきます。
%ZLANGV00
「V(variable)」とついている通り、オリジナルの特殊変数を作成します。
特殊変数については、常々よく利用していると思います。
特殊変数の一覧
特殊変数名 | 説明 |
---|---|
$HOROLOG | 現在のプロセスのローカル日付と時刻 |
$JOB | 現在のプロセスのジョブ ID |
$NAMESPACE | 現在のネームスペース名 |
$TLEVEL | 現在のトランザクションの入れ子レベル |
$USERNAME | 現在のプロセスのユーザ名 |
$ZHOROLOG | システム起動時以降の経過秒数 |
$ZJOB | 現在のプロセスのジョブの状態 |
$ZPI | 円周率 |
$ZTIMESTAMP | 協定世界時 (UTC) 形式による現在の日付と時刻 |
$ZTIMEZONE | GMT を基準にしたローカル・タイム・ゾーン・オフセット |
$ZVERSION | 現在のバージョン |
$IO | デバイスID |
これらは、多々ある特殊変数の一部です。
では次は、これらと同様の特殊変数を作成していきます。
作成
「%SYS」ネームスペースにて、「%ZLANGV00」ルーチンを作成します。
今回は下記2つの特殊変数をサンプルで作成します。
- 苗字を格納 & 返す
- 本日の日付を「YYYY-MM-DD」で返す
サンプル
%ZLANGV00 ;
q
;-
;
;-- 苗字を保存 & 返す
ZSEI(val) ;
i ($d(val)) {
s ^||testSei=val
}else{
q $g(^||testSei)
}
;-
;
;-- 本日の日付をYYYY-MM-DDで返す
ZNDATE ;
q $zd($h, 3)
;-
;
では、ターミナルにて出力してみたいと思います。

今回作成した特殊変数「$zsei」は、引数をプロセス・グローバルに保存し、呼び出しの度にプロセス・グローバルの値を返す方法を採用しています。
※プロセス・変数やグローバル等でも代用可能です。
特殊変数の作成と使用方法は以上になります。
次は、特殊コマンドの解説を行います。
%ZLANGC00
「C(command)」とついている通り、オリジナルのコマンドを作成します。
オリジナルのコマンド?
と聞いても、イマイチ「ピン」と来ないかと思うので、実際にルーチンを作成しつつ動作を確認してみましょう。
作成
「%SYS」ネームスペースにて、「%ZLANGC00」ルーチンを作成します。
今回は、ネームスペース「%SYS」と「SAMPLE」に関数を用意し、その関数を実行するオリジナルのコマンドを作成して、%ZLANGC00の理解を深めたいと思います。
【サンプルルーチン】
ZADDFUJIコマンドは、ルーチン内のサブルーチンを実行しています。
ZSAMPLEコマンドは、ネームスペース「SAMPLE」に存在しているクラスを実行しています。
%ZLANGC00
q
;-
;
ZADDFUJI(val)
w $$ADDFUJIWARA(val) // ↓のラベルを呼ぶ
;-
;
ADDFUJIWARA(val)
q "藤原"_val
;-
;
ZSAMPLE
// 実行ネームスペースにあるクラスを呼ぶ
d ##class(developer.Sample).callName()
q
;-
;
ネームスペース「SAMPLE」にある関数「callName()」
ClassMethod callName()
{
w "藤原道長"
}
では、実行ネームスペースを「SAMPLE」に変更し、各コマンドを実行してみましょう。
コマンドは下記になります。
zn "sample"
zaddFuji "道長"
zsample
実行結果が下記になります。

では、実行ネームスペースを「USER」に変更し、コマンドを実行したら、どのような結果が返ってくるでしょうか。

予想通り、コマンド「ZSAMPLE」はエラーになりましたね。
実行クラスがネームスペース「SAMPLE」に存在しているため、さすがに実行は難しいようです。
もし、他ネームスペースで実行したい場合は、特殊変数「$namespace」を使用してネームスペースを切り替える必要があります。
ZSAMPLE
new $namespace
s $namespace = "sample"
d ##class(developer.Sample).callName()
q
;-
;
コマンド「ZADDFUJI」に関しては、ルーチン「%ZLANGC00」がネームスペース「%SYS」に存在しているためか、どのネームスペースでも実行可能です。
どのネームスペースでも実行させたいのであれば、「%SYS」に処理を配置しておいた方が楽ですね。
速度検証
前回の記事からも、結果は予測できていますが、念のため速度検証を行いたいと思います。
下記をルーチンに張り付けて、検証を実施してみます。
Check(cnt) ;
s start = $zh
f pos=1:1:cnt {
zsample
}
w "オリジナル:"_($zh-start),!
s start = $zh
f pos=1:1:cnt {
d ##class(developer.Sample).callName()
}
w " 通常:"_($zh-start)
下記が実行コマンドになります。
d Check(1000000)
【実行結果(100万回ループ)】
オリジナル:1.962925
通常:1.028507
呼び出しが遅いのは、前回の記事でも書いた通りです。
一回の実行速度は「0.000001」程度の差ですが、実行回数が増加すればその差は無視できなくなります。
アイディア・コーディング量を選択するか、処理速度を優先するかは、システムの性格にもよるので、検討をお願いいたします。
おわりに
いかがだったでしょうか。
全2回にわたり、3つの%ZLANGルーチンについて解説しました。
全体的な印象としては、「コーディング量を減らせる一方で、呼び出し時間が増加する」という、少し惜しい機能といえます。
しかしながら、アイデア次第では大きく活用の幅が広がる可能性を秘めています。
もし、「こんな使い方をしている」といった事例がありましたら、ぜひご連絡いただければ幸いです!