You are here:

FoxPro/Cancel Validate

Advertisement


Question
QUESTION: Hello,

I am running a program (.spr) in which I am saying like this :

abc=0
nn=space(30)
@5,5 say 'Enter Value:-' get abc valid myval(abc)
@6,5 say 'Enter Name :-' get nn
@.... some more fields
@.... push buttons
read cycle

In above push buttons I have add,edit,next,previous,delete etc.

Now, suppose I ran the program and I am going to add new record, it will prompt the value of abc.  As I goes to add new record, all push buttons get disabled and only save and cancel button remains activated (as it happens when we creates a screen and generate .spr file)  Now if user clicks on cancel button, it do not terminates the read and goes into myval function to check the value of abc variable.

I need that if user clicks on cancel button, it should not validate the abc variable and should terminate the read.

function myval
parameter xy
if !between(xy,3,4)
wait wind "Invalid Values" Nowait
endif
return


Even I tried by saying if !between(xy,3,4) and mrow() <> 22 (the row position of push buttons), it worked but problem is next time it accepts the values in abc variable out of 3 and 4 too, because it do not change the mouse row.

Kindly help me and let me know, if I am unclear in my request.

Thanks and Regards
Girish Sharma

ANSWER: Hi,

This may be a single issue or a combination of two different problems.   

1.  VALIDATION OF ABC

   If the code shown for your MYVAL function is identical to what is being used, it will not prevent invalid entries.  It will warn the user with the WAIT WINDOW, but it won't prevent the data from being kept and potentially stored later.   Within a function, a RETURN defaults to RETURN .T. unless .F. is specified.  If you want to totally prevent the field from containing invalid data:

    function myval
    parameter xy
    if !between(xy,3,4)
       wait window alltrim(str(xy)) + " is an invalid value" Nowait
       return .F.    
       * Returning .F. prevents the user from leaving the field while it contains invalid data
    endif
    * If it gets this far, it passed the IF condition and contains valid data
    return .T.

2.  FAILURE TO TERMINATE

   This is more confusing.  Since the actual code for creating the push buttons is not included, I don't know what it will do.  If the FUNCTION or PICTURE clause of your "@...push buttons" contains an "N" it explicitly forces the button not to terminate the READ.  A "T" in the clause forces the button to terminate the read.  If neither "N" nor "T" are in the FUNCTION or PICTURE clause, "T" is the default behavior and the read should terminate.  

3.  POSSIBILITY OF A COMBINED PROBLEM

   If your function is already uses a RETURN .F. (like the one I entered above), the read cannot terminate if the data is invalid.  The reason:  When you attempt to activate the "Cancel" button, the VALID clause on the GET for "abc" is activated first and program control will not leave the field because RETURN .F. won't let it.  If the data is acceptable, the "Cancel" process should proceed properly.  If you are using the ESCAPE key to activate the "Cancel" button it is easy to fix.  If you are clicking on the "Cancel" button, it's more risky.

    USING ESCAPE

    function myval
    parameter xy

    if lastkey() = chr(27)   && If the last key pressed was Escape
       return .t.
    endif

    if !between(xy,3,4)
       wait window "Invalid Values" Nowait
       return .F.    
    endif
    return .T.

    USING THE MOUSE

    function myval
    parameter xy

    if !between(xy,3,4)
       wait window "Invalid Values" Nowait

       if abc = 0     && Nothing was entered
         return .t.
       endif

       return .F.    
    endif
    return .T.

  This one will allow you to pass the VALID clause on the GET for "abc" without entering anything in the field.  BUT - it will also allow you to save the data later, unless you trap for it.  You can trap for it by putting a check into the code prior to saving the data:

    if abc = 0
       * don't allow the invalid data to be saved; either throw it away, or ask for a
       * corrected value for ABC.  A single @...GET and a READ would be enough.
    else
       * your existing save process goes here
    endif



