Сделать имя переменной, используя цикл и строку в 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, это возможно:
- используйте локальную переменную типа нового объекта, который вам нужно создать, например
static text
- сделать его живым объектом (создать экземпляр) с
create
- установить свойства объекта, что вам нужно
- "прикрепить" новый объект к его родителю (либо
window
или визуальныйuserobject
- хоть какой-тоgraphicobject
возможно с использованием win32apiSetParent
функция) сOpenUserObject()
метод. Обратите внимание, что вы не можете просто добавить его непосредственно к родителюControl[]
массив. - Вы также можете сохранить объект в своем собственном массиве для последующего удобного доступа к созданным объектам вместо того, чтобы зацикливаться на
Control[]
массив - как только объект прикреплен к его родителю, вы можете повторно использовать локальную переменную для создания другой
Вот пример:
//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
Может быть, я упрощаю, если да, дайте мне знать, если есть желание, всегда есть способ.;)