Get Dynamic-Field - Value

balta

Member
Hello,

I have this fields

It is possible to get the screen-value of fiels in a loop?

Thanks,
Baltazar

1621518293613.png
 

balta

Member
What you need?

I have 12 fields

txtReferencia1_1
txtReferencia2_1
txtReferencia3_1
etc

That I want to loop the values

Code:
do i = 1 to 3:

    messsage txtReferencia + string(i) + "_1":screen-value
             view-as alert-box.

end.

That don't work...

Can you help?
 

TomBascom

Curmudgeon
An actual runnable example is much more useful than isolated and incomplete snippets that don't work. For instance, show what you have that DOES work and then indicate with a comment where you would like some code to do something that you cannot figure out how to do.

The SCREEN-VALUE is an attribute of the UI widget showing the value in your window. It is not an attribute of a variable or a field. So you need some method of identifying that UI widget and returning a handle to it. One general purpose way to do that is to "walk the widget tree" looking for UI widgets that correspond to your data element (txtReferencia1_1 etc).

But the more we know about the actual code the more specific we can get. If the window is static and the UI elements convenient to access you could, potentially, skip a lot of steps and go right to the widget handle that you need.

But I cannot read your mind and I have no idea what your actual code looks like.
 

Osborne

Active Member
As Tom has explained:
The SCREEN-VALUE is an attribute of the UI widget showing the value in your window. It is not an attribute of a variable or a field. So you need some method of identifying that UI widget and returning a handle to it.
So you need to obtain the handle to the field, and again as Tom has posted "walking the widget tree" is the general solution.

Attached is a very old kbase that shows how to handle extent field screen values that you can adapt. Send the function the name of the variable - you will not require the index parameter (piElement) - and it will return the handle of the field which you can then read the screen value:
Code:
...
do i = 1 to 3:
   hField = getHdl(vhFstChildHdl,"txtReferencia" + string(i) + "_1").
   messsage hField:screen-value view-as alert-box.
end.
 

Attachments

  • How To avoid error 3565 when working with array widget's elements.txt
    2.1 KB · Views: 2

balta

Member
Hi @TomBascom and @Osborne,

What I want to do is "simple", read the values of field start with 'txtReferencia' (in another languages is straightforward), In Progress it isn't very easy.

I will try to do the "walking the widget tree", but I have thought that exists an easy solution.

What is in mind I have described here and send the info requested.

Thanks both for your help.
 

TomBascom

Curmudgeon
I know you think you’re asking for something simple but it remains very unclear.

“Read the values of a field” is not the same as obtaining the SCREEN-VALUE.

You have not sent the info requested. You still haven’t shown anything like enough of an example to understand what you are really trying to do and the words that you are using to describe your requirements are actually describing failed solutions to the unstated requirements. We just know that some broken snippets of code without any context don’t work.

If it is so straightforward in other languages perhaps you could post a functional example written in another language?
 

balta

Member
I think that I have give the information needed. I will try to be more clear (with examples) in future requests.

For me the value of field (fill-in) in Progress is screen-value.

Below an example in JS (JQuery)

I have an array and loop the fields in HTML (in this case I set the checkbox to false and clear and input).

Code:
// LIMPA ("RESET") | sobre TODOS
for (var i=0; i < arr_acabamentos_base.length; i++){

    id_acabamento = arr_acabamentos_base[i].id_acabamento;
    //
    $('#chkAcabamentoModal_' + id_acabamento).prop('checked',false);
    //
    $('#txtNrCoresModal_' + id_acabamento).val("");
    $('#txtNrCoresModal_' + id_acabamento).hide();
}

HTML/PHP

Code:
div class="checkbox abc-checkbox">
    <input data-bind="attr:{id: 'chkAcabamentoModal_' + id_acabamento,
        'data-id_acabamento': id_acabamento,
        'data-cores_acabamento': cores_acabamento},
        click: $root.click_acabamento"
        name="chkAcabamentos_Modal[]" class="styled" type="checkbox">
    <label data-bind="attr:{for: 'chkAcabamentoModal_' + id_acabamento}">
        <span data-bind="text: descr_acabamento_completa"></span>
    </label>
    <div data-bind="if: notas" style="display: inline-block">
        &nbsp;<i class="fas fa-info-circle" aria-hidden="true" data-bind="attr: {title: notas}"></i>
    </div>
