I am new to progress 4GL language. I have written a logic which is trying to check <> "" values for dimensional arrays and giving syntax error. Can anyone pls help me where I am making mistakes and the logic I written is correct or not?
DEFINE VARIABLE anotarray AS CHARACTER NO-UNDO.
DEFINE VARIABLE barray AS CHARACTER EXTENT 3 NO-UNDO.
ASSIGN
barray[1] = "yes"
barray[2] = "no"
anotarray = ""
.
/***value can be stored randomly in variable barray. so we cannot specify [1],[2],[3] for if condition***/
/***based on req. I need to check both anotarray or barray <> "" ***/
IF (anotarray OR barray ) <> "" THEN DISP barray.
/*** ERROR thrown- An array was specified in an expression, on the right-hand side of an assignment, or as a parameter when no array is appropriate or expected. (361)*** /
This syntax is not valid : IF (anotarray OR barray) <> "" THEN ...
You have to cycle through all elements of your array. You can do it using a DO statement and the EXTENT function.
Also, you have to compare both variables to the empty string : IF anotarray <> "" OR barray[ix] <> "" THEN ...
This code should work :
DEFINE VARIABLE anotarray AS CHARACTER NO-UNDO.
DEFINE VARIABLE barray AS CHARACTER EXTENT 3 NO-UNDO.
DEFINE VARIABLE ix AS INTEGER NO-UNDO.
ASSIGN
barray[1] = "yes"
barray[2] = "no"
anotarray = ""
.
DO ix = 1 TO EXTENT(barray):
IF barray[ix] <> "" OR anotarray <> "" THEN DISP barray[ix].
END.
You have two problems in this expression:
anotarray or barray
One is the error 361 that you have reported. That error is because you cannot check the entire array all at once. You need to check each element of the array.
The other issue is that OR compares logical values not character values.
So what you probably want to write is something more like:
if ( anotearry <> "" or barray[1] <> "" or barray[2] ) then display barray.
Related
Can you help me.
if convert binary to octal anyone can help me..???
this code convert octal to binary. help me for change this code.
function oct2bin returns character ( input octalString as character ):
define variable i as integer no-undo.
define variable n as integer no-undo.
define variable c as character no-undo.
define variable result as character no-undo.
n = length( octalString ).
if n < 2 or substring( octalString, 1, 1 ) <> "~\" then /* a valid octalString begins with "\" */
do:
message "valid octal strings must begin with ~\".
result = ?.
end.
else
do i = 2 to n:
c = substring( octalString, i, 1 ).
if asc( c ) < 48 or asc( c ) > 55 then /* a valid octalString only contains the digits 0 thru 7 */
do:
message c "is not a valid numeric character".
result = ?.
leave.
end.
Groups of three bits can be converted into an octal digit. Divide the binary number into three-bit groups, convert the group to an octal digit, then string the digits into an octal number.
PROCEDURE BinToOct:
DEFINE INPUT PARAMETER pcBinStr AS CHARACTER NO-UNDO.
DEFINE OUTPUT PARAMETER pcOctStr AS CHARACTER NO-UNDO.
DEFINE VARIABLE cPadding AS CHARACTER NO-UNDO.
DEFINE VARIABLE iLoop AS INTEGER NO-UNDO.
DEFINE VARIABLE cBinDigit AS CHARACTER NO-UNDO.
DEFINE VARIABLE cOctDigit AS CHARACTER NO-UNDO.
/* Pad input with zeroes to make it divisible by 3. */
IF LENGTH(pcBinStr) MOD 3 <> 0 THEN
ASSIGN
cPadding = FILL("0", (3 - LENGTH(pcBinStr) MOD 3))
pcBinStr = cPadding + pcBinStr.
/* Divide up bits into groups of 3. */
DO iLoop = 1 TO LENGTH(pcBinStr) BY 3:
cBinDigit = SUBSTRING(pcBinStr, iLoop, 3).
/* Convert bits to octal digit. */
CASE cBinDigit:
WHEN "000" THEN cOctDigit = "0".
WHEN "001" THEN cOctDigit = "1".
WHEN "010" THEN cOctDigit = "2".
WHEN "011" THEN cOctDigit = "3".
WHEN "100" THEN cOctDigit = "4".
WHEN "101" THEN cOctDigit = "5".
WHEN "110" THEN cOctDigit = "6".
WHEN "111" THEN cOctDigit = "7".
OTHERWISE MESSAGE "Bad input" VIEW-AS ALERT-BOX ERROR.
END CASE.
/* Add digit to result string. */
pcOctStr = pcOctStr + cOctDigit.
END.
END PROCEDURE.
DEFINE VARIABLE cResult AS CHARACTER NO-UNDO.
RUN BinToOct (INPUT "1010011100101", OUTPUT cResult).
MESSAGE cResult VIEW-AS ALERT-BOX INFORMATION.
I'm trying to populate an integer variable from a character variable. If there is any error found I want to show the error message and trace all the possible cases for failure got.
//Defining variable
Define variable char_value as character no-undo initial "kk".
Define variable int_value as integer no-undo.
define variable ix as integer no-undo.
Assign int_value = integer(char_value) no-error.
IF ERROR-STATUS:ERROR OR ERROR-STATUS:NUM-MESSAGES > 0 THEN
DO:
MESSAGE ERROR-STATUS:NUM-MESSAGES
" errors occurred during conversion." SKIP
"Do you want to view them?"
VIEW-AS ALERT-BOX QUESTION BUTTONS YES-NO
UPDATE view-errs AS LOGICAL.
IF view-errs THEN
DO ix = 1 TO ERROR-STATUS:NUM-MESSAGES:
MESSAGE ERROR-
STATUS:GET-NUMBER(ix)
ERROR-STATUS:GET-
MESSAGE(ix).
END.
END.
There are two conditions which I want to know.
What char value I gave so that no. Of error returns will be more than 1.
How can I trace all the possible cases for failure got.
The built-in conversion routine does not do what you want it to do. So you will need to parse your input prior to attempting to convert it. Something like this:
function isDigit returns logical ( input d as character ):
if length( d ) = 1 then
return ( index( "0123456789", d ) > 0 ).
else
return no.
end.
procedure checkInteger:
define input parameter integerString as character no-undo.
define output parameter errorList as character no-undo.
define output parameter ok as logical no-undo.
define variable i as integer no-undo.
define variable n as integer no-undo.
define variable c as character no-undo.
ok = yes.
n = length( integerString ).
do i = 1 to n:
c = substring( integerString, i, 1 ).
if i = 1 and c = "-" then next.
if isDigit( c ) = no then
do:
ok = no.
errorList = errorList + substitute( "The character '&1' at offset &2 is not a valid integer value~n", c, i ).
end.
end.
errorList = trim( errorList, "~n" ). // remove the trailing newline (if any)
return.
end.
define variable ok as logical no-undo.
define variable errorList as character no-undo.
run checkInteger( "12x34y56z789", output errorList, output ok ).
if ok = yes then
message "string is a properly formed integer, go ahead and convert it".
else
message
"string was not correctly formed, do not try to convert it" skip
errorList
view-as alert-box information
.
Note #1 If the input contains unprintable characters the errorList string will display it literally and it will look kind of funny. You could, of course, encode them to be more readable. Doing so is left as an exercise. Or another question.
Note #2 This code makes no attempt to check that the string value will fit into an integer or an int64. That is also left as an exercise.
While you can make your parsing as complex as you like, I would just keep it simple and ensure the user is provided enough information, which in this case is the complete input value:
def var cc as char initial "kk".
def var ii as int.
ii = integer( cc ).
catch e as progress.lang.error:
message quoter( cc, "'" ) e:getMessage(1) view-as alert-box.
end catch.
I have a written query for matching 2 characters and parse the data but I feel that the way i did is wrong. Let me share my logic with you
DEFINE VARIABLE I AS INTEGER NO-UNDO.
DEFINE VARIABLE cData AS CHARACTER NO-UNDO.
DEFINE VARIABLE cParsData AS CHARACTER NO-UNDO.
ASSIGN
cData = 'PRRSCLPP0123456789'.
DO I = 1 TO LENGTH(cData):
cParsData = SUBSTRING(cData,I).
IF cParsData MATCHES 'PP*' THEN MESSAGE SUBSTRING(cParsData,4,9).
END.
As you see the way i did is wrong and its parsing each character per iteration i think but what i need is it should parse two characters per iteration so that we can matches "PP". You can share or change the logic for different ways to get the same output
It is hard to imagine a reason for iterating through the string one character at a time looking for "PP" and then spitting out characters 4 through 13. It would be much simpler to do this:
define variable myData as character no-undo.
define variable foundIt as integer no-undo.
myData = "PRRSCLPP0123456789".
foundIt = index( myData, "PP" ).
if foundIt > 0 then
message substring( myData, 4, 9 ).
If there is a reason to go through that string one character at a time I think it must not be contained in your code sample or question.
On a side note: MATCHES "PP*" is equivalent to BEGINS "PP". It doesn't matter much in this case but it is a bad habit to needlessly throw MATCHES at string comparisons. Especially if that habit ends up in a WHERE clause. Using MATCHES in WHERE clauses will cause a table scan. Which is almost always a bad idea.
If you are trying to output N characters after the position that "PP" was found (rather than the hard-coded 4 through 13) you would do it like so (assuming that n = 9):
define variable myData as character no-undo.
define variable foundIt as integer no-undo.
myData = "PRRSCLPP0123456789".
foundIt = index( myData, "PP" ).
if foundIt > 0 then
message substring( myData, foundIt + 1, 9 ).
I dont quite understand what you want to do. Do you want to search the string and see if there's "PP" in it? Then you don't need to do it in an iteration. Simply
cData MATCHES "*PP*" will tell you that.
If "PP" is some kind of delimiter and you want to do something with the data before and after you can do:
DEFINE VARIABLE I AS INTEGER NO-UNDO.
DEFINE VARIABLE cData AS CHARACTER NO-UNDO .
DEFINE VARIABLE cParsData AS CHARACTER NO-UNDO.
ASSIGN
cData = 'PRRSCLPP0123456789'.
DO I = 1 TO LENGTH(cData):
cParsData = SUBSTRING(cData,I, 2).
IF cParsData = 'PP' THEN DO:
DISPLAY
SUBSTRING(cData, i + 2) FORMAT "x(20)" LABEL "After PP"
SUBSTRING(cData, 1, i - 1) FORMAT "x(20)" LABEL "Before PP".
END.
END.
This only works for one occurance of "PP" in the string though. You should try to explain better exactly what you are after.
You left a lot more information in a comment on another answer:
If PP really always is position 10 (and 11) or 20 (and 21) and you only want the follwing 10 chars then you can do:
DEFINE VARIABLE cData1 AS CHARACTER NO-UNDO.
DEFINE VARIABLE cData2 AS CHARACTER NO-UNDO.
/* Position 10 and 11 */
cData1 = 'PRRSCLAAAPP0123456789'.
/* Position 20 and 21 */
cData2 = 'PRRSCLAAAPRRSCLAAAPP9876543210AA'.
FUNCTION parse RETURNS CHARACTER
(INPUT cString AS CHARACTER ):
IF INDEX(cString, "PP") > 0 THEN
RETURN SUBSTRING(cString, INDEX(cString, "PP") + 2, 10 ).
ELSE
RETURN "".
END.
MESSAGE cData1 " ->" parse(cData1) SKIP
cData2 " ->" parse(cData2) VIEW-AS ALERT-BOX.
I am fetching a numeric value from an HTML table. If it fails to fetch the value I fill the value "NA" instead. Here is the odd part 0 <> "NA" is false, 0 = "NA" is true, 0 == "NA" is False. I get that = is not case sensitive, and == is, but I thought <> was case sensitive... So why does it work like this?
Local $x = 0
If $x <> "Test" Then
MsgBox(0,"","x <> Test")
Else
MsgBox(0,"","x = Test")
EndIf
With this exaplle I get a message box "x = Test"
but I thought <> was case sensitive
According to the docs, it is not a string-specific comparison operator like ==. Rather, it’s just the negation of =, so your string will still be interpreted as an integer – both "NA" and "Test" becoming 0 – and fail to satisfy 0 <> 0.
Tests if two values are not equal. Case insensitive when used with strings. To do a case sensitive not equal comparison use Not ("string1" == "string2")
I have tried all but its not working
I am getting a colum value form Data base as
substatus=rsprefobj("isnotificationactive");
after doing
Response.write substatus
It gives me --> n
and when i do
intcomaprestringval=StrComp(substatus,"n",vbTextCompare)
Response.write intcomaprestringval
It(intcomaprestringval) gives me --> 1 even though they are same
I want to take some decision based on database value if its "n" or "y"
If intcomaprestringval = 0 Then
some
Else
some
End If
But StrComp()always returns 1 in my case whether database value is "n" or "y" :(
I write a compare function that will return either "OK" if 2 values are a match or "No Match" if they do not. Here it is:
Function Compare(str1, str2, comp)
str = "OK"
If StrComp(str1, str2, comp) <> 0 Then str = "No Match"
Compare = str
End Function
str1 and str2 are the 2 values you wish to compare and comp is the method of comparison (0 = binary comparison and 1 = text comparison). I always use 0.
So you would use it like this:
If Compare(substatus, "n", 0) = "OK" Then
' Values match
Else
'Values do not match
End If
Hope it helps
Regarding your test:
intcomaprestringval=StrComp(substatus,"n",vbTextCompare)
Are you setting vbTextCompare to be 0 at some point earlier in your code?
I have used Trim() as suggested by #EntBark
Dim myvalue
myvalue=Trim(substatus)
intcomaprestringval=StrComp(myvalue,"n",vbTextCompare)