FWH 18.08: Gets with loop variable as array subscript

FWH 18.08: Gets with loop variable as array subscript

Postby nageswaragunupudi » Thu Sep 27, 2018 6:26 am

There are occassions when we need to Get values of array elements like, aValue[ 1 ], aValue[ 2 ], ... , aValue[ n ]. If they are not many we can write code something like this:

Code-1: (Correct)
Code: Select all  Expand view

@  40, 20 SAY aPrompts[ 1 ] SIZE 80,24 PIXEL OF oDlg
@  40,110 GET aGets   [ 1 ] VAR aValues[ 1 ] SIZE 120,28 PIXEL OF oDlg
@  70, 20 SAY aPrompts[ 2 ] SIZE 80,24 PIXEL OF oDlg
@  70,110 GET aGets   [ 2 ] VAR aValues[ 2 ] SIZE 120,28 PIXEL OF oDlg
@ 100, 20 SAY aPrompts[ 3 ] SIZE 80,24 PIXEL OF oDlg
@ 100,110 GET aGets   [ 3 ] VAR aValues[ 3 ] SIZE 120,28 PIXEL OF oDlg
@ 130, 20 SAY aPrompts[ 4 ] SIZE 80,24 PIXEL OF oDlg
@ 130,110 GET aGets   [ 4 ] VAR aValues[ 4 ] SIZE 120,28 PIXEL OF oDlg
 


This works well.
But where there are many values, we would like to create the Says and Gets in a loop we may write code something like this:

Code-2: (Wrong)
Code: Select all  Expand view

   nRow     := 40
   for n := 1 to nLen
      @ nRow, 20 SAY aPrompts[ n ] SIZE 80,24 PIXEL OF oDlg
      @ nRow,110 GET aGets[ n ] VAR aValues[ n ] ;
         SIZE 120,28 PIXEL OF oDlg
      nRow  += 30
   next
 


But this does not work. We get a runtime error.

Reason: For every Get, its bSetGet codeblock is assigned with
{ |u| If( PCount() == 0, aValues[ n ], aValues[ n ] := u ) }.
During runtime this codeblock is evaluated with the value of 'n', which is always nLen+1 and array bound error occurs.

To overcome this problem, we need to create the Gets in a separate function using the concept of detatched locals. Here is a working sample using this principle.

Code-3: (Correct working sample)
Code: Select all  Expand view
#include "fivewin.ch"

function Main()

   local oDlg
   local aPrompts := { "First", "Second", "Third", "Fourth" }
   local aValues  := { Space( 10 ), Space( 10 ), Space( 10 ), Space( 10 ) }
   local aGets[ 4 ], n, nRow

   DEFINE DIALOG oDlg SIZE 400,250 PIXEL TRUEPIXEL

   nRow     := 40

   for n := 1 to 4
      @ nRow, 20 SAY aPrompts[ n ] SIZE 80,24 PIXEL OF oDlg
      aGets[ n ] := CreateGet( nRow, 110, aValues, n, oDlg )
      nRow  += 30
   next

   @ nRow, 20 BUTTON "Close" SIZE 100,30 PIXEL OF oDlg ACTION oDlg:End()

   ACTIVATE DIALOG oDlg CENTERED

   XBROWSER aValues // Ceck the values

return nil

function CreateGet( nRow, nCol, aArray, nEle, oDlg )

   local oGet

   @ nRow, nCol GET oGet VAR aArray[ nEle ] SIZE 120,24 PIXEL OF oDlg

return oGet
 


Enhacement in FWH 18.08:

It is no more necessary to create the Gets in a separate function. We can create the gets straight away in the loop iteslef in a single command. This is a working sample, using the new clause SUBSCTIPT:

Syntax:
@ r, c GET aArray SUBSCRIPT n // where n is the loop variable

Code-4: ( Correct FWH 18.08 )
Code: Select all  Expand view
#include "fivewin.ch"

