【问题标题】:Make variable name using loop and string in PowerBuilder在 PowerBuilder 中使用循环和字符串创建变量名
【发布时间】:2013-08-22 09:09:24
【问题描述】:

如果可以使用循环和字符串在 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 并且我可以为它们赋值。如果有人成功,请告诉我,提前谢谢

【问题讨论】:

    标签: loops powerbuilder variable-names


    【解决方案1】:

    您的描述缺乏术语精确度。

    如果您真的想动态地创建新的变量作为“powerscript 子例程或函数中的变量”,这简直是不可能

    如果您想在窗口或可视用户对象中动态创建一些新的控件静态文本或文本编辑对象这是可能的

    1. 使用您需要创建的新对象类型的局部变量,例如static text
    2. 使用create 使其成为活动对象(实例化)
    3. 根据需要设置对象属性
    4. 使用OpenUserObject() 方法将新对象“附加”到其父对象(window 或视觉userobject - 尽管使用win32api SetParent 函数可以使用任何graphicobject)。请注意,您不能简单地将其直接添加到父级的 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如果您将其设置为特定的属性。

    【讨论】:

      【解决方案2】:

      我认为这是不可能的。解决方法可能是一个数组。

      兄弟。加博尔

      【讨论】:

      • 这会很复杂。因为它可以是 text1.tag、text1.visible、text1.enabled,即使我可以定义二维数组,但这会使代码更加复杂..
      • 我不明白为什么它更复杂。您可以定义一个具有必要属性的非可视用户对象和来自该 uo 的数组。
      • 同意,这将是一个简单的解决方案。如果您需要许多属性,则只需创建一个 NVO OR 结构,然后 ant 设置一个数组,如下所示:我将在下面的答案中举一个示例..
      【解决方案3】:

      我会看到两种方法来做到这一点,但它们并不像您希望的那样简单:

      1。控制数组

      第一种方法是遍历控件数组(在窗口、选项卡和用户对象上)。我将创建一个将控件名称作为字符串的函数,然后创建另一个重载相同函数并获取控件名称和窗口对象数组的函数。纯字符串方法只会调用字符串/数组方法,传递字符串并添加 window.Control 作为第二个参数。字符串/数组方法将遍历数组,并为每个元素获取 ClassDefinition。从中提取名称,并按照您希望它匹配字符串参数的方式对其进行解析(例如,对于 w_test`tab_first`tabpage_first`cb_here,您希望 cb_here 匹配,还是 tab_first`tabpage_first`cb_here?)。酌情处理比赛。当您找到选项卡或用户对象类型的控件时,使用该对象中的控件数组再次调用字符串/数组函数;酌情处理成功/失败返回。

      2。数据窗口

      您所描述的内容非常适用于 DataWindows,以及它们的 Describe() 和 Modify() 函数。由于您只向这些函数传递一个字符串,因此您不仅可以构建控件名称,还可以构建它们设置的值,就像构建任何字符串一样。实际上,您可以一起构建多个 Modify() 字符串(由空格分隔)并调用 Modify();这不仅更快,而且减少了窗口闪烁和可见活动。

      不要陷入这样的想法,因为您的数据不是来自数据库,所以您不能使用 DataWindow。创建一个外部 DataWindow,并在 Constructor 事件期间插入一行来简单地使用它。


      正如您可能猜到的,我强烈支持 DataWindow 方法。它不仅会表现得更好,而且当您想要继续并标记更多控件类型时,它会提供更多的灵活性,而不仅仅是静态文本。 (即使使用一种控件类型,您也必须进行一些类型转换,但如果您想进入多个类型,则需要启动一个 CHOOSE CASE 来处理您的所有类型。)

      祝你好运,

      特里

      【讨论】:

        【解决方案4】:

        您不能在脚本中创建变量名,因为必须先声明变量才能使用它们。使用 PBNI,可以按照您描述的方式生成名称,然后获取对该名称的变量的引用,该变量已经存在,但我认为这不是您想要的。如果您想跟踪控件的其他属性,只需从任何对象(sle、mle 等)继承一个新的用户对象并添加您想要的属性。然后您可以将您的用户对象放在窗口上并使用属性。另一种方法是使用控件的 Tag 属性。它包含一个字符串,您可以将任何内容放入其中。PFC 使用这种技术。 Terry 的 DataWindow 解决方案是存储任意数据的好方法。

        【讨论】:

          【解决方案5】:

          是的,而且有不止一种方法可以给猫剥皮。

          听起来您有几个属性,所以我会使用一组自定义非可视用户对象或一组结构。否则,您可能会使用 .NET 框架中的某些东西,例如字典对象或类似的东西,或者使用外部数据源的 datawidnow,您可以将列名称为 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
          

          如果是这样让我知道,也许我过于简单化了,如果有意愿,总会有办法。 ;)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2019-01-04
            • 2012-06-06
            • 2013-04-12
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多