Grid Validation

General development discussion.

Moderators: Susan Smith, admin, Gabriel

Post Reply
mluchterhand
Posts: 52
Joined: Mon Jun 08, 2009 7:28 pm
Location: Des Moines, IA
Contact:

Grid Validation

Post by mluchterhand »

Hi,

Sorry if this is a dumb question but I'm very new to grids. I have successfully created a grid that accepts input and is properly reading changes back into the proper arrays (thanks to the BR Wiki). However, my problem is that I need to validate most of the entered data and I'm not sure how to do that. I would prefer to do this while the user is entering the data either by cell or row. I am not sure where to put the validation code or what specific commands to use honestly. I would greatly appreciate any feedback. Here is my code:

06500 PRINT FIELDS "4,1,grid 19/80,headers": (MAT HEADINGS$,MAT WIDTHS,MAT FORMS$)
06600 PRINT FIELDS "4,1,grid 19/80,=": (MAT DIV$,MAT ACCT$,MAT DEBIT,MAT CREDIT,MAT DESC$)
06700 INPUT FIELDS "4,1,GRID 19/80,ROWCNT,CHG": ROWS ! # of changed rows
06800 MAT SUBSCR(ROWS)
06900 INPUT FIELDS "4,1,GRID 19/80,ROWSUB,CHG,NOWAIT": MAT SUBSCR ! read subscripts
07000 MAT DIV$(ROWS) : MAT ACCT$(ROWS) : MAT DEBIT(ROWS) : MAT CREDIT(ROWS) : MAT DESC$(ROWS) ! redimension
07100 INPUT FIELDS "4,1,GRID 19/80,ROW,CHG,NOWAIT": (MAT DIV$, MAT ACCT$,MAT DEBIT, MAT CREDIT, MAT DESC$) ! read changed rows

I'm using BR 4.31fb.

Thanks in advance.
Thanks - Matt Luchterhand
Gabriel
Posts: 412
Joined: Sun Aug 10, 2008 7:37 am
Location: Arlington, TX
Contact:

Re: Grid Validation

Post by Gabriel »

It sounds like you're gonna want some kind of a loop to read the grid and do validations.

To start with, it might be easier to package your input statements up into separate functions. This will make the logic easier to follow.

I'm going to remove the line numbers from your code, because its easier to follow without line numbers. But just add line numbers back in when you put it in your program.

Step 1: Turn it into Functions

Code: Select all

def fnPrintListview(mat Div$, mat Accts,mat Debit,mat Credit,mat Desc$)
   PRINT FIELDS "4,1,grid 19/80,headers": (MAT HEADINGS$,MAT WIDTHS,MAT FORMS$)
   PRINT FIELDS "4,1,grid 19/80,=": (MAT DIV$,MAT ACCT$,MAT DEBIT,MAT CREDIT,MAT DESC$)
fnend

def fnInputListview(mat Div$, mat Accts,mat Debit,mat Credit,mat Desc$;___,Rows)
   INPUT FIELDS "4,1,GRID 19/80,ROWCNT,CHG": ROWS ! # of changed rows
   MAT SUBSCR(ROWS)
   INPUT FIELDS "4,1,GRID 19/80,ROWSUB,CHG,NOWAIT": MAT SUBSCR ! read subscripts
   MAT DIV$(ROWS) : MAT ACCT$(ROWS) : MAT DEBIT(ROWS) : MAT CREDIT(ROWS) : MAT DESC$(ROWS) ! redimension
   INPUT FIELDS "4,1,GRID 19/80,ROW,CHG,NOWAIT": (MAT DIV$, MAT ACCT$,MAT DEBIT, MAT CREDIT, MAT DESC$) ! read changed rows 
fnend
Step 2: Call those functions:

Code: Select all

   let fnPrintListview(mat Div$, mat Accts,mat Debit,mat Credit,mat Desc$)
   let fnInputListview(mat Div$, mat Accts,mat Debit,mat Credit,mat Desc$)
At this point you have something that does the same thing as before, but might be a little easier to follow.

Step 3: Add a DO loop so you can do your validations

Code: Select all

let fnPrintListview(mat Div$, mat Accts,mat Debit,mat Credit,mat Desc$)
Do
   let fnInputListview(mat Div$, mat Accts,mat Debit,mat Credit,mat Desc$)
   ! Validate stuff here

   ! If something changed during validation, then
   ! let fnPrintListview(mat Div$, mat Accts,mat Debit,mat Credit,mat Desc$)
   ! end if
   
loop until fkey=SaveButton
Its important to realize, the above code is PseudoCode, was written in here, and hasn't been tested. I'm just trying to explain the logical processess you'll need to follow in order to get what you want done.

You didn't give enough information for me to show you the actual code that does what you want. So here's the general idea.


You'll need to make a way to exit your listview, so that you can exit the DO loop when you get there. You could add a Save button, or decide that the Enter key is what finished their entering stuff in the list. You'll also need to add the "X" attribute to each of the columns. You do this by adding ",X" to the Form Spec$ for the column. So, in your example above, if your mat Forms$(1) was "CC 20" then you would make it "CC 20,X" instead. This will cause it to interrupt the input fields and let you do validations, any time something changes in one of those columns.