As a final note:  If possible (and you're not already doing so), you should consider using the screen generator for data entry.  It provides much better control of events, but still ends up with an SPR file after being compiled.  If you are already using the screen generator, each button (or button group) should have a check box to control termination of the read.

I hope this helps.  If you're still having a problem, feel free to post a follow-up question.  If you do, please include as much actual code as possible.  If you capture the screen while the code file is open, you can attach a picture to your question.  
         [ Capture the screen with Alt + PringScreen ]

Good Luck,

Fred

P.S.  If you decide not to ask for anything further, please use the "Comment" section within the rating system to let me know if I helped solve your problem.  I don't care as much about the rating itself as I do about knowing if the issue is resolved.


---------- FOLLOW-UP ----------

QUESTION: Thanks Fred and sorry for late reply.

Here it is my actual code : (The above one was just an example)

...
...  Some popup declaration and windows specifications code
...

@ 0,71 GET m.govtpvt WHEN isediting SIZE 1,1 MESS '1-GOVT 2-PVT'  VALID GOVTCHK(M.GOVTPVT)
@ 3,1 SAY "Examcode:"
@ 4,4 GET m.examcode WHEN isediting SIZE 1,1 Mess '1-SEC 2-SR' && VALID EXAMCHK(M.EXAMCODE)
@ 4,13 GET m.subj1 WHEN isediting SIZE 1,2
...
...

* And here are push buttons :

@ 20,0 GET m.top_btn ;
  PICTURE "@*HN \<Top" ;
  SIZE 1,5,1 ;
  DEFAULT 1 ;
  VALID btn_val('TOP') ;
  MESSAGE 'Go to first record.'
@ 20,6 GET m.prev_btn ;
  PICTURE "@*HN \<Prev" ;
  SIZE 1,6,1 ;
  DEFAULT 1 ;
  VALID btn_val('PREV') ;
  MESSAGE 'Go to previous record.'
@ 20,13 GET m.next_btn ;
  PICTURE "@*HN \<Next" ;
  SIZE 1,6,1 ;
  DEFAULT 1 ;
  VALID btn_val('NEXT') ;
  MESSAGE 'Go to next record.'
@ 20,20 GET m.end_btn ;
  PICTURE "@*HN \<End" ;
  SIZE 1,5,1 ;
  DEFAULT 1 ;
  VALID btn_val('END') ;
  MESSAGE 'Go to last record.'
@ 20,26 GET m.loc_btn ;
  PICTURE "@*HN \<Locate" ;
  SIZE 1,8,1 ;
  DEFAULT 1 ;
  VALID btn_val('LOCATE') ;
  MESSAGE 'Locate a record.'
@ 20,35 GET m.add_btn ;
  PICTURE "@*HN \<Add" ;
  SIZE 1,5,1 ;
  DEFAULT 1 ;
  VALID btn_val('ADD') ;
  MESSAGE 'Add a new record.'
@ 20,41 GET m.edit_btn ;
  PICTURE "@*HN Ed\<it" ;
  SIZE 1,6,1 ;
  DEFAULT 1 ;
  VALID btn_val('EDIT') ;
  MESSAGE 'Edit current record.'
@ 20,48 GET m.del_btn ;
  PICTURE "@*HN \<Delete" ;
  SIZE 1,8,1 ;
  DEFAULT 1 ;
  VALID btn_val('DELETE') ;
  MESSAGE 'Delete current record.'
@ 20,57 GET m.prnt_btn ;
  PICTURE "@*HN P\<rint" ;
  SIZE 1,7,1 ;
  DEFAULT 1 ;
  VALID btn_val('PRINT') ;
  MESSAGE 'Print report.'
@ 20,65 GET m.exit_btn ;
  PICTURE "@*HN \<Close" ;
  SIZE 1,7,1 ;
  DEFAULT 1 ;
  VALID btn_val('EXIT') ;
  MESSAGE 'Close screen.'

IF NOT WVISIBLE("_46s0qyxnr")
  ACTIVATE WINDOW _46s0qyxnr
ENDIF


*       靈컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴
*                 
*           MS-DOSREAD contains clauses from SCREEN s2784161     
*                 
*       聃컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴컴
*

READ CYCLE ;
  ACTIVATE READACT() ;
  DEACTIVATE READDEAC() ;
  NOLOCK

When I press A (going to add a new record), all push buttons becomes disabled and Save and Cancel remains enabled.  Cursor is in m.govtpvt variable and asking user to input.  Now suppose he want to cancel the adding the record, it should be terminate the read.

Here it is my code for function GOVTCHK :

FUNCTION GOVTCHK
PARAMETER TT
IF !BETWEEN(TT,1,2)
WAIT WIND "Invalid Values" Nowait
IF TT=0 AND !INLI(LAST(),13,9,24,5) && Enter,Tab,Upkey,Downkey
RETURN .T.
ENDIF
_curobj=1
endif
return

I want to capture mouse click i.e. if user press the cancel button the read should be terminated. As you said "If the FUNCTION or PICTURE clause of your "@...push buttons" contains an "N" it explicitly forces the button not to terminate the READ.", all above push buttons have "N"; but I wish that if user clicks the cancel button then it should terminate the read please.

Thank you once again for your detailed and helpful reply.

Thanks and Regards
Girish Sharma

Answer
Hello again,

The GOVTCHK function seems to be the problem.  Remove the ! from the following line:

       IF TT=0 AND !INLI(LAST(),13,9,24,5) && Enter, Tab, Upkey, Downkey


The use of _curobj = 1 has the same effect as RETURN .F. described in my original answer.  The "Cancel" button is never activated because control cannot exit from the first GET.

Best of luck,

Fred

NOTE:  Although no longer relevant, my previous answer contained an error.  

         LASKEY() = CHR(27) should have been LASTKEY() = 27  

FoxPro

All Answers


Answers by Expert:


Ask Experts

Volunteer


Fred Frase

Expertise

Questions about development only. No installation or hardware specific questions, please. Your first step in requesting assistance should be to identify the version of FoxPro you are using. I can write short functions but, PLEASE do not ask me to write programs for you.

Experience

Nearly 30 years professional programming experience using FoxPro (FoxBase through VFP 9) or other xbase language, primarily in Windows environments.

Education/Credentials
Completed a 1,000 hour diploma course in programming at International Academy of Ohio (subsequently merged with Southern Ohio College).

©2016 About.com. All rights reserved.