「武器を身につけよう」へ戻る

配列を使う

「プロパティーを使ってみよう」の最後で少し配列について触れましたが、その配列についてもう少し詳しく見ていきたいと思います。
配列とFor〜nextを併用することで一連の似通った処理を効率的に処理することができます。
普通の変数については以前お話しました。
「データ(数字や文字)を入れる箱のようなもの」として説明したと思います。
これまでは話を簡単にする為使いませんでしたがVBScriptには
dim
と言うステートメントがあります。

たとえば
dim a
などという形で使われます。
「aと言う名前のデータを入れる箱を用意しておく」
といった意味です。
dimを使わなくても普通の変数のときは変数を最初に使うときにVBScriptが勝手に用意してくれるのでこれまで使わなかったのですが、スクリプトを読みやすくする為にも全ての変数を「dim」を使って宣言しておく事をお勧めします。
(参考)ついでにoption explicitというvbsのステートメントを調べてみてください。

VBやVBScriptを見ると
dim a(9)
などという記述を見たことがあるのではないでしょうか?
これは配列の宣言と呼ばれます。
このステートメントを言い換えると
「データ(数字や文字)を入れる(aという同じ名を持つ)箱を(10個)用意しておく。」
というような意味です。
注)配列の添字(括弧内の数字)は0から始まることに注意してください。

このように宣言すると、用意した変数(箱)を
aの1番目の箱は a(0)
aの2番目の箱は a(1)
aの10番目の箱は a(9)
と言う具合にaと言う名前の後ろの( )内の数字で区別して指定することができるようになります。
普通の変数はa,bといった「名前」で区別していたところを、後ろに続く括弧内の数字(添字)で区別しよう、ということです。

Topへ
使い方は変数と同じです。
普通の変数ではaという箱を用意しその箱にデータを代入します。
dim a
a=10


配列ではaという(同じ名前の)箱を3つ用意し、添字を使って区別して代入します。(左図を参照してください)
dim a(2)
a(0)=10
a(1)=16
a(2)=9
注)配列の添字は0から始まることに注意してください。

それではなぜ
dim a,b,c,d,e,f,g,h,i,j
と記述しても10個の箱を用意できるのに、わざわざ
dim a(9)
などという事をするのでしょう。
答えは簡単「便利だから」です。
ここでshadeに戻りましょう。
shadeでスクリプトを使う場合アンカーポイントの座標を
XShade.AnchorPoint()
で取り出すことがよくあります。
新規画面で10個のアンカーポイントからなる開いた線形状を適当に作ってください。(左図参照)

貴方はいま「x座標値がマイナスのポイントを抜き出したい」と思っています。
そして、後で「そのx座標値がマイナスのポイントのx座標値を0にしたい」と考えています。
また、「この座標値を使って他の処理もしたい」と考えているとします。
このような場合、まず、しなければいけないことは座標値を取り出し変数に確保することです。
配列を使わず普通の変数でこれを行うならば
dim x0,x1,x2,x3,x4,x5,x6,x7,x8,x9
x0=Xshade.AnchorPoint(0,0)
'0番目のアンカーポイントのx座標値
x1=Xshade.AnchorPoint(0,1) x2=Xshade.AnchorPoint(0,2) x3=Xshade.AnchorPoint(0,3) x4=Xshade.AnchorPoint(0,4) x5=Xshade.AnchorPoint(0,5) x6=Xshade.AnchorPoint(0,6) x7=Xshade.AnchorPoint(0,7) x8=Xshade.AnchorPoint(0,8) x9=Xshade.AnchorPoint(0,9) '10番目のアンカーポイントのx座標値
となります。
また、この値がマイナスかどうか調べ,マイナスならz座標値を0にしたいので
if x0<0 then XShade.AnchorPoint(0,0)=0
if x1<0 then XShade.AnchorPoint(1,0)=0
if x2<0 then XShade.AnchorPoint(2,0)=0
if x3<0 then XShade.AnchorPoint(3,0)=0
if x4<0 then XShade.AnchorPoint(4,0)=0
if x5<0 then XShade.AnchorPoint(5,0)=0
if x6<0 then XShade.AnchorPoint(6,0)=0
if x7<0 then XShade.AnchorPoint(7,0)=0
if x8<0 then XShade.AnchorPoint(8,0)=0
if x9<0 then XShade.AnchorPoint(9,0)=0
Topへ
となるでしょう。
ここで配列を使って書き換えると
					

dim x(9) x(0)=Xshade.AnchorPoint(0,0) '0番目のアンカーポイントのx座標値 x(1)=Xshade.AnchorPoint(0,1) x(2)=Xshade.AnchorPoint(0,2) x(3)=Xshade.AnchorPoint(0,3) x(4)=Xshade.AnchorPoint(0,4) x(5)=Xshade.AnchorPoint(0,5) x(6)=Xshade.AnchorPoint(0,6) x(7)=Xshade.AnchorPoint(0,7) x(8)=Xshade.AnchorPoint(0,8) x(9)=Xshade.AnchorPoint(0,9) '10番目のアンカーポイントのx座標値 if x(0)<0 then XShade.AnchorPoint(0,0)=0 if x(1)<0 then XShade.AnchorPoint(0,1)=0 if x(2)<0 then XShade.AnchorPoint(0,2)=0 if x(3)<0 then XShade.AnchorPoint(0,3)=0 if x(4)<0 then XShade.AnchorPoint(0,4)=0 if x(5)<0 then XShade.AnchorPoint(0,5)=0 if x(6)<0 then XShade.AnchorPoint(0,6)=0 if x(7)<0 then XShade.AnchorPoint(0,7)=0 if x(8)<0 then XShade.AnchorPoint(0,8)=0 if x(9)<0 then XShade.AnchorPoint(0,9)=0