Then, you basically, do your validations (check the data, make sure its correct) and then either exit the loop (if they clicked the Save button) or reprint the data and go back up to try again (if they didn't click the save button, but instead the validations were triggered by them changing something in a column that had an X attribute).

Write back with more specific details and we'll try to help you further.

Gabriel
Gabriel
Posts: 412
Joined: Sun Aug 10, 2008 7:37 am
Location: Arlington, TX
Contact:

Re: Grid Validation

Post by Gabriel »

Also, I really hope we get our forum working again soon. This is such a disaster - I didn't even notice you wrote until now. And now I realize you wrote your question two weeks ago.
mluchterhand
Posts: 52
Joined: Mon Jun 08, 2009 7:28 pm
Location: Des Moines, IA
Contact:

Re: Grid Validation

Post by mluchterhand »

Gabriel, I have had some time to work on this program again. I have made the changes you suggested and it is definitely much easier to work with. Thank you for that. However, I am still unsure of how to validate the data properly. I have tried validating several ways and I almost always end up with a 122 error (illegal array element). Here is my full code:

Code: Select all

! Dimension Arrays
DIM HEADINGS$(5), WIDTHS(5), FORMS$(5), SUBSCR(500)
LET HEADINGS$(1)="Branch": LET HEADINGS$(2)="Acct": LET HEADINGS$(3)="Debit": LET HEADINGS$(4)="Credit": LET HEADINGS$(5)="Description"
LET WIDTHS(1)=7: LET WIDTHS(2)=7: LET WIDTHS(3)=15: LET WIDTHS(4)=15: LET WIDTHS(5)=30
LET FORMS$(1)="cc 3,X": LET FORMS$(2)="cc 4,X": LET FORMS$(3)="nz 10.2,X": LET FORMS$(4)="nz 10.2,X": LET FORMS$(5)="cc 15,X"
DIM DIV$(500)*3, ACCT$(500)*4, DEBIT(500), CREDIT(500),DESC$(500)*15
!
PRINT FIELDS "24,76,CC 4,,b20": "Save"
LET FNPRINTLISTVIEW(MAT DIV$,MAT ACCTS,MAT DEBIT,MAT CREDIT,MAT DESC$)
DO
  LET FNINPUTLISTVIEW(MAT DIV$,MAT ACCTS,MAT DEBIT,MAT CREDIT,MAT DESC$)
  ! Validate stuff here
  ! If Branch is greater than 32 then print in red and make user fix
  ! 
  ! If Account is not 4 digits then print in red and make user fix
  !
  ! If something changed during validation, then
  ! let fnPrintListview(mat Div$, mat Accts,mat Debit,mat Credit,mat Desc$)
  ! end if
!
LOOP UNTIL FKEY=20
!
DEF FNPRINTLISTVIEW(MAT DIV$, MAT ACCTS,MAT DEBIT,MAT CREDIT,MAT DESC$)
  PRINT FIELDS "4,1,grid 19/80,headers": (MAT HEADINGS$,MAT WIDTHS,MAT FORMS$)
  PRINT FIELDS "4,1,grid 19/80,=": (MAT DIV$,MAT ACCT$,MAT DEBIT,MAT CREDIT,MAT DESC$)
FNEND
!
DEF FNINPUTLISTVIEW(MAT DIV$, MAT ACCTS,MAT DEBIT,MAT CREDIT,MAT DESC$;___,ROWS)
  INPUT FIELDS "4,1,GRID 19/80,ROWCNT,CHG": ROWS ! # of changed rows
  MAT SUBSCR(ROWS)
  INPUT FIELDS "4,1,GRID 19/80,ROWSUB,CHG,NOWAIT": MAT SUBSCR ! read subscripts
  MAT DIV$(ROWS) : MAT ACCT$(ROWS) : MAT DEBIT(ROWS) : MAT CREDIT(ROWS) : MAT DESC$(ROWS) ! redimension
  INPUT FIELDS "4,1,GRID 19/80,ROW,CHG,NOWAIT": (MAT DIV$, MAT ACCT$,MAT DEBIT, MAT CREDIT, MAT DESC$) ! read changed rows
FNEND
As you may be able to tell from the code, a sample validation I would like to do is ensure that the branch (DIV$) value is less than 32. Another validation I would like is to ensure that ACCTS is always 4 digits.
Thanks - Matt Luchterhand
Gabriel
Posts: 412
Joined: Sun Aug 10, 2008 7:37 am
Location: Arlington, TX
Contact:

Re: Grid Validation

Post by Gabriel »

Matt,

You're asking two questions here.

1) How to do validations.
2) How to print stuff in red.

I'm going to address question 1 and when you get that working, post more on here and we'll address question 2.

But first, a couple of notes:

a) You didn't tell me what line gives you the error 122, and it looks like you removed your validation code before sending it to me. If in the future you include the code that's actually getting the error, and tell me which line gets the error, that will help me to understand whats going on.

