View Full Version : Range of values editing on *CHAR command field - Why?
01-01-1995, 02:00 AM
I created a command to input 3 values into a CL program. All three parms are defined as *CHAR in my command, but the values are actually numbers. What I am trying to do is to FORCE the user enter "01" instead of "1". I accomplished this by setting up Range of values to do some basic editing: Lower value = 01, Upper value = 29. This worked, my CL is NOT invoked unless the user enters 2 digits. The command would not accept "4" as valid input, "04" had to be entered. I really want the upper value to be 99, not 29. What I noticed is that the editing that I want was NOT enforced if the Upper Range of value was anything above 29. Does anyone know WHY this is?
06-15-2000, 02:36 PM
Susan, even though a range of '01' to '29' disallows '4', it allows '1' and '2'. '4' is working (being disallowed) with an upper limit of '29' because '4 ' is greater than '29'. There's no range including '40' and '50' that disallows '4 '. The only way to do this is to define 99 single values (ugh). I'd pass the parameter as decimal(2,0) values with a restriction of 1 - 99. If you can't change the CL, you could add another program for the command to use that calls your CL after converting the parameters. Are all values 01 - 99 allowed? I mean, are the parameters just numbers, or do they mean something else? If they mean something else, you could define special values in the command that map to your 2-digit numbers. RSTD(*YES) SPCVAL((*CHARLIE '01') (*SALLY '04')) Barbara Morris
06-15-2000, 02:40 PM
Susan, Could you post your command source? I suspect there is something else going on here. Also, why do you insist on using *CHAR if you only want numeric entries given? Why not have the CPP accept the values as *DEC and convert to character? I also suspect that you would find entries like 1A or 2B would be within the range of 01 to 29 when compared on a character basis. I assume this is not acceptable. Doug
06-15-2000, 06:50 PM
Douglas, Here's my command source. The first 2 *CHAR fields seemed to validate the numbers correctly. The last parm only seems to work when the upper value is 29 or less. If I used 99 for the upper range value it allowed a single digit entry. I am wondering WHY this is? I resolved this by changing this command and the CL to use *DEC variables, but I'd still like to know why this *CHAR field edits so strangely. When the last parm is defined as shown below, it does not allow "1", it forces "01", which is what I want. But again, it does allow "1" as input when I have the upper level of the range set at anything 30 or above. There is something going on here that I am not aware of .... CMD PROMPT('Copy Bucket files to Retro Env') PARM KWD(YEAR) TYPE(*CHAR) LEN(4) RANGE(2000 + 2005) MIN(1) MAX(1) PROMPT('Enter 4 digit + year - YYYY') PARM KWD(MONTH) TYPE(*CHAR) LEN(2) RANGE(01 12) + MIN(1) MAX(1) PROMPT('Enter 2 digit month + - MM') PARM KWD(BATCH) TYPE(*CHAR) LEN(2) RANGE(01 29) + MIN(1) MAX(1) PROMPT('Enter 2 digit batch + - BB')
06-15-2000, 09:08 PM
Susan, <font color=blue>The first 2 *CHAR fields seemed to validate the numbers correctly. </font> Sorry; the first one does only somewhat by accident. The second does not validate the numbers correctly. The first one only works because the first three characters of the lower and upper boundaries are the same, and the fourth position does not have any characters available between 0 and 5 except the digits. If the range was 1999 to 2005 or 2005 to 2010 it would not work for the same reason the second does not validate correctly. The second parameter does not validate correctly because it is defined as *CHAR. The RANGE(01 12) does *not* mean it has to be a two-digit number. It means the *character string* has to compare between '01' and '12'. This really only ensures the first character is a 0 or 1 (eliminating keying just 2-9), and that when the first character is '0' the second is at least '1' or that when the first character is '1' the second character is not over '2'. Thus, you cannot key '0 ' because it is not at least '01'. You cannot key a leading blank and a digit (' 1' to ' 9') because they are less than '01'. You cannot key '2 ' to '9 ' because they are over '12' (that is '2' is *greater* than '12' in a character comparison). You cannot key a two-digit number greater than '12' simply because '13'-'19' exceed '12' and anytime the first digit exceeds '1' it is greater than '12'. Now try keying these values into your command: <ul> '1 ' this is the only 1 digit number that will work (see above) '1*' '1Z' [/list] Basically, if you have a '1' in the first byte, *any* character below '3' will pass in the second byte. Since the digits are near the very end of the EBCDIC collating sequence (unlike ASCII), you can put nearly anything in the second byte including a blank. Going back to parameter 1, the reason RANGE(2000 2005) works is strictly because the first three bytes *must* be '200' and the last byte is only effectively allowed the range '0' to '5'. If you had RANGE(1999 2005) you would be able to key '2' or '20' or '2ABC' or any string of other equally invalid years. Likewise, RANGE(2005 2010) would accept '201k', etc. <font color=blue>The last parm only seems to work when the upper value is 29 or less. If I used 99 for the upper range value it allowed a single digit entry. I am wondering WHY this is?</font> As near as I can tell, it is just the values you happen to be testing. On my system, neither '29' nor '99' work correctly. Or '12' for that matter. I think what you may be seeing is by using RANGE(01 99) you are effectively allowing the first character to be anywhere from '0' to '9' and thus can enter any 1-digit number for the same reasons laid out above. You could also key '2B' or '5Q' or '9&' for that matter. When you tried RANGE(01 29) you could not key '3' to '9', and thought it was working correctly. However, it would still take '1' or '2' or '1H' or '2+' or ... <font color=blue>I resolved this by changing this command and the CL to use *DEC variables</font> This is the most reasonable solution, IMHO. There are at least two other alternatives: Use VALUES() and list each valid entry. For YEAR use VALUES(2000 2001 2002 2003 2004 2005) and for MONTH use VALUES(01 02 03 04 05 06 07 08 09 10 11 12). For BATCH you could still do it since you can list up to 300 constants, but it seems silly to me to do it this way. Use a Validity Checking Program (VCP) to substring each byte and check each byte one at a time to make sure it is between '0' and '9', and still use the RANGE() check for the lower and upper limit. You could eliminate 1-digit entries by coding FULL(*YES), but this would not eliminate entries like '1q' which is still between '01' and '12'. <font color=blue>When the last parm is defined as shown below, it does not allow "1", it forces "01", which is what I want.</font> Try it again. It *does* allow '1' on my system the way you coded it, and '2' for that matter. With RANGE(01 99) it also allows '3' to '9'; with RANGE(01 29) it does not. I think you were only testing selected values, as near as I can tell. <font color=blue>There is something going on here that I am not aware of .... </font> You're trying to use a character comparison for numeric values. Why don't you want to use *DEC values? Then RANGE() will work fine. The user will not be forced to key a leading zero, but why do you want them to? You'll get the correct value whether they do or not when defined as *DEC, so why do you care? Using FULL(*YES) is not valid with *DEC data types as it is with *CHAR, so that won't enforce it either. Doug
06-16-2000, 06:19 AM
Thanks Douglas. That exlains it! As I said in my post last night, I gave up and changed them to *DEC. I was just trying to understand why the fields were editing the way that they were. Thanks for spending so much time on this. I appreciate all of your help!
Powered by vBulletin® Version 4.1.5 Copyright © 2013 vBulletin Solutions, Inc. All rights reserved.