となります。

「なーんだ良いことなんて何一つもないじゃないか」といわれるでしょう。
しかし、実は配列の括弧の中の数字は変数に置き換えることができるのです。

そこで前回覚えたfor〜nextを思い出してください。
これといっしょに使うとどうなるでしょう。

dim x(9),i     'iという変数を用意し、これを使い配列の添字の部分を変化させていきます。
for i=0 to 9
 x(i)=XShade.AnchorPoint(i,0)
 if x(i)<0 then XShade.ANchorPoint(i,0)=0
next
とできるのです。
(参考)もちろん、もとのデータを後で使う予定がなければ配列を使わず、次のようにすれば同じ処理はできます。
Topへ
for i=0 to 9
 if XShade.AnchorPoint(i,0)<0 then XShade.ANchorPoint(i,0)=0
next
データ数が10個なので配列を使わなくてもそれほど苦痛は感じませんが、これがデータ数100となったら考えただけでぞっとしませんか? 実行結果は右図の通り。


Topへ

多次元配列

上記の例では確保する座標値はx座標値だけでしたが、x,y,z全ての座標値を確保したいときはどうすればいいでしょう。
これまでの知識で考えると

dim x(9),y(9),z(9),i
for i=0 to 9
 x(i)=XShade.AnchorPoint(i,0)
 y(i)=XShade.AnchorPoint(i,1)
 z(i)=XShade.AnchorPoint(i,2)
next

となるでしょう
ついでなのでx,y,zに関しても配列にしてしまいましょう。
x,y,zを添字の0,1,2に置き換えて配列にします。
dim a(9,2),i
for i=0 to 9
 a(i,0)=XShade.AnchorPoint(i,0)
 a(i,1)=XShade.AnchorPoint(i,1)
 a(i,2)=XShade.AnchorPoint(i,2)
next
もちろんこれでは意味がないのでfor〜nextを使って
dim a(9,2),i,j
for i=0 to 9  'ポイントの数
 for j=0 to 2  '0:x , 1:y , 2:z を意味する。
 a(i,j)=XShade.AnchorPoint(i,j)
 next
next
とします。

上記の例ではa(9,2)が2次元配列と言うことになります。
同じ名前の箱を10×3(つまり30個)用意しています。
イメージとしては右図の通りです。

括弧の中に2つの添字を置き、その添字で箱を指定して特定します。(添字は番地のようなものです。)
スクリプトの中で「5番目のポイントのy座標の値(データ)を使いたい」ときは
a(4,1)
となります。
(注)配列の添字が0から始まるのを忘れないで下さい。
配列を使わずに同じ式を羅列した場合、修正するときなどは全ての式を変更しなくてはなりませんが、配列を使うと基本式は一つなので一箇所修正するだけで済むと言うのも大きな利点の一つです。

Topへ

REDIM

もう一つVBScriptの配列で便利なものにredimというステートメントがあります。
shadeでVBScriptを使っていると
(アンカーポイントの数が判らない)線形状の全てのアンカーポイントの座標値を取得したい
ことがあります。
つまりdimで配列(箱)の数を特定できない場合です。
前述の例ではアンカーポイントの数が固定(10個)なので上記のように書けるのですが、今回はそうはいきません。
そこで役に立つのがredimステートメントです。

次スクリプトは
選択した線形状(アンカーポイントの数の判らない)の全ての座標値(x,y,z)を取得する
サンプルです。
positionは座標値を確保する二次元配列
numはアンカーポイントの数を確保する変数

dim position(),num,i,j
num=XShade.NumberOfAnchorPoints()
redim position(num-1,2)
for i=0 to num-1
 for j=0 to 2
  position(i,j)=XShade.AnchorPoint(i,j)
 next
next
最初の行で括弧内の添字を省略して配列positionを宣言しておきます。
XShade.NumberOfAnchorPoints()で線形状のポイントの数を取得した後、3行目で新たにredimを使い実際の添字を変数(num-1)で指定します。
num取得後に
dim position(num-1,2)
とできればよいのですがそれは許されません。
4行目で
for i=0 to num-1
とループの終わりがnum-1となっていますが、これは配列の添字が0から始まることに起因します。(数えてみれば判るでしょう)
このようにして未定であったカッコ内の数字を確定後に指定できるのが redim の最も有効な使い道です。(配列の動的確保とも言います)

このように配列を使う(変数を添字を使って扱える)ということはそれだけスクリプトの汎用性が広がり、簡素に表現できるようになるのです。
shadeのスクリプトで変換マトリックスを扱うときなどは2次元配列 matrix(3,3) を使うと非常に楽になります。

「武器を身につけよう」へ戻る Topへ