</div>
 

TomBascom

Curmudgeon
Once again your examples are incomplete. They do not actually work when I try to run them.

None the less I will try to explain what I think is going on.

Unless I completely misunderstand it, in your code JavaScript/HTML you are working with dynamically named variables that you are creating on the fly.

Progress has no such capability. Variables must be explicitly declared at compile time with something like:
Code:
define variable myVariable_1 as integer no-undo.
define variable myVariable_2 as integer no-undo.
and so forth.

There is absolutely no way to create or reference variables dynamically and there are no handles to variables. So you cannot iterate over a collection of variables and extract the value. Thus a snippet of code like this:
Code:
do i = 1 to 3:

    messsage txtReferencia + string(i) + "_1":screen-value
             view-as alert-box.

end.
is nonsense in a Progress program.

In Progress you _could_ create objects with properties using NEW and have handles to those but that does not appear to be what you are trying to do.

Or a temp-table could also be created dynamically with dynamic field names and you could then obtain handles to those fields. But, again, you do not seem to be doing that.

Another difference between Progress and your examples has to do with how data is displayed. Progress moves data back and forth from variables and fields to "the screen buffer" and the elements on the screen are not the same widgets and handles as the variables or fields. A SCREEN-VALUE is an attribute of a widget that is contained in a FRAME and the FRAME is contained in a WINDOW. These relationships are the "widget tree" that we are referring to (there is potentially a lot more complexity to it than that but the high level perspective is as I describe). The SCREEN-VALUE can be changed completely independently of any change to a variable that might be related to that widget. It is almost always a mistake to think of the SCREEN-VALUE as the value of the widget.

Your first post shows a tiny fragment of a screen with one column that looks like it might be from a (temp-)table displaying 12 records. Your Javascript/HTML code appears to be re-setting a value in a similar column.

Let's just assume that we are working with the sports2000 database and that we are going to show the discount% for the first 12 customers:
Code:
define variable i as integer no-undo.

form
  customer.name customer.discount skip
 with
  frame a
  12 down
.

for each customer no-lock:

  display name discount with frame a.
  down with frame a.
  i = i + 1.
  if i >= 12 then leave.

end.

So far, so good? We have 12 lines with 2 columns.

If I assume that you want to set all of those discounts to 0 for some reason then the code might look like this:
Code:
define variable ok as logical no-undo.
define variable i  as integer no-undo.

form
  customer.name customer.discount skip
 with
  frame a
  12 down
.

/* review customer discounts
 */

do while true:

  i = 0.
  for each customer no-lock:

    display name discount with frame a.
    down with frame a.
    i = i + 1.
    if i >= 12 then leave.

  end.

  message "reset discounts?" view-as alert-box question buttons yes-no update ok.

  if ok = yes then
    do:
      i = 0.
      for each customer exclusive-lock:
        discount = 0.
        i = i + 1.
        if i >= 12 then leave.
      end.
      next.
    end.

  leave.

end.

Notice how I changed the value of the field in the table and then re-displayed the data? That's much, much easier than walking the widget tree, finding the proper widget and then changing the SCREEN-VALUE, then somehow copying the SCREEN-VALUE back to the appropriate records from the database. (Simply changing the SCREEN-VALUE will have no impact on the data persisted in the database.) But that assumes that I have correctly guessed something similar to whatever it is that you are trying to accomplish and my confidence in that guess is low.
 
Last edited:

balta

Member
Thanks for your long post.

I can to that in other languages (the example sent). I have sent you a dynamic example, but I could define 12 static fields and do the loop in JS.

In Progress, I have already "seen" that I cannot do this, in Progress I have to walk the widget tree (and for me that is "annoying"), I have to loop all fields to get in my case 12 fields (I have a lot of fields).

As I have referred, in following questions I will attach a program with my question to be more clear.

In your post you have referred this

"
Or a temp-table could also be created dynamically with dynamic field names, and you could then obtain handles to those fields. But, again, you do not seem to be doing that.
"

Do you have an example code to do that? I think that could work.

Once more, thanks for your help.
 
Top