function Main()

   local oDlg
   local aPrompts := { "First", "Second", "Third", "Fourth" }
   local aValues  := { Space( 10 ), Space( 10 ), Space( 10 ), Space( 10 ) }
   local aGets[ 4 ], n, nRow := 40

   DEFINE DIALOG oDlg SIZE 400,250 PIXEL TRUEPIXEL

   nRow     := 40
   for n := 1 to 4
      @ nRow, 20 SAY aPrompts[ n ] SIZE 80,24 PIXEL OF oDlg
      @ nRow,110 GET aGets[ n ] VAR aValues SUBSCRIPT n ;
         SIZE 120,28 PIXEL OF oDlg
      nRow  += 30
   next

   @ nRow, 20 BUTTON "Close" SIZE 100,30 PIXEL OF oDlg ACTION oDlg:End()

   ACTIVATE DIALOG oDlg CENTERED

   XBROWSER aValues

return nil
 


Let us now consider a bit more complex case of a multi dimentional array consisting of Prompts in the first column, variables in the second column and pictures in the third column. Here the get variable is aData[ n, 2 ] where n is the loop variable.

In this sample, let us also try using the recently introduced syntax:
@ r, c SAY ...GET ...

Code-5 (Working sample FWH 1808)
Code: Select all  Expand view

function ArrayGets

   local oDlg
   local aData    := { { "First  ",  Space( 10 ), nil         }, ;
                       { "Second ",  Space( 10 ), "@!"        }, ;
                       { "Third  ",  DATE(),      "@D"        }, ;
                       { "Fourth ",  0,           "99,999.99" }  }

   local aGets[ 4 ], n, nRow

   DEFINE DIALOG oDlg SIZE 400,250 PIXEL TRUEPIXEL

   nRow     := 40
   for n := 1 to 4

      @ nRow, 20 SAY aData[ n, 1 ] GET aGets[ n ] VAR aData SUBSCRIPT n, 2 ;
         PICTURE aData[ n, 3 ] SIZE 240,28 PIXEL OF oDlg

      nRow  += 30
   next

   @ nRow, 20 BUTTON "Close" SIZE 100,30 PIXEL OF oDlg ACTION oDlg:End()

   ACTIVATE DIALOG oDlg CENTERED

   XBROWSER aData // Check

return nil
 


This enhancement in FWH 1808 makes programming Gets of arrays using loop variables.

This new syntax is not applicable to gets from resources as such gets are not generally redefined in a loop.
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10295
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: FWH 18.08: Gets with loop variable as array subscript

Postby ellano » Thu Sep 27, 2018 9:09 am

Thanks for this improvement!

It will be marvelous if we can use it like this:

Code: Select all  Expand view
LOCAL n, nIDSay:=900, nIDGet:=600, nLen:=20

for n := 1 to nLen
    REDEFINE SAY oSay[n]              SUBSCRIPT n ID nIDSay IDSUBSCRIPT nIDSay OF oFld:aDialogs[1]   //Say, Get pair
    REDEFINE GET oGet[n] VAR aData[n] SUBSCRIPT n ID nIDGet IDSUBSCRIPT nIDGET OF oFld:aDialogs[1]
    nIDGet++
    nIDSay++
 next


May I suggest it as an enhancement on a future version?

Emiliano Llano Díaz
ellano
 
Posts: 107
Joined: Tue Sep 15, 2009 7:52 am

Re: FWH 18.08: Gets with loop variable as array subscript

Postby nageswaragunupudi » Thu Sep 27, 2018 10:05 am

We can consider extending this feature to resource also, if you think it will be useful.

Note: It is not "VAR aData[ n ] SUBSCRIPT n"
It should be "VAR aData SUBSCRIPT n"

There is no need for a subscript clause for SAYs
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10295
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: FWH 18.08: Gets with loop variable as array subscript

Postby ellano » Thu Sep 27, 2018 10:29 am

At least for me it will reduce my code from several dozen lines to a handful. :D
ellano
 
Posts: 107
Joined: Tue Sep 15, 2009 7:52 am

Re: FWH 18.08: Gets with loop variable as array subscript

Postby nageswaragunupudi » Thu Sep 27, 2018 10:46 am

Ok.
We will provide this in 18.08
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10295
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: FWH 18.08: Gets with loop variable as array subscript

Postby ellano » Sun Jan 27, 2019 6:34 pm

Could you please indicate me what I am doing wrong here?

