Сделать имя переменной, используя цикл и строку в PowerBuilder

Меня интересует, возможно ли сделать имя переменной в 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, и я смогу назначить для них значения. Дайте мне знать, если кто-нибудь преуспел, заранее спасибо

5 ответов

В вашем описании отсутствует определенная точность.

Если вы действительно хотите динамически создавать новые переменные как "переменная в подпрограмме powerscript или функции", это просто невозможно.

Если вместо этого вы хотите динамически создавать какие-либо новые элементы управления statictext или textedit объекты в окне или визуальном объекте userob, это возможно:

  1. используйте локальную переменную типа нового объекта, который вам нужно создать, например static text
  2. сделать его живым объектом (создать экземпляр) с create
  3. установить свойства объекта, что вам нужно
  4. "прикрепить" новый объект к его родителю (либо window или визуальный userobject - хоть какой-то graphicobject возможно с использованием win32api SetParent функция) с 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)

Результат

Как вы можете видеть, одна проблема практичности заключается в том, что вы не можете ссылаться на эти элементы управления, создавая имя элемента управления, как "text"+2, вместо этого вы должны получить доступ к моему edits[] массив или цикл через элементы управления и проверить их .tag свойство, если вы установите его на что-то конкретное.

Я видел бы два способа сделать это, но они не так просты, как кажется, что вы надеялись:

1. Контрольный массив

Первый способ заключается в том, чтобы пройти через массивы управления (на окнах, вкладках и пользовательских объектах). Я бы создал функцию, которая бы принимала имя элемента управления в виде строки, затем другую, которая перегружала бы ту же функцию и принимала имя элемента управления и массив оконных объектов. Метод только для строки будет просто вызывать метод строка / массив, пропуская строку и добавляя window.Control в качестве второго параметра. Метод string/array проходит через массив и для каждого элемента получает ClassDefinition. Извлеките из него имя и разберите его на части так, как вы хотите, чтобы оно соответствовало строковому параметру (например, для w_test`tab_first`tabpage_first`cb_here, хотите ли вы, чтобы cb_here соответствовал, или tab_first`tabpage_first`cb_here?). Разобраться со спичками по мере необходимости. Когда вы найдете элемент управления типа tab или пользовательский объект, снова вызовите функцию string/array с массивом Control из этого объекта; иметь дело с успехом / неудачей возвращается в зависимости от обстоятельств.

2. Окно данных

То, что вы описываете, прекрасно работает с DataWindows и их функциями Describe() и Modify(). Поскольку вы передаете этим функциям только строку, вы можете создавать не только имена элементов управления, но и значения, для которых они установлены, как если бы вы строили любую строку. Фактически, вы можете собрать несколько строк Modify() вместе (разделенных пробелом) и сделать один вызов Modify(); это не только быстрее, но и уменьшает мерцание окон и видимую активность.

Не думайте, что, поскольку ваши данные не из базы данных, вы не можете использовать DataWindow. Создайте внешнее окно DataWindow и просто используйте его с одной строкой, вставленной во время события Constructor.


Как вы можете догадаться, я бы решительно поддержал подход DataWindow. Мало того, что он будет работать лучше, но он обеспечит гораздо большую гибкость, когда вы хотите двигаться дальше и отмечать больше типов элементов управления, чем просто статический текст. (Вам придется выполнять приведение типов даже с одним типом элемента управления, но если вы хотите получить кратные значения, вам нужно запустить CHOOSE CASE для обработки всех ваших типов.)

Удачи,

Терри

Вы не можете создать имя переменной в скрипте, потому что переменные должны быть объявлены, прежде чем вы сможете их использовать. С PBNI можно сгенерировать имя так, как вы его описываете, а затем получить ссылку на переменную с таким именем, которая уже существует, но я не думаю, что это то, что вам нужно. Если вы хотите отслеживать дополнительные свойства для своих элементов управления, просто унаследуйте новый пользовательский объект от того, чем он является (sle, mle и т. Д.), И добавьте нужные свойства. Затем вы можете разместить свой пользовательский объект в окне и использовать свойства. Другой подход заключается в использовании свойства Tag элемента управления. Он содержит строку, в которую вы можете поместить все, что хотите. PFC использует эту технику. Терри DataWindow решение является хорошим подходом для хранения произвольных данных.

Я не думаю, что это возможно. Обходной путь может быть массивом, может быть.

Br. Габор

Да, и существует более одного способа кожи кошки.

Похоже, у вас есть несколько свойств, поэтому я бы использовал массив пользовательских невизуальных пользовательских объектов или массив структур. В противном случае вы, вероятно, могли бы использовать что-то из.NET Framework, например объект словаря или что-то в этом роде, или данные, использующие внешний источник данных, где вы можете ссылаться на имена столбцов как col + ll_index.ToString().

ПРОСТОЙ Пример:

Создайте собственный NVO со следующими переменными экземпляра, плюс функции getter/setter для каждого, назовите его 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

Может быть, я упрощаю, если да, дайте мне знать, если есть желание, всегда есть способ.;)

Другие вопросы по тегам