b) I noticed you're dimensioning all the arrays for reading to something large (500). It won't hurt if you do, but you don't need to do that because they're re-sized using the MAT command prior to using them. So you can dimension them to anything you want. In your sample code, I changed it to (1) so that the program doesn't use more memory then it needs.

Now, lets address question 1, and once we get that working, we can address question 2.

Since I couldn't see what you were trying, I wanted to start with a simple example. (I'll address the changing it to red thing in another email but first, lets get this working).

Code: Select all

  let SomethingChanged=0
  for index=1 to udim(mat Div$)
     ! If Branch is greater than 32 then print in red and make user fix
     let Number=-999999
     let Number=val(Div$(Index)) conv Ignore
     if Number<=0 then
        let Div$(Index)="1"
        let SomethingChanged=1
     end if
     if Number>=32 then
        let Div$(Index)="32"
        let SomethingChanged=1
     end if
     ! or print in red

     ! If Account is not 4 digits then print in red and make user fix
     if len(trim$(Acct$(Index)))><4 then
        ! its an error, change to blank or print in red or something
        let Acct$(Index)=""
        let SomethingChanged=1
     end if
  next Index

  If SomethingChanged then
     let fnPrintListview(mat Div$, mat Accts,mat Debit,mat Credit,mat Desc$)
  end if
So, we use a For Next loop to loop through the data. Then we test each value and if its a problem, we set it to something that works.


Now, here's the code all together, so you can see how the whole routine goes together.

Code: Select all

! Dimension Arrays
DIM HEADINGS$(5), WIDTHS(5), FORMS$(5), SUBSCR(1)
LET HEADINGS$(1)="Branch": LET HEADINGS$(2)="Acct": LET HEADINGS$(3)="Debit": LET HEADINGS$(4)="Credit": LET HEADINGS$(5)="Description"
LET WIDTHS(1)=7: LET WIDTHS(2)=7: LET WIDTHS(3)=15: LET WIDTHS(4)=15: LET WIDTHS(5)=30
LET FORMS$(1)="cc 3,X": LET FORMS$(2)="cc 4,X": LET FORMS$(3)="nz 10.2,X": LET FORMS$(4)="nz 10.2,X": LET FORMS$(5)="cc 15,X"
DIM DIV$(1)*3, ACCT$(1)*4, DEBIT(1), CREDIT(1),DESC$(1)*15
!
PRINT FIELDS "24,76,CC 4,,b20": "Save"
LET FNPRINTLISTVIEW(MAT DIV$,MAT ACCTS,MAT DEBIT,MAT CREDIT,MAT DESC$)
DO
  LET FNINPUTLISTVIEW(MAT DIV$,MAT ACCTS,MAT DEBIT,MAT CREDIT,MAT DESC$)
  ! Validate stuff here

  let SomethingChanged=0
  for index=1 to udim(mat Div$)
     ! If Branch is greater than 32 then print in red and make user fix
     let Number=-999999
     let Number=val(Div$(Index)) conv Ignore
     if Number<=0 then
        let Div$(Index)="1"
        let SomethingChanged=1
     end if
     if Number>=32 then
        let Div$(Index)="32"
        let SomethingChanged=1
     end if
     ! or print in red

     ! If Account is not 4 digits then print in red and make user fix
     if len(trim$(Acct$(Index)))><4 then
        ! its an error, change to blank or print in red or something
        let Acct$(Index)=""
        let SomethingChanged=1
     end if
  next Index

  If SomethingChanged then
     let fnPrintListview(mat Div$, mat Accts,mat Debit,mat Credit,mat Desc$)
  end if
  !
LOOP UNTIL FKEY=20
!
DEF FNPRINTLISTVIEW(MAT DIV$, MAT ACCTS,MAT DEBIT,MAT CREDIT,MAT DESC$)
  PRINT FIELDS "4,1,grid 19/80,headers": (MAT HEADINGS$,MAT WIDTHS,MAT FORMS$)
  PRINT FIELDS "4,1,grid 19/80,=": (MAT DIV$,MAT ACCT$,MAT DEBIT,MAT CREDIT,MAT DESC$)
FNEND
!
DEF FNINPUTLISTVIEW(MAT DIV$, MAT ACCTS,MAT DEBIT,MAT CREDIT,MAT DESC$;___,ROWS)
  INPUT FIELDS "4,1,GRID 19/80,ROWCNT,CHG": ROWS ! # of changed rows
  MAT SUBSCR(ROWS)
  INPUT FIELDS "4,1,GRID 19/80,ROWSUB,CHG,NOWAIT": MAT SUBSCR ! read subscripts
  MAT DIV$(ROWS) : MAT ACCT$(ROWS) : MAT DEBIT(ROWS) : MAT CREDIT(ROWS) : MAT DESC$(ROWS) ! redimension
  INPUT FIELDS "4,1,GRID 19/80,ROW,CHG,NOWAIT": (MAT DIV$, MAT ACCT$,MAT DEBIT, MAT CREDIT, MAT DESC$) ! read changed rows
FNEND
Gabriel
Post Reply