Code: Select all  Expand view
nIDGet:=116
nLen:=62
FOR n := 47 TO nLen
    REDEFINE GET aPedg[n,2] SUBSCRIPT n ID nIDGet IDSUBSCRIPT nIDGET OF oFld:aDialogs[4] UPDATE READONLY FONT oFuente[2]
    nIDGet++
NEXT


I am trying to convert this to the new syntax:

Code: Select all  Expand view
REDEFINE GET aPedg[47,2] ID 116 OF oFld:aDialogs[4] UPDATE READONLY FONT oFuente[2]
REDEFINE GET aPedg[48,2] ID 117 OF oFld:aDialogs[4] UPDATE READONLY FONT oFuente[2]
REDEFINE GET aPedg[49,2] ID 118 OF oFld:aDialogs[4] UPDATE READONLY FONT oFuente[2]
REDEFINE GET aPedg[50,2] ID 119 OF oFld:aDialogs[4] UPDATE READONLY FONT oFuente[2]
REDEFINE GET aPedg[51,2] ID 120 OF oFld:aDialogs[4] UPDATE READONLY FONT oFuente[2]
...


Thanks
Emiliano Llano Díaz
ellano
 
Posts: 107
Joined: Tue Sep 15, 2009 7:52 am

Re: FWH 18.08: Gets with loop variable as array subscript

Postby nageswaragunupudi » Mon Jan 28, 2019 2:59 pm

Please try
Code: Select all  Expand view
nIDGet:=116
nLen:=62
FOR n := 47 TO nLen
    REDEFINE GET aPedg SUBSCRIPT n,2 ID nIDGet IDSUBSCRIPT nIDGET OF oFld:aDialogs[4] UPDATE READONLY FONT oFuente[2]
    nIDGet++
NEXT
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10295
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: FWH 18.08: Gets with loop variable as array subscript

Postby ellano » Mon Jan 28, 2019 3:29 pm

Mr. Rao:

Thanks for your answer.

I did try that combination (among another dozen ones that, of course, I do not remember) in despair but I got this enigmatic error:

.\prg\register.PRG(777) Error E0030 Syntax error "syntax error at 'GET'"

Same for this code:

Code: Select all  Expand view

* original:
*REDEFINE GET oGet[64] VAR aPedg[23,2] MEMO ID 108 OF oFld:aDialogs[4] UPDATE READONLY FONT oFuente[2]

nIDGet:=108
nLen  :=30
n     :=64

FOR nIDVar := 23 TO nLen
    REDEFINE GET oGet SUBSCRIPT n VAR aPedg SUBSCRIPT nIDVar,2 MEMO ID nIDGet IDSUBSCRIPT nIDGET OF oFld:aDialogs[4] UPDATE READONLY FONT oFuente[2]
    nIDGet++
    n++
NEXT
...

*Original
*REDEFINE GET aPedg[47,2] ID 116 OF oFld:aDialogs[4] UPDATE READONLY FONT oFuente[2]

nIDGet:=116
nLen:=62
FOR n := 47 TO nLen
    REDEFINE GET aPedg SUBSCRIPT n,2 ID nIDGet IDSUBSCRIPT nIDGET OF oFld:aDialogs[4] UPDATE READONLY FONT oFuente[2]
    nIDGet++
NEXT
 


FWH 18.10

Emiliano Llano Díaz
ellano
 
Posts: 107
Joined: Tue Sep 15, 2009 7:52 am

Re: FWH 18.08: Gets with loop variable as array subscript

Postby cnavarro » Mon Jan 28, 2019 5:04 pm

Emiliano, clause duplicate?


REDEFINE GET oGet SUBSCRIPT n VAR aPedg SUBSCRIPT nIDVar,2 MEMO ID nIDGet IDSUBSCRIPT nIDGET OF oFld:aDialogs[4] UPDATE READONLY FONT oFuente[2]
Cristobal Navarro
Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo
El secreto de la felicidad no está en hacer lo que te gusta, sino en que te guste lo que haces
User avatar
cnavarro
 
Posts: 6501
Joined: Wed Feb 15, 2012 8:25 pm
Location: España

Re: FWH 18.08: Gets with loop variable as array subscript

Postby ellano » Mon Jan 28, 2019 5:20 pm

