<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />数年前、私は属性スタイルの測定システム分析のためのサンプリング計画を自動的に生成するスクリプトの構築に取り組んでいました。 すべてが順調に進んでいたのですが、大きな問題に遭遇しました。パーツの数が実行時に選択されている場合、使用されているパーツのマスター「合格/不合格」リストを生成するウィンドウをスクリプトで表示するにはどうすればよいでしょうか? さて、あなたはすでにこれを行う簡単な方法を考えているかもしれません。 しかし、私は今でも自分が思いついた方法を誇りに思っており、それをこのブログ投稿で共有したいと思います。
JSL Scripting Index のプログラミング部分には、Eval と Parse という一見無害な 2 つのエントリが隠されています。 これらの関数を使用すると、狡猾なスクリプタは文字列をコードの一部であるかのように実行できます。 これが可能になると、驚くべき意味が生まれます。 これを行うと、以前の問題も解決できます。
簡単なスクリプトを作成して詳しく見てみましょう。
//セクション 1:
// 1 つのパーツの合否基準を取得する
//いくつかの変数を初期化します
私= 1 ;
リストパーツ= {} ;
//条件を取得するためにモーダルウィンドウを構築します
新しい窓( 「合格/不合格リストの取得」 、
<<モーダル、
H リストボックス(
V リストボックス(
ラインナップボックス( 2 、
テキストボックス(文字(私)) 、リストパーツ[私】 =テキスト編集ボックス( "合格" ) 、
ボタンボックス( "OK" 、リストパーツ[私] =リストパーツ[私] <<テキストの取得; ) 、ボタンボックス( "キャンセル" )
)
)
)
) ;
//リストを見る
見せる(リストパーツ[私]) ;
ログが表示されていることを確認してから、このスクリプトを実行します。 スクリプト自体はウィンドウを表示し、1 つのパートに対してのみ、そのパートが「合格」か「不合格」かを尋ねます。 OK ボタンが押されると、ウィンドウ内のテキストはすべて i に渡されます。番目listParts リスト内の場所、listParts がログに表示されます。 たった 1 つの項目のリストに結果を保存するのは、現時点ではちょっとばかげているように思えますが、合格/不合格の基準を保存するパーツが複数ある場合には理にかなっています。 スクリプトが 3 つの部分でどのようになるかについては、以下の例を参照してください。
//第2節:
//上記のスクリプトを繰り返しますが、3 つの部分の基準を取得します
私= 1 ;
リストパーツ= {} ;
新しい窓( 「合格/不合格リストの取得」 、
<<モーダル、
H リストボックス(
V リストボックス(
ラインナップボックス( 2 、
テキストボックス(文字( 1 )) 、リストパーツ[ 1 ] =テキスト編集ボックス( "合格" ) 、
テキストボックス(文字( 2 )) 、リストパーツ[ 2 ] =テキスト編集ボックス( "合格" ) 、
テキストボックス(文字( 3 )) 、リストパーツ[ 3 】 =テキスト編集ボックス( "合格" ) 、
ボタンボックス( "OK" 、ために(私= 1 、私<= 3 、私++、リストパーツ[私] =リストパーツ[私】 <<テキストの取得; )) 、ボタンボックス( "キャンセル" )
)
)
)
) ;
見せる(リストパーツ) ;
しかし、まだ問題は解決していません。 このスクリプトで、任意の数のパーツに基づいて動的な数のテキスト ボックスを表示するにはどうすればよいでしょうか。このテキスト ボックスは、スクリプトの実行が開始されるまで不明であり、スクリプトが実行されるたびに異なる可能性があります。 前述の神童、エヴァルとパースを助けに来てください。 次のコードを見てください。
//セクション 3:
//パーツの数を決定する
新しい窓( 「パーツは何個ですか?」 、
<<モーダル、
ネブ=数値編集ボックス( 10 ) 、
ボタンボックス( "OK" 、パーツ数=ネブ<<得る; )
) ;
見せる(パーツ数) ;
リストパーツ= {} ;
//モーダルウィンドウ用のスクリプトの最初の部分を構築します
//「is \!」のエスケープ文字シーケンス
ある= 」
新しいウィンドウ(\!"合格/不合格リストの取得\!",
<<モーダル、
H リスト ボックス(
V リストボックス(
ラインナップボックス(2、
」 ;
//for ループは 2 番目の部分を作成します。これにより、部分の数に応じて入力ボックスが構築されます。
// ||連結のショートカットです
b = 「」 ;
ために(私= 1 、私<=パーツ数、私++、
b1 =文字( 「テキストボックス(char(」 ||文字(私) || "))、listParts[" ||文字(私) || "] = テキスト編集ボックス(\!"パス\!")," ) ;
b = b || b1 ;
) ;
//モーダルウィンドウ用のスクリプトの最後の部分を構築します
c = 」
Button Box(\!"OK\!", for (i = 1, i <=numParts, i++, listParts) = リストパーツ<< テキストを取得;))、ボタン ボックス(\!"キャンセル\!")
)
)
)
)
」 ;
// スクリプトの一部を結合して実行します
d =ある|| b || c ;
評価(解析する( d )) ;
//何が作成されたかを見てください
見せる( d ) ;
見せる(リストパーツ) ;
まず、パーツの数をユーザーに尋ねるセクションがあり、パーツの数は numParts に保存されます。 次に、スクリプトは、すべて紫色であることを除けば、JSL に似ていると思われる 3 つの個別の文字列を作成します。 最初の文字列は、テキスト ボックスが挿入される部分まで、以前のスクリプトの正確なコピー (引用符で文字列が終わらないようにするための特別なコードが含まれています) です。 2 番目の部分は、以前に入力された多くの部分 (numParts) のテキストボックスの繰り返しで構成される文字列を構築する for ループです。 3 番目のセクションは、前のスクリプトの最後の部分です。
この文字列が作成されたら、それらを結合します ( d =ある|| b || c ; )、次に、評価(解析する( d )) ;このコマンドは、JMP が文字列 d (調整可能な数のテキスト ボックスを含む動的に作成された文字列) を、文字列 d が単なる文字列ではなく JSL スクリプトであるかのように解析したときに何が起こるかを評価します。 ログを参照して、多数のテキスト ボックスを表示する非常に長いコマンドと、生成された合格/不合格のリストの両方を確認します (デフォルトをそのまま使用する場合は以下を参照)。
d = "
新しいウィンドウ(\!"合格/不合格リストの取得\!",
<<モーダル、
H リスト ボックス(
V リストボックス(
ラインナップボックス(2、
テキスト ボックス(char(1))、listParts[1] = テキスト エディット ボックス(\!"パス\!")、テキスト ボックス(char(2))、listParts[2] = テキスト エディット ボックス(\!"パス\ !"),テキスト ボックス(char(3)), listParts[3] = テキスト エディット ボックス(\!"パス\!"),テキスト ボックス(char(4)), listParts[4] = テキスト エディット ボックス(\ !"Pass\!"),Text Box(char(5)), listParts[5] = テキスト編集ボックス(\!"Pass\!"),Text Box(char(6)), listParts[6] = テキスト編集ボックス(\!"パス\!"),テキスト ボックス(char(7)), listParts[7] = テキスト編集ボックス(\!"パス\!"),テキスト ボックス(char(8)), listParts[ 8] = テキスト編集ボックス(\!"パス\!"),テキスト ボックス(char(9)), listParts[9] = テキスト編集ボックス(\!"パス\!"),テキスト ボックス(char(10) )、listParts[10] = テキスト編集ボックス(\!"パス\!")、
Button Box(\!"OK\!", for (i = 1, i <=numParts, i++, listParts) = リストパーツ<< テキストを取得;))、ボタンボックス(\!"キャンセル\!")
)
)
)
)
";
listParts = {"合格", "合格", "合格", "合格", "合格", "合格", "合格", "合格", "合格", "合格"};
ここで、その影響について少し考えてみましょう。 これらの概念を使用すると、コード自体を調整して実行するコードを作成できます。 動的で、自己参照的で、再帰的で、クレイジーなスクリプトは、ほんの始まりに過ぎない可能性があります。 十分な時間と忍耐があれば、おそらくこのコンセプトを使ってスカイネットを作成できるでしょう。 よく考えてみると、それはあまり良い考えではないかもしれません…
型なし変数の楽しい謎をご覧ください。 JSL では、そのような状況に驚くほど簡単に陥ります。 私も、機能するはずのないコードをうっかり使ってしまったことがあります。JMP の新しいバージョンや動作条件の違いによって、私のずさんな行為がついに失敗したとき、それを解くのは本当に大変でした。
詳細を白状したいのですが、まったく覚えていません(おそらく抑圧しているのでしょうか?)。JSL クラブの第一のルールは、JSL クラブで何が起こっているかについて話さないことです。
あなたのフォローで腹を抱えて大笑いしたと言えば十分です。
Erin の意見に加えて、この例では名前を常に適切に使用していないという点で、私のちょっとした愚かさも原因であると考えられます。 何が起こっているのかと思いますが、ウィンドウが作成されるときに、大量のテキスト ボックスが作成されます。 テキスト ボックスはオブジェクトであるため、<< Get Text() メッセージを送信できる必要があります。 愚かな点 (運?) は、各テキスト ボックスに ListParts という名前が割り当てられていることです。いつListParts[x] に Get Text () メッセージを送信すると、実際にテキストが取得されます。 振り返ってみると、listParts[x] テキスト ボックスに別の名前を付ける必要がありました (つまり、以下の例では、ListParts[1] を tb[1] に置き換えます)。
Text Box(char(1)), listParts[1] = Text Edit Box("Pass"),
これは、実際には間違っているにもかかわらず、スクリプトが作成者が望んだことを実行する稀な例の 1 つであると思います。これは、ある意味刺激的です。
ここでの問題は、<
オブジェクトではないものにメッセージを送信することはできません。また、リストは、たとえばデータ テーブルと同じ意味でオブジェクトではありません。 私は最近、クライアントのアドインの 1 つで長年のバグを修正しようとしていたことに気づき、修正しました。
list<<INSERT item=""></INSERT>
それ以外の
insert item(list, item)
私たちの多くが混乱しているのは、連想配列は <<メッセージを受け取ることができるオブジェクトであるため、次のような同じ名前のコマンドでも異なる構文が表示されることだと思います。
map=associative array(:Name, :Weight);
map<<INSERT item=""></INSERT>
手元の質問に戻りますが、そもそも、この例で listparts[i]<Re: Eval ()、Parse ()、および再帰、メタプログラミングの冒険
素晴らしい例です、ありがとう@Jed_Campbell 。解決できない問題が 1 つあります。エラーが発生します: 'List' のアクセスまたは評価で、Send Expects Scriptable Object を送信してください、 {/*###*/"Pass", "Fail"}
この送信コマンドが問題の原因だと思います。複数の数字を選択した場合にのみエラーが発生します。何かご意見は?
listParts = listParts << Get Text;