http://madia.world.coocan.jp/cgi-bin/VBBBS/wwwlng.cgi?print+200711/07110042.txt
のスレッドで、魔界の仮面弁士さんのコメントを興味深く拝見しました。
以前から、VB6に無いJavaScriptの配列のsort,push,pop,shift,unshift・・
などの便利なメソッドを使えればなー と考えていました。
> Set SC = CreateObject("ScriptControl")
> SC.language = "JScript"
> SC.ExecuteStatement "List=new Array()"
> Set List = SC.Eval("List")
> For n = 1 To 50
> List.push n
> Next
上記手法で、利用できるのですね。魔界の仮面弁士さんに感謝いたします。
それで、質問としては
1.単なる配列への読み込みや読み出しを行う場合、処理速度的には
どうでしょうか? → 遅くなる、ならない?
2.配列の各中身を取り出すには?
上の例で、List(n)といった形では取り出せませんでした。
List.slice(n,n+1) という以外にありませんか?
よろしくお願いします。
> 上記手法で、利用できるのですね。
利用できますが、IDispatchEx の言語実装の差異により、
メンバ名の「大文字小文字が区別される」という問題があります。
たとえば、そのコードで得た Arrray オブジェクトの要素数を調べる際に、
Debug.Print List.length 'これは OK
Debug.Print List.Length 'これは NG
という現象が発生します。
Visual Basic では、大文字小文字が自動補正されてしまうため、
この事は、かなり都合が悪いです(VBScript であればまだマシですが)。
自動補正されないよう、「CallByName によるメンバ呼び出し」を検討するか、
「ScriptControl 経由での JScript 呼び出し」にするのが安全かと。
> 1.単なる配列への読み込みや読み出しを行う場合、処理速度的には
> どうでしょうか? → 遅くなる、ならない?
VB ネイティブの配列と Long 配列など比べれば遅くはなるでしょうが、それ自体は
単なる COM オブジェクトですから、問題視するほど遅くは無いと思います。
Collection や Dictionary をレイトバインドで使ったときと同程度では無いかと。
まぁ、憶測で答えているだけなので、気になるのであれば、
実際に検証されることをおすすめします。
> 2.配列の各中身を取り出すには?
> 上の例で、List(n)といった形では取り出せませんでした。
JScript 側の変数に対して、スクリプトコントロール経由で
Debug.Print SC.Eval("List[3]")
のように取り出すことが可能です。
VB 側の変数から取り出す場合は、
Debug.Print CallByName(List, "3", VbGet)
のように書けます。
ただし範囲外のインデックスが指定された場合、前者のコードでは
Empty が返されるのに対し、後者は実行エラー 438 が発生します。
>>> SC.ExecuteStatement "List=new Array()"
>>> Set List = SC.Eval("List")
これは、
Set List = SC.Eval("List=new Array()")
の 1 行にまとめられそう。
>> List.slice(n,n+1) という以外にありませんか?
あるいは、「For Each v In List」での取り出しも可能です。
> VB ネイティブの配列と Long 配列など比べれば遅くはなるでしょうが、
う。日本語が変ですね。
「VB ネイティブの Long 配列などと比べれば遅くはなるでしょうが、」
に読み替えてください。
まぁ何にせよ、扱いにくすぎて実用的では無いですね。(^^;
もし使うなら、*.wsc などにカプセル化しておいた方が良いと思います。
魔界の仮面弁士さん
詳細な御説明ありがとうございます。
> まぁ何にせよ、扱いにくすぎて実用的では無いですね。(^^;
> もし使うなら、*.wsc などにカプセル化しておいた方が良いと思います。
どの程度使えるか?あるいは扱いにくいか実際に使ってみないと
わからないですね。
> 利用できますが、IDispatchEx の言語実装の差異により、
> メンバ名の「大文字小文字が区別される」という問題があります。
>
> たとえば、そのコードで得た Arrray オブジェクトの要素数を調べる際に、
> Debug.Print List.length 'これは OK
> Debug.Print List.Length 'これは NG
> という現象が発生します。
>
> Visual Basic では、大文字小文字が自動補正されてしまうため、
> この事は、かなり都合が悪いです(VBScript であればまだマシですが)。
機会があれば使ってみて遊んで見たいと思います。
どうもありがとうございました。
解決のチェックを忘れていました。
編集 削除確認してませんが、
List.3
Eval("List." & n)
とか
JScriptなので、Arrayオブジェクトのプロトタイプにメソッドを追加して、
List.Item(n)
なんて、できますよ。
ただ、そうすると、
For Each x In List
が変なことになって、ちょっと使えなくなります。
sc.AddCode "function Array.prototype.get(i){return this[i];}"
sc.AddCode "function Array.prototype.put(i,v){return this[i]=v;}"
こんなの
スクリプトプログラマさん
> sc.AddCode "function Array.prototype.get(i){return this[i];}"
> sc.AddCode "function Array.prototype.put(i,v){return this[i]=v;}"
> こんなの
大変参考になりました。
早速、VBの大文字小文字対応するために
SC.AddCode "function Array.prototype.Length(){return this.length;}"
とやってみました。
しかし、
Debug.Print List.Length では
function Array.prototype.Length(){return this.length;}
となってしまいます。
Debug.Print List.Length(1) などと適当に引数を与えると
正しく値が得られます。
式を修正することで、引数を与えずに正しいデータを取得する
スクリプトはどの様にすればよいのでしょうか?
よろしくお願いします。
無理でしょう。
CallByName(List,"Length",vbMethod)
Eval("List.Length()")?
それなら最初から
Eval("List.length")
か、
Dim length
ダミー宣言を入れとくとか
あと訂正
List.[3]
Eval("List.[" & n & "]")
ですね
> Dim length
> ダミー宣言を入れとくとか
目から鱗です。
そういえば、あのコードを書いたときに・・・
と思い当たりますね!
スクリプトプログラマさん、どうもありがとうございました。
2回目の解決です (笑