Mr. Navarro:

Thanks for your concern.
Maybe in that one, but in the other one? (gives same cryptic error):

.\prg\register.PRG(783) Error E0030 Syntax error "syntax error at 'GET'"

Code: Select all  Expand view
* Original code
* REDEFINE GET aPedg[47,2] ID 116 OF oFld:aDialogs[4] UPDATE READONLY FONT oFuente[2]
nIDGet:=116
nLen:=62
FOR n := 47 TO nLen
    REDEFINE GET aPedg SUBSCRIPT n,2 ID nIDGet IDSUBSCRIPT nIDGET OF oFld:aDialogs[4] UPDATE READONLY FONT oFuente[2]
    nIDGet++
NEXT
ellano
 
Posts: 107
Joined: Tue Sep 15, 2009 7:52 am

Re: FWH 18.08: Gets with loop variable as array subscript

Postby cnavarro » Mon Jan 28, 2019 5:33 pm

Emiliano, try

REDEFINE GET aPedg SUBSCRIPT n,2 ID nIDGet OF oFld:aDialogs[4] UPDATE READONLY FONT oFuente[2]
Cristobal Navarro
Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo
El secreto de la felicidad no está en hacer lo que te gusta, sino en que te guste lo que haces
User avatar
cnavarro
 
Posts: 6501
Joined: Wed Feb 15, 2012 8:25 pm
Location: España

Re: FWH 18.08: Gets with loop variable as array subscript

Postby ellano » Tue Jan 29, 2019 11:10 am

Thanks. That make it work, but then the whole structure is useless since it attach all the GET array to one ID.

At least it narrows the error down to the IDSUBSCRIPT part that seems to be giving the problem (and error)

Emiliano Llano Díaz
ellano
 
Posts: 107
Joined: Tue Sep 15, 2009 7:52 am

Re: FWH 18.08: Gets with loop variable as array subscript

Postby cnavarro » Tue Jan 29, 2019 11:41 am

ellano wrote:Thanks. That make it work, but then the whole structure is useless since it attach all the GET array to one ID.

At least it narrows the error down to the IDSUBSCRIPT part that seems to be giving the problem (and error)

Emiliano Llano Díaz


Emiliano

Code: Select all  Expand view


FOR n := 47 TO nLen
    REDEFINE GET aPedg SUBSCRIPT n,2 ID nIDGet OF oFld:aDialogs[4] UPDATE READONLY FONT oFuente[2]
    nIDGet++
NEXT

 
Cristobal Navarro
Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo
El secreto de la felicidad no está en hacer lo que te gusta, sino en que te guste lo que haces
User avatar
cnavarro
 
Posts: 6501
Joined: Wed Feb 15, 2012 8:25 pm
Location: España

Re: FWH 18.08: Gets with loop variable as array subscript

Postby ellano » Tue Jan 29, 2019 2:46 pm

Thank you for your advice. We have now two cases:

Code: Select all  Expand view
* This one works:
nID:=116
FOR nIDGet := 47 TO 62
    REDEFINE GET aPedg SUBSCRIPT nIDGet,2 ID nID OF oFld:aDialogs[4] UPDATE READONLY FONT oFuente[2]
    nID++
NEXT

* This one, a little more complex, has an error E0030 on GET
nIDGet:=  64
nID   := 108
FOR nIDVar := 23 TO 30
    REDEFINE GET oGet[nIDGet] VAR aPedg SUBSCRIPT nIDVar,2 MEMO ID nID OF oFld:aDialogs[4] UPDATE READONLY FONT oFuente[2]
    nID++
    nIDGet++
NEXT
ellano
 
Posts: 107
Joined: Tue Sep 15, 2009 7:52 am

Re: FWH 18.08: Gets with loop variable as array subscript

Postby nageswaragunupudi » Tue Jan 29, 2019 3:34 pm

This is correct
Code: Select all  Expand view
nID:=116
FOR nIDGet := 47 TO 62
    REDEFINE GET aPedg SUBSCRIPT nIDGet,2 ID nID OF oFld:aDialogs[4] UPDATE READONLY FONT oFuente[2]
    nID++
NEXT
 
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10295
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Next

Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 32 guests