0

ループと文字列を使用して PowerBuilder で変数名を作成できるかどうかに興味があります。例えば:

long ll_go
string lst_new
for ll_go = 1 to 8
  lst_new = "text" + ll_go
  lst_new.tag = 5500
next

したがって、変数 text1、text2..、text8 が与えられ、それらに値を割り当てることができます。成功した人がいたら教えてください、事前に感謝します

4

5 に答える 5

1

あなたの説明には用語の正確さが欠けています。

実際に新しい変数を「powerscript サブルーチンまたは関数の変数」として動的に作成したい場合、これは単純に不可能です。

代わりに、新しいコントロールstatictext または textedit オブジェクトをウィンドウまたはビジュアル ユーザーオブジェクトに動的に作成する場合は、次のことが可能です。

  1. 作成する必要がある新しいオブジェクトのタイプのローカル変数を使用します。static text
  2. でライブオブジェクトにする(インスタンス化する)create
  3. オブジェクトのプロパティを必要なものに設定します
  4. メソッドを使用して、新しいオブジェクトをその親 ( awindowまたはビジュアルのいずれかuserobject- graphicobjectwin32apiSetParent関数を使用すると可能ですが) に「アタッチ」しますOpenUserObject()Control[]親の配列に単純に直接追加することはできないことに注意してください。
  5. 配列をループする代わりに、後で作成したオブジェクトに簡単にアクセスできるように、オブジェクトを独自の配列に保持することもできControl[]ます
  6. オブジェクトがその親にアタッチされると、ローカル変数を再利用して別の変数を作成できます

次に例を示します。

//put this in a button clicked() event on a window
//i_myedits is declared in instances variables as 
//SingleLineEdit i_myedits[]
SingleLineEdit sle
int i
for i = 1 to 8 
    sle = create singlelineedit
    sle.text = string(i)
    sle.tag = "text_" + string(i)
    sle.height = pixelstounits(20, ypixelstounits!)
    sle.width = pixelstounits(100, xpixelstounits!)
    parent.openuserobject(sle, pixelstounits(10, xpixelstounits!), pixelstounits(22 * i, ypixelstounits!))
    i_myedits[i] = sle //keep our own reference
next

値アクセスの例:

//put that in another button clicked() event
SingleLineEdit sle
int i
string s_msg

for i = 1 to upperbound(i_myedits[])
    sle = i_myedits[i]
    if i > 1 then s_msg += "~r~n"
    s_msg += "edit #" + string(i) + " (" + sle.tag + ") says '" + sle.text + "'"
next
messagebox("Edits values", s_msg)

結果

ご覧のように、実用上の問題の 1 つは、 のようなコントロールの名前を作成してこれらのコントロールを参照できないことです"text"+2。代わりに、my 配列にアクセスするedits[]か、コントロールをループして、.tag特定の値に設定した場合はそれらのプロパティをテストする必要があります。

于 2014-08-24T10:39:25.990 に答える
0

私はそれが可能だとは思わない。回避策はおそらく配列である可能性があります。

Br. ガボール

于 2013-08-22T09:55:25.743 に答える
0

はい、猫の皮を剥ぐ方法は複数あります。

いくつかのプロパティがあるように聞こえるので、カスタムの非視覚的ユーザー オブジェクトの配列、または構造体の配列を使用します。それ以外の場合は、辞書オブジェクトなどの .NET フレームワークから何かを使用するか、外部データソースを使用して datawidnow を使用できます。ここでは、列名を col + ll_index.ToString() として参照できます。

簡単な例:

次のインスタンス変数とそれぞれの getter/setter 関数を使用してカスタム NVO を作成し、n_single_field という名前を付けます。

// add the properties and recommend getter and setter functions
public string myTag
public string myText
public int myTabOrder
...

// To USE the NVO define an unbounded array
n_single_field fields[]

// to process the populated fields
integer li_x, li_max_fields

// loop through field 1 through max using array index for field number
li_max_fields = upperbound(fields)
for li_x = 1 to li_max_fields
    fields[li_x].myTag = 'abc'
    fields[li_x].myText = 'text for field number ' + li_x.ToString()
    fields[li_x].myTabOrder = li_x * 10
next

単純化しすぎているのかもしれませんが、意志があれば必ず道は開けます。;)

于 2013-12-12T20:49:20.490 に答える
0

これを行うには 2 つの方法があると思いますが、期待していたほど簡単ではありません。

1. 制御配列

最初の方法は、コントロール配列 (ウィンドウ、タブ、およびユーザー オブジェクト) を通過することです。コントロール名を文字列として受け取る関数を作成してから、同じ関数をオーバーロードし、コントロール名と windowobject の配列を受け取る別の関数を作成します。文字列のみのメソッドは、文字列/配列メソッドを呼び出し、文字列を渡し、window.Control を 2 番目のパラメーターとして追加します。文字列/配列メソッドは配列を通過し、要素ごとに ClassDefinition を取得します。そこから名前を取り出し、文字列パラメーターと一致させたい方法で解析します (たとえば、w_test`tab_first`tabpage_first`cb_here の場合、cb_here を一致させますか、それとも tab_first`tabpage_first`cb_here?)。必要に応じて一致を処理します。タイプがタブまたはユーザー オブジェクトのコントロールを見つけたら、そのオブジェクトの Control 配列を使用して文字列/配列関数を再度呼び出します。成功/失敗のリターンを適切に処理します。

2.データウィンドウ

あなたが説明していることは、データウィンドウとその Describe() および Modify() 関数で非常にうまく機能します。これらの関数には文字列のみを渡すため、コントロール名だけでなく、文字列を作成する場合と同じように設定されている値も作成できます。実際、複数の Modify() 文字列を一緒に (スペースで区切って) 作成し、Modify() を 1 回呼び出すことができます。これは高速であるだけでなく、ウィンドウのちらつきや目に見えるアクティビティを減らします。

データがデータベースからのものではないので、データウィンドウを使用できないという考えに陥らないでください。外部データウィンドウを作成し、Constructor イベント中に 1 つの行を挿入して使用します。


ご想像のとおり、私はデータウィンドウ アプローチを強く支持します。パフォーマンスが向上するだけでなく、静的テキストだけでなく、より多くのコントロール タイプにタグを付けたい場合に、柔軟性が大幅に向上します。(コントロール タイプが 1 つの場合でも、いくつかのタイプ キャストを行う必要がありますが、複数のコントロール タイプを使用する場合は、すべてのタイプを処理するために CHOOSE CASE を開始する必要があります。)

幸運を、

テリー

于 2013-08-22T14:03:21.473 に答える