Quote:
>Posted for: Kelli Buccelli, ARS
>Summary:
>Need a way for the after row /next field statement in an input
>array to return to the same row instead of moving to the next row.
>Problem:
>In a 4GL program input array, we are using the after row statement
>to test if all the values are correct. The row contains 4 numbers
>one or more of which must be greater then 0. All four cannot be 0.
>If all four are 0 we want to go the the first field on the row and
>prompt the user to re-enter a valid row. The problem is that the
>next field statement in an after row statement goes to the next
>field on the next row leaving a row of incorrect values. The following
>is an example 4gl program, screen and sql. This problem has been
>tested with 4GL 4.0, 4.1, 1.1 and RDS 4.1. We have a workaround
>using the after field statement and duplicating a lot of code.
>Any suggestion on how to do it with the after row statement?
The "common" approach to this is to add a NOENTRY field in the perform
screen as the last field of the screen record, Put the INPUT ARRAY
statement in a WHILE loop, and keep a counter so that when we want to
go back a row we can EXIT INPUT, loop back up, reenter INPUT ARRAY, and
then use NEXT FIELD to the NOENTRY field to go down to the desired row.
I added to your code below for an example:
Quote:
>-------cut here rowtest.4gl -------
>## After Row test:
># Need a way in 4GL to return to the same row if the whole row
># does not meet some input requirement. The following is
># an example where a row is 4 numbers and on of the four numbers
># must be > 0. Currently the after row clause to check this
># moves on the the next row.
>database rowtest
>main
# CHANGE TO BELOW >define p_f1 array[50] of record like f1.*,
DEFINE p_f1 ARRAY[50] OF RECORD
col1 LIKE f1.col1,
col2 LIKE f1.col2,
col3 LIKE f1.col3,
col4 LIKE f1.col4,
ne CHAR(1) # NOENTRY field
END RECORD,
arrg SMALLINT, # Our "go to row" counter
act SMALLINT, # hold the value of arr_count()
Quote:
> p_rec int,
> s_rec int
>open window win1 at 5,5
> with form "rowtest" attribute (border )
LET act = 0
LET arrg = 1
WHILE arrg > 0
# CHANGE TO BELOW >call set_count(0)
CALL set_count(act)
# CHANGE TO BELOW >input array p_f1 from s_f1.*
input array p_f1 WITHOUT DEFAULTS from s_f1.*
Quote:
> before row
> let p_rec = arr_curr()
> let s_rec = scr_line()
IF arrg > p_rec THEN
# we want to go lower in the array,
# so go to the NOENTRY field
NEXT FIELD ne
END IF
# reset arrg if we're going into this row
LET arrg = 0
# below not required, but recommended
NEXT FIELD col1
Quote:
> error "Before Row p_rec = ",p_rec, " s_rec = ", s_rec
> after row
LET act = arr_count()
# NOT NEEDED > let p_rec = arr_curr()
# NOT NEEDED > let s_rec = scr_line()
Quote:
> if ( p_f1[p_rec].col1 = 0 and p_f1[p_rec].col2 = 0
> and p_f1[p_rec].col3 = 0 and p_f1[p_rec].col4 = 0 ) then
> error "Invalid Row one entry must be > 0"
# CHANGE TO BELOW > next field col1
LET arrg = p_rec
EXIT INPUT
Quote:
> ################################################
> # this is the problem. the program executes this
> # statement and goes to col1 on the next row
> ################################################
> end if
> error "After Row p_rec = ",p_rec, " s_rec = ", s_rec
> sleep 2
>end input
# since we reset arrg on each row we enter, exiting with ACCEPT or
# INTERRUPT will cause use to exit the WHILE loop
END WHILE # arrg > 0
Quote:
>end main
>------------cut here rowtest.per ------------------
>database rowtest
>screen size 24 by 80
>{
> After Row test Table
>[f000 ] [f001 ] [f002 ] [f003 ][a]
>[f000 ] [f001 ] [f002 ] [f003 ][a]
>[f000 ] [f001 ] [f002 ] [f003 ][a]
>[f000 ] [f001 ] [f002 ] [f003 ][a]
>[f000 ] [f001 ] [f002 ] [f003 ][a]
>[f000 ] [f001 ] [f002 ] [f003 ][a]
>[f000 ] [f001 ] [f002 ] [f003 ][a]
>[f000 ] [f001 ] [f002 ] [f003 ][a]
>[f000 ] [f001 ] [f002 ] [f003 ][a]
>[f000 ] [f001 ] [f002 ] [f003 ][a]
>}
>end
{* I added field a to the screen form ------------------^^^ *}
Quote:
>tables
>f1
>attributes
>f000 = f1.col1;
>f001 = f1.col2;
>f002 = f1.col3;
>f003 = f1.col4;
a = FORMONLY.ne TYPE CHAR, NOENTRY;
Quote:
>end
>instructions
{* BELOW NOT REQUIRED, BUT RECOMMENDED *}
DELIMITERS " "
{*
IF DELIMITERS LINE IS ADDED, WE CAN CHANGE THE SCREEN TO BELOW:
[f000 ] [f001 ] [f002 ] [f003 |a]
[f000 ] [f001 ] [f002 ] [f003 |a]
[f000 ] [f001 ] [f002 ] [f003 |a]
[f000 ] [f001 ] [f002 ] [f003 |a]
[f000 ] [f001 ] [f002 ] [f003 |a]
[f000 ] [f001 ] [f002 ] [f003 |a]
[f000 ] [f001 ] [f002 ] [f003 |a]
[f000 ] [f001 ] [f002 ] [f003 |a]
[f000 ] [f001 ] [f002 ] [f003 |a]
[f000 ] [f001 ] [f002 ] [f003 |a]
*}
{* CHANGE TO BELOW >screen record s_f1[10] ( f1.* ) *}
SCREEN RECORD s_f1[10] (col1, col2, col3, col4, ne)
Quote:
>end
>-----cut here rowtest.sql -------
>create database rowtest;
>create table f1
> (
> col1 integer,
> col2 integer,
> col3 integer,
> col4 integer
> );
>------------end --------------------
================
Dennis J. Pimple
Informix CSE / Denver