Error: 3565

Hi Everybody,
When i try using the variable subscript for array instead of using constant subscript Progress 4GL throws the below error;

Code Snippet:

DEFINE VARIABLE a AS INTEGER EXTENT 3 /* VIEW-AS FILL-IN */ NO-UNDO.

DEFINE FRAME f
a[1] NO-LABEL
a[2] NO-LABEL
a[3] NO-LABEL.

ON 'ENTRY':U OF a[2] IN FRAME f
DO:
MESSAGE SELF:INDEX
VIEW-AS ALERT-BOX INFO BUTTONS OK.
APPLY "TAB":U TO a[SELF:INDEX] IN FRAME f.
END.

ENABLE ALL WITH FRAME f.

WAIT-FOR CLOSE OF CURRENT-WINDOW.

Error:
Widget array-element requires constant subscript. (3565)
** Could not understand line 13. (196)

Explanation i got from help:
Widget array-element requires constant subscript. (3565)

Expression subscripts require on-the-fly mapping of the subscripted entity at run-time to a widget. That is only implemented for fill-ins when they are being used directly in a frame. It is not implemented for any widget at all within a widget:attribute phrase.

1) I guess the message from Progress says this has not been implemented for any widget except FILL-IN. I have tried for FILL-IN as well, i get the same error. I might be wrong in the way of usage. Correct me if i am wrong. Please provide me with an example if solved.
2) Is there an alternative method to achieve the goal?

Can someone help me out in this regard? Thanks in advance.
 
Are you trying to use a variable in the frame or in the trigger? And what is it that you expect a variable to do for you?

In any event the solution is fairly straight-forward. Don't use arrays. Use discrete data elements.
 
Hi Tom,
I do agree that the best practice is; a frame should contain discrete elements. In my project the guys have used such a logic. Its bit tough at this stage to change all the coding stuffs, so instead we are searching if we could get some solution to this scenario. It will be more helpful for us if you could provide a solution to this.

Scenario:

The thing is we have a frame with 3 contact fields and 3 email fields as below. The below frame has got 2 array variables (contact and email, extent 3).

contact1 email1
contact2 email2
contact3 email3

Here they have provided with a trigger on the last email field (email3)
and they have iterated through the array and checked for email validation. Consider, the email provided in the email2 field is wrong, then we need to make the user to move to that particular field (in our case it is email2).

So now this can be done using the following code snippet (...pseudo code);

DO i = 1 TO 10:
lError = pcheckBadEmail(email).
IF lError THEN
DO:
APPLY "ENTRY" TO email IN FRAME fContact. /** Error **/
RETURN NO-APPLY.
END.
END.


I hope the above code snippet would have made you to be in sync with our problem. Let me know if more information is required.

Thanks in advance.
 
Use a case statement and enumerate each of the target array elements to apply "entry" to. It's crude but it ought to work.
 
Hi Tom,
Ya Sure, thanks a lot for your suggestion. I do agree that its hard coding and this is not the way to code. For time being let me ask them to implement in this way and then during refactoring let me ask them to change the logic with discrete data elements in the frame.

Thanks for your quick response and valuable suggestion. :)
 
What I tend to do is to set up an array of widget-handles and assign each one of them before normal processing. That way I can access each display field using variables.You can even interrogate each one using a loop, so you can set SCREEN-VALUES, FORMAT, ROW, COL and all kinds of things very easily.

Code:
DEFINE VARIABLE wa AS WIDGET-HANDLE EXTENT 3    NO-UNDO.
ASSIGN wa[1] = a[1]:HANDLE IN FRAME f
       wa[2] = a[2]:HANDLE IN FRAME f
       wa[3] = a[3]:HANDLE IN FRAME f.
ON 'ENTRY':U OF wa[2] DO:
END.
 
This is one of those infuriating limitations. In the past I've used a solution a little different to sphipp.

Code:
function getRef returns widget-handle (index as int):
   case index:
      when 1 then return a[1]:handle in frame f.
      when 2 then return a[2]:handle in frame f
      when 3 then return a[3]:handle in frame f.
   end case.
end function.
If you have a large extent, you may want to remove the redundant code with the help of the preprocessor:
Code:
&scoped-define getRef1 when 1 then return a[
&scoped-define getRef2 ]:handle in frame f.

/*then something like this..*/
{&getRef1} 1 {&getRef2}
{&getRef1} 2 {&getRef2}
{&getRef1} 3 {&getRef2}
 